微信号:infoqchina

介绍:有内容的技术社区媒体

Cassandra数据模型设计最佳实践(上部)

2013-08-27 15:47 InfoQ

【编者注:InfoQ中文站获得了eBay工程师Jay Patel的授权,将会为陆续为读者呈现Cassandra数据模型设计的系列内容。】


本文是Cassandra数据模型设计第一篇(全两篇),该系列文章包含了eBay使用Cassandra数据模型设计的一些实践。其中一些最佳实践我们是通过社区学到的,有些对我们来说也是新知识,还有一些仍然具有争议性,可能在要通过进一步的实践才能从中获益。


本文中,我将会讲解一些基本的实践以及一个详细的例子。即使你不了解Cassandra,也应该能理解下面大多数内容。


说说Cassandra在ebay的使用情况


我们尝试使用Cassandra已经超过1年时间了。Cassandra现在正在服务一些用例,涉及到的业务从大量写操作的日志记录和跟踪,到一些混合工作。其中一项服务是我们的“Social Signal”项目,支撑着ebay的pruduct pages里like/own/want特性。我们开发的一些用例已经上线运行,但更多的还是处于开发阶段。


我们的Cassandra集群规模并不庞大,但正在稳步的增长中。在过去几个月里,我们共部署了几十个节点,它们分布在几个跨机房的小型集群中。你可能会问,为什么要多个集群?我们通过的职能部门和业务来划分集群。相同职能部门的相同业务的用例共享一个集群,但它们存在于不同的keyspaces中。


RedLaser, Hunch和其它ebay的合作伙伴也在尝试cassandra解决现实中各种问题。除了Cassandra,我们也在使用MongoDB和Hbase,本文中我不会讨论它们,但我相信它们都有各自的优点。


我相信此时你一定有很多问题,在这篇文章里暂时不会一一说明。在即将到来的Cassandra Summit大会,我将更详细的讲解我们每个用例场景,数据模型和多数据中心部署,以及经验教训和其它知识。


本文重点讲述我们在ebay应用的Cassandra数据模型设计最佳实践。下面让我们先看看这系列文章会用到的一些术语。


术语和约定


术语“Column Name” 和 “Column Key”被认为是一样的。同样的,“Super Column Name” 和 “Super Column Key”也认为是相同的。


下图表示一个 Column Family (简称CF)中的一个row



下图表示一个 Super Column Family (简称SCF)中的一个row



下图表示一个Column Family中一个row,它包含Composite Columns。Composite Columns的属性通过分隔符’|’连接。请注意,这里看到的只是数据的表现形式,Cassandra内置了Composite Column,它是一个对象,并不是使用’|’作为属性分隔符的字符串。(顺便说下,本文不要求你掌握Super Column和Composite Column方面知识。)


基于上面的内容,让我们开始第一个实践吧!


不要把Cassandra model想象成关系型数据库table


取而代之,应该把它想象成事一个有序的map结构。


对于一个新手来说,下面关系型数据库术语常常被对应到Cassandra模型



这种对比可以帮助我们从关系型数据库转换到非关系型数据库。但是当设计Cassandra column famiy的时候请不要这样去类比。取而代之,考虑它是一个map中嵌入另一个map:外部map的key为row key,内部map的key为column key,两个map的key都是有序的。如下:



why?


将column family想象成嵌套的并排序的map比关系型数据库table描述的更为准确,它将帮助你正确的进行Cassandra模型设计。



How?


Map可以进行高效查询,同时排序的特性可以进行高效column扫描。在Cassandra中,我们可以使用row key和column key做高效查找和范围扫描


Column key的数量是很庞大的(译者注:目前译者所使用的Cassandra1.2.5版本,每个row支持最多20亿个columns)。换句话说你,你可以拥有一个wide rows。


Column key自身可以存储值,即你可以拥有一个没有值的column。

如果集群使用Order Preserving Partitioner (OOP)策略进行数据存储,就可以对row key进行范围查询。但是OOP大多数情况都不推荐使用(译者注:将rowkey按照顺序存储到节点上,如果分区不均匀,将导致数据读写不均衡),所以你可以认为外部的map是不排序的,如下:



上面提到的”Super Column”,认为它们是一组column,这样的话,两级嵌套map就会像下面展示的一样变为三级嵌套map:



注意:


你需要传递timestamp给每个column value,因为Cassandra使用它做内部的冲突处理机制。但在建模过程中你可以忽略它(译者注:在操作column的时候timestamp信息会自动添加到column)。同时,不要考虑在你的程序中使用column的timestamp,因为它不是为你设计的,与Hbase不同,它们不会生成新的version数据(译者注:在Hbase中相同rowkey和column key的数据会保存多个version,而Cassandra会将相同数据覆盖,timestamp只保存最后一次更新的时间)。


因为Super Column的性能问题和缺乏二级索引支持问题,Cassandra社区对它的使用曾有过强烈争议。所以,推荐使用Composite Columns代替Super Column实现功能。(译者注:使用Super Column,如果你要获取其中一个columnvalue,则要扫描整个Super Column,这会导致查询性能很糟糕)


更多请阅读原文。


***********************************

本文来自InfoQ微信公众账号:infoqchina

1、回复“今日新闻”,查看今天更新的新闻;

2、回复“今日英文”,查看今天英文站的更新;

3、回复“文章 +关键词”,搜索关键词相关内容;

4、回复“QCon”,了解QCon大会相关信息;

5、回复“活动”,了解最近InfoQ组织的线下沙龙;

6、回复“架构师”,获取《架构师》下载地址;

7、回复“投稿”,了解投稿流程。

***********************************

 
InfoQ 更多文章 Facebook如何实现PB级别数据库自动化备份 学术派Google软件工程师Matt Welsh谈移动开发趋势 Spotify为什么要使用一些“无聊”的技术? 妹纸们放假了,汉纸们做啥? 大多数重构可以避免
猜您喜欢 iOS使用脚本批量打渠道包 两种方法来实现在C#的winform项目的多个窗体中传值 快乐编程与极限编程 面向开发者服务的用户体验 细谈Spring(九)spring+hibernate声明式事务管理详解