还有五天,就是7月8日,我们的结婚三周年纪念日了,在这个周末,我收集了两个人在一起的点点滴滴的往事,做了一个小视频,来纪念这一个日子,把祝福送给我的爱妻。
照例,视频密码还是 internet
注1:无搞笑内容,寻娱乐者不必打开了,直接祝福就好了,嘿嘿
注2:配乐为伍佰的《与你到永久》
致谢:感谢王冀彬等人参与拍摄的部分照片
还有五天,就是7月8日,我们的结婚三周年纪念日了,在这个周末,我收集了两个人在一起的点点滴滴的往事,做了一个小视频,来纪念这一个日子,把祝福送给我的爱妻。
照例,视频密码还是 internet
注1:无搞笑内容,寻娱乐者不必打开了,直接祝福就好了,嘿嘿
注2:配乐为伍佰的《与你到永久》
致谢:感谢王冀彬等人参与拍摄的部分照片
本月的最主要新闻来自Hadoop社区,世界杯正在南非举行,而Hadoop世界的最大的聚会则是每年6月在硅谷举办的Hadoop Summit,今年的 Hadoop Summit 会在 6月29日在圣克拉拉举办,继续了去年的盛况。此外IaaS相关开源社区也很活跃。
1. Hadoop Summit 2010将于6月29日举行
http://developer.yahoo.com/events/hadoopsummit2010/
MapReduce模式大规模并行处理的事实标准 Hadoop 项目拥有庞大的用户社区,在世界各地会召开不同规模的社区聚会或会议,一年一度的在硅谷召开的Hadoop Summit是其中最为重要的会议,会议由Hadoop的发起者Yahoo公司举办,全球的 Hadoop 开发者、研究者和用户会参加会议的开发、研究和应用三个主题的研讨,包括Yahoo、Amazon、Cloudera、Facebook在内的云计算领先者都会进行主题发言。
目前,Hadoop的线下活动已经有Hadoop Summit, Hadoop World这样的全球峰会、HUG Meetup这样的小规模技术讨论,以及中国、印度等地的区域性大会,线下活动的丰富是社区成熟的产物,同时也帮助社区更进一步的健康发展。
2. CloudEra与Quest合作开发Hadoop Oracle Connector
http://news.cnet.com/8301-13846_3-20008242-62.html
仍然是一条Hadoop相关新闻,CloudEra宣布,要和Quest Software合作为Hadoop开发一个Oracle Connector,以便进行 Hadoop 和 Oracle 的双向数据通信。
Cloudera 之前已经开发了一个数据库导入工具 squoop,而这次的 Oracle 导入/导出工具更进一步针对了 Oracle 广泛应用的企业IT系统。
3. C12G 发布 OpenNebula 1.4 指南(PDF版)
http://www.c12g.com/blog:2010-06-21-c12g_releases_opennebula_1.4_pdf_guides_-_june_21_2010
OpenNebula 是当前的一个比较著名的开源 IaaS 系统(另一个是Eucalyptus),今年3月,项目的创立者们成立了一家名为C12G的公司,开始商业化地运营。在OpenNebula上个月推出 1.4 企业版和简化版后,这个月C12G发布了1.4版的手册,这个公司正在逐渐开始运转,推动OpenNebula更加成熟。
商业化和开源从来都不矛盾,获得良好商业模式的支持会使得开源软件和社区更具有生命力,MySQL就是个不错的例子,不过,开源软件的生命力在于健康的社区,如果不能营造一个健康开放的社区,开源项目和商业公司可能面临双输的结局,这样的例子也比比皆是。现在对C12G进行判断还为时尚早,期待C12G和OpenNebula共同繁荣。
4. Eucalyptus发布伙伴计划,推进云计算产业链丰富与完善
http://www.crn.com/software/225701187;jsessionid=PDVDQFSBBPVG5QE1GHOSKH4ATMY32JVN
另一家开源IaaS厂商Eucalyptus也不甘寂寞,他们开始了一个合作伙伴计划,向系统集成商、零售商、服务提供商以及平台厂商推广云计算。这项计划的核心是一个“Eucalyptus合作伙伴云”,让伙伴们可以在这里开发、测试他们的解决方案。Eucalyptus期望可以通过这种方式可以构建一个以自己为中心的、繁荣的云计算生态环境。
一个星期以来都想为一天天长大的斯屹写一篇日志,尤其是最近用新手机拍了很多视频以后,不过这两天太忙了,总没时间整理视频们,一拖再拖。不过,不能总欠着儿子的,给不了他一篇完美的日志,也不能完全不给啊,呵呵。
斯屹最近生了几回病,吊瓶都用上了,全家心疼坏了,生病之余还在5月30号参加了研究院的亲子大赛,和爸爸一起拿了一个项目的第三名,表现优异,赢了个令人羡慕的大奖,稍后再补上同事帮忙拍的照片吧。
斯屹在运动方面也有很大加强,这次让人震惊的飞过小桥太刺激了(视频第20秒)
视频的密码是internet
最近斯屹的经典行为——有一天晚上他突然拍了爷爷大腿外侧两下,说“斯屹最喜欢爷爷了”——原因是他妈妈跟他说,去,拍拍爷爷马屁,说“斯屹最喜欢爷爷了”,然后他就果然去拍了……全家笑翻。
更多视频和端午假期去天津海边的情况,回头再发吧,这里先给儿子一个交代,呵呵,别都忘了。
原文: http://www.rackspacecloud.com/blog/2010/05/12/cassandra-by-example/#
原作者:Eric Evan
原文发布日期:May 12, 2010
译者:王旭(http://wangxu.me/blog/ , @gnawux)
翻译时间:2010年5月15,25,26日
近来 Cassandra 备受瞩目,很多人正在评估是否可以应用 Cassandra。由于这些人更多的追求速度,相应的,我们的文档就过于粗浅了。这些文章中,最差的是为有关系数据库基础的人解释Cassandra数据模型的那些。
Cassandra 数据模型实际和传统的数据库差异非常大,足够让人眩晕,而且很多误解都需要修正。
有些人把这个数据模型描述成存放map的map,或对于super column的场景,是存放map的map的map。这些解释经常用类似 JSON 标记的视觉辅助展示方法来进行佐证。其他人则把列族看做是系数表,还有人把列族看作是存放列对象的集合容器。甚至有人有时把列看走势三元组。我觉得所有这些解释都不够好。
问题在于很难去用类比的方法来确切解释一个新的东西,而且如果比较的不准确的话常常把人搞糊涂。我仍然期望有人能解释清楚这个数据模型,但同时我觉得确切的例子可能更容易说明白一些。
尽管 Twitter 本身就是 Cassandra 的一个实际的应用场景,它仍然是一个不错的教学实例,因为它众所周知而且易于抽象。在例子中,和很多站点一样,每个用户都有一份用户数据(显示名称、密码、email等),这些信息链接到朋友(译注:用户follow的人)和 follower(译注:follow用户的人)。此外,如果没有那些短 tweets 的话也就不是 twitter 了,tweet每条140个字符,它们都关联着诸如时间戳和惟一的id这样的元数据,这个id我们可以从URL里看到。
现在我们在一个关系数据库里来直接进行建模,我们首先需要一个表来存放用户。
CREATE TABLE user (
id INTEGER PRIMARY KEY,
username VARCHAR(64),
password VARCHAR(64)
);
我们还需要两张表来存储一对多的follow关系。
CREATE TABLE followers (
user INTEGER REFERENCES user(id),
follower INTEGER REFERENCES user(id)
);
CREATE TABLE following (
user INTEGER REFERENCES user(id),
followed INTEGER REFERENCES user(id)
);
显然,我们还需要表来存储tweets。
CREATE TABLE tweets (
id INTEGER,
user INTEGER REFERENCES user(id),
body VARCHAR(140),
timestamp TIMESTAMP
);
由于仅仅是个例子,我已经极大简化了情况,但仅仅是这个极度简化的模型,也还有很多需要做的工作。例如,要以可行的方法达到达到数据归一化就需要一个外部键值约束,而因为我们需要从多张表join信息,我们需要对任意值建索引,以保证高效。
但是让一个分布式系统正常工作相当有挑战性,几乎不可能不做任何折衷。对Cassandra来说也是如此,而且这也是为什么上述数据模型对我们来说是无法工作的的原因。对于入门者,没有可供参考的完整性,缺乏次索引使得join很难进行,所以,你必须反归一化。另一方面,你被迫思考你要进行的查询的方式和期望结果,因为这差不多就是数据模型看起来的样子。
那么如何把上述模型翻译到Cassandra中呢?十分幸运,我们只需要看看 Twissandra,这是 Eric Florenzano 写的一个 Twitter 的简化版克隆,用作例子。那么让我们来使用 Twitter 和 Twissandra 作为例子来看看 Cassandra 的数据模型是如何的。
Cassandra 是一种无 schema 的数据存储方式,但为你的应用做一些特定的配置还是必要的。Twissandra 给出了一个可以工作的 Cassandra 配置,不过研究一下关于数据模型方面的配置还是物有所值的。
Keyspaces 是 Cassandra 中最顶层的命名空间。在未来版本的 Cassandra 中,将可以动态创建 keyspace,正如在 RDBMS 中创建数据库一样,但是对于 0.6 和以前的版本,这些都在主配置文件中定义,如:
<Keyspaces> <Keyspace Name="Twissandra"> ... </Keyspace> </Keyspaces>
对于每个 keyspace,都可以有一个或多个列族。列族是用于关联类型相近的记录的命名空间。Cassandra 在写操作时,在一个列族内部允许有记录级的原子性,对它们进行查询非常高效。这些特性十分重要,在进行你的数据建模前必须记牢,它们会在下面讨论到。
和keyspace类似,列族也在主配置文件中定义,虽然在将来的版本中你将可以在运行时创建列族,正像在RDBMS中创建表一样。
<Keyspaces>
<Keyspace Name="Twissandra">
<ColumnFamily CompareWith="UTF8Type" Name="User"/>
<ColumnFamily CompareWith="BytesType" Name="Username"/>
<ColumnFamily CompareWith="BytesType" Name="Friends"/>
<ColumnFamily CompareWith="BytesType" Name="Followers"/>
<ColumnFamily CompareWith="UTF8Type" Name="Tweet"/>
<ColumnFamily CompareWith="LongType" Name="Userline"/>
<ColumnFamily CompareWith="LongType" Name="Timeline"/>
</Keyspace>
</Keyspaces>
需要指出的是,上面的配置片段中,指定名字的时候同时指定了一个比较者类型。这凸显了 Cassandra 和传统数据库的又一个重大不同,记录按照设计的顺序存储,在之后不能轻易改变。
一下子看所有的七个Twissandra列族是干什么的可能不那么直观,所以,我们来逐个仔细看一下:
User用于存储用户信息,大致相当于上面描述的用户表。列族中的每条记录以UUID为键值,并包含用户名和密码列。
在User列族中查询一个用户需要知道用户的键值,但从用户名怎么找到这个UUID键值呢?在上面描述的SQL关系数据库里的话,我们就在User表里来一个匹配用户名的SELECT语句(WHERE username = ‘jericevans’)就行了。但这对于Cassandra来说却不可能。
首先,关系数据库可以顺序地扫描全表来进行这样一个 SELECT,但由于记录是基于键值分布在 Cassandra 集群中的,这个匹配将可能会在多个节点上进行,可能是很多节点。而且,即使是数据就在一个节点上,仍然有一个原因会让这一操作远没有关系数据库效率高,因为关系数据库可以对username列有索引。前面提到过,Cassandra是不支持第二索引的。
解决方案就是,建立一个我们自己的反向索引,进行用户名到UUID键值的映射,这就是Username列族的用途。
Friends 和 Follower 列族可以回答这些问题:用户X follow了哪些人?谁follow了用户X?这两个列族的键值都是这个唯一的用户ID,其中包含了哪些有follow关系的用户以及它们创建的时间。
Tweet 列族用于存放所有的tweets。这个列族以每个 tweet 的 UUID为键值,还包含了用户id,tweet内容以及tweet时间这些列。
这是属于每个用户的时间线。记录的键值是用户的ID,其他的列中,包含有一个数字时间戳到Tweet列族中的tweet ID的映射。
最后,Timeline列族类似于Userline,只是这里存储着每个用户的朋友的tweet的时间线视图。
有了上面这些列祖,现在我们可以看一些常用的操作都是如何发生的。
首先,新用户需要一个方法来注册一个账户,当他们注册的时候,组要将他们添加到Cassandra数据库中去。对于Twissandra,我们来看看里面的内容:
username = 'jericevans' password = '**********' useruuid = str(uuid())
columns = {'id': useruuid, 'username': username, 'password': password}
USER.insert(useruuid, columns)
USERNAME.insert(username, {'id': useruuid})
Twissandra是用Python写成的,使用 Pycassa 作为访问 Cassandra的客户端,上述大写的 USER 和 USERNAME 是 pycassa.ColumnFamily 的实例,它们需要在使用之前的某个位置被分别初始化。
这里说明一下,这不是从 Twissandra 里原样摘出来的。我让他们更加简单而且是自包含的。比如,在上面的例子中,如果没有对用户名和密码的赋值的话,可能不那么好理解,不过一个 web 应用只能从用户注册表单里得到这些内容。
从这个例子中回来,有两个不同的 Cassandra 写操作(insert()),第一个创建了一个用户列族,另一个更新了用户名到用户 UUID 键值的反向映射表。在两个例子中,参数都是用于查找记录的键值,以及包含列名和值的map。
frienduuid = 'a4a70900-24e1-11df-8924-001ff3591711'
FRIENDS.insert(useruuid, {frienduuid: time.time()})
FOLLOWERS.insert(frienduuid, {useruuid: time.time()})
这里我们再来两个不同的insert()操作,这次是加入一个用户到我们的朋友列表,并加入反向关系:给被 follow 用户添加一个 follower。
tweetuuid = str(uuid()) body = '@ericflo thanks for Twissandra, it helps!' timestamp = long(time.time() * 1e6)
columns = {'id': tweetuuid, 'user_id': useruuid, 'body': body, '_ts': timestamp}
TWEET.insert(tweetuuid, columns)
columns = {struct.pack('>d', timestamp: tweetuuid}
USERLINE.insert(useruuid, columns)
TIMELINE.insert(useruuid, columns)
for otheruuid in FOLLOWERS.get(useruuid, 5000):
TIMELINE.insert(otheruuid, columns)
要存储一条新的tweet,我们需要使用一个新的UUID作为键值,在 Tweet列族创建一个记录,其中的列包含作者的用户ID,创建的时间,当然还有tweet的文本内容本身。
此外,用户的 Userline 中也要加入tweet的时间和它的id。如果这是用户的第一条tweet的话,这个insert()会产生一条新的纪录,后面的只是为这条记录添加新列。
最后要给发出tweet的用户和其他follower的 timeline 列族添加这条tweet的ID和时间。
值得注意的一件事是,这里,时间戳使用的是64位长整型变量,而当它成为一个列的名字的时候,它会被打包为网络字节序的二进制值。这是因为Userline和Timeline列族使用了一个LongType Comparator,允许我们使用数值区间指定查找指定范围,所以它们被按照数值来存放起来。
timeline = USERLINE.get(useruuid, column_reversed=True) tweets = TWEET.multiget(timeline.values())
接收一个用户的tweet,首先从Userline获取tweet ID的一个列表,然后从Tweet列族通过multiget()方法莱读取这些tweet。得到的结果将是通过着数值表示的时间戳逆序排列的,因为Userline使用了LongTyper comparator,并且reversed设置为了True。
start = request.GET.get('start')
limit = NUM_PER_PAGE
timeline = TIMELINE.get(useruuid, column_start=start, column_count=limit, column_reversed=True) tweets = TWEET.multiget(timeline.values())
和上一个例子类似,这次是从 Timeline 读取 tweet ID,不过这次我们还使用了 start 和 limit 来控制读取列的范围。这样有助于输出结果的分页。
希望这足够提供给你一个大致的概念。重复一下,我从代码中提取了一些例子,为了简明起见,略去了一些操作,所以现在可能是 check out 出 Twissandra 的源代码并进行下一步深入研究的好时候了。有很多功能,诸如 retweet 和 lists,都还空着没有实现,可以作为一个练习的起点。如果你已经熟悉 Python 和 Django 的话,那你可以考虑实现一下这些方法。
Cassandra 的 wiki 包含了大量的信息,而且还在不断增多,还包括一个实时更新的其他人贡献的文章与幻灯片的列表。
如果你喜欢IRC的话,你可以加入 irc.freenode.net 的 #cassandra 频道,来和那里的人聊天,他们总是热衷于提供帮助和回答问题。如果你更青睐 email 的话,cassandra-user 邮件列表上也有很多可以提供帮助的人。
忙碌的一周,来点流水账,开始的一日FML和最后的一日出差是亮点:
上周六,头天晚上喝酒了,第二天一早还没醒酒起床地铁到天通苑来看儿子,中午吃晚饭,下午去单位加班,本来想干到晚上然后回蓟门里休息的,结果到九点多,老婆来电话说儿子发烧了。虽然老婆说不用我回去,我还是想回去帮帮忙,至少让老婆能多睡一会,于是——
儿子发烧了,我还在加班,很不心安 9:01 PM May 8th via Echofon
儿子发烧了,赶快赶回天通苑 (@ 西便门桥) http://4sq.com/cqyEzK 10:05 PM May 8th via foursquare from here
应该还有70分钟能到老婆和儿子身边 (@ Changchunjie Subway Station 地铁长椿街站) http://4sq.com/cbZ3Dy 10:14 PM May 8th via foursquare from here
老婆说不用我,我还是想回去让她能稍微歇一下 (@ Chongwenmen Subway Station 地铁崇文门站) http://4sq.com/bgtk9k 10:24 PM May 8th via foursquare from here
可是屋漏偏逢连天雨,再次因为没听天气预报而遭到报应……
好像下雨了,TP417 北苑路北进站前ATP故障,紧急停车一次 #ourmetro 10:59 PM May 8th via dabr
刚才打了个雷,md,我又要被雨淋了,咋这么背呢 11:01 PM May 8th via dabr
天通苑南进站前再次ATP故障,是下雨造成的吧 #ourmetro 11:06 PM May 8th via dabr
儿子啊,你爸爸让雷劈着就回来啦 (@ 地铁天通苑南站) http://4sq.com/dz7eYZ 11:08 PM May 8th via foursquare from here
雨太大,出不了站 #FML 11:11 PM May 8th via dabr
这时和家打了个电话,老婆怕我人品太差被雷劈了,让我关上手机,在我买了一把伞之后,赶到家的时候,已然空无一人,斯屹烧到39.4,老婆抓狂地带着他去医院了,刚好这时我手机听话的关机了,所以就没带我。他们要我在家待命,随时送东西去医院——时逢我家的车去修了,在这样的一天说FML应该不为过吧。四点钟儿子才回来,打了吊瓶,烧退了,休息两三天之后,斯屹基本恢复了,这孩子的抵抗力还是不错的,今天我回家,他和爸爸非常亲,呵呵,有儿子真开心。
——————8<——————-FML的分隔线———————8<——————————–
周三下午,正和同事一起在外面开会,忽然接到通知,去武汉开会,是的,下午就走,于是——
- 出发,赶飞机 (@ Xitucheng subway station地铁西土城站) http://4sq.com/d1zdD6 3:54 PM May 12th via foursquare from here
- 换机场线,间隔太不美好了,能赶上飞机么 (@ Sanyuanqiao Subway Station 地铁三元桥站) http://4sq.com/9oHfO1 4:22 PM May 12th via foursquare from here
- md,机场快轨也太慢了,要误我值机了 (@ 首都机场二号航站楼) http://4sq.com/cS5J5S 5:01 PM May 12th via foursquare from here
- 唉,登机口又是在航站楼的尽头,每次都这样,好像近处登机门从来不开一样 5:19 PM May 12th via dabr
- 到了不用坐,直接开始登机,头一次啊,时间真悬,东航的,也是头一回坐,会不会头一次准点啊 5:23 PM May 12th via dabr
- 难道我瘦了?B737-800啥时候这么宽敞了?还以为是空客的呢 5:30 PM May 12th via dabr
- 预料之中的郁闷,交通管制,等15分钟 5:55 PM May 12th via dabr
实际是晚了一个小时…..到武汉后
晚点一小时,安全着陆武汉,似乎下雨了 (@ 武汉天河机场) http://4sq.com/9rk4WG 8:34 PM May 12th via foursquare from here
这个出租车在哭雨中开高速,一直保持100以上,没停着地在打电话,我很怕的说 9:05 PM May 12th via dabr
出租车里这个电台太烦了,非常吵,而且不清楚 9:19 PM May 12th via dabr
到了,CCSA的会务大婶十分居委会啊 (@ 亚洲大酒店) http://4sq.com/d1CiUY 9:53 PM May 12th via foursquare from here
路上总共用时6个小时,和同事了解了会议情况之后,睡觉之前翻译了一篇文章
每次来武汉出差都会半夜翻译篇文章啊,这次是 Ran Tavory 的Understanding #Cassandra Code Base,译文在这里: http://wangxu.me/blog/?p=381 1:26 AM May 13th via Echofon
翻译了一篇文章,算是私活,第二天早起吃饭之后去开会,开了不到两个小时——对,就是不到两个小时,然后……然后就吃中午饭,就准备回北京了——我来的时候路上就六个小时啊,开会居然只有不到俩小时,虽然是正事吧,可性价比也太低了吧……
check-out 准备回北京,唉,跑这么远来,就开了不到俩小时的会 12:24 PM May 13th via dabr
@hzmangel 热干面没吃到,鸭脖子买了点,晚上来找我吃啊 12:53 PM May 13th via dabr in reply to hzmangel
来机场路上,司机一直在瞌睡,我使出浑身解数在和司机搭讪,同车两个不明真相的同事都觉得我真tmd贫,果然是个侃爷… 1:33 PM May 13th via dabr
平安到机场了,传说中的大雨还没出现,希望尽早飞回北京 (@ 武汉天河机场) http://4sq.com/9rk4WG 1:35 PM May 13th via foursquare from here
躲过司机的瞌睡一劫之后,我们开始等待预计3点的飞机……
good,我和同事之间没人,心情愉快,PS:旁边的国航飞机还没动,他们已经晚了快半小时了,我们如果正点应该3点飞 2:47 PM May 13th via dabr
md,交通管制,我们也飞不了呢 2:58 PM May 13th via dabr
实际上晚点大约一小时,度过了相当无聊的飞机上的时间之后——
到北京了,还是去坐机场快轨吧 (@ 首都机场二号航站楼) http://4sq.com/cS5J5S 5:56 PM May 13th via foursquare from here
机场出口有免费取用的打火机,不知是不是在安检口处人们丢下的 6:00 PM May 13th via dabr
回家时坐机场线运气好多了,刚好一组车进T2站,不像来时等了14分钟 6:05 PM May 13th via dabr
机场快轨回程很快啊,不到一刻钟就从T2到三元桥了 (@ Sanyuanqiao Subway Station 地铁三元桥站) http://4sq.com/9oHfO1 6:20 PM May 13th via foursquare from here
10号线也这么拥挤,没上去… #ourmetro 6:24 PM May 13th via dabr
对没什么行李的乘客,机场快轨还是个不错的选择,很快就到家了 (@ Xitucheng subway station地铁西土城站) http://4sq.com/d1zdD6 6:45 PM May 13th via foursquare from here
回程用时总计也是六个多小时,这次出差,路上花费了十二个半小时,开会两个小时,创下性价比新低,唉……特此记之。
原文: http://prettyprint.me/2010/05/02/understanding-cassandra-code-base/
原作者:Ran Tavory
原文发布日期:May 2nd, 2010
译者:王旭(http://wangxu.me/blog/ , @gnawux)
翻译时间:2010年5月12日
最近我为 cassandra 添加了一些小特性,于是我花了些时间来更仔细地考察了这个系统的内部设计。诸如 embedded service 这样的特性实际上并不需要对源代码和设计的深入理解,但其他特性,比如 truncate 就需要对系统中使用的不同算法有深入的了解,如写操作时如何进行的,读操作时如何进行的,值时如何删除的(提示:他们没有……)等等。
源代码虽然不是非常长,有大约91136行,但非常密级,而且有很多算法,所以直接读这些代码对我来说并不是非常简单。我是用如下的外科手段来进行行数计数的($ cassandra/trunk $ find * -name *.java -type f -exec cat {} \;|wc -l )
我写这篇文章希望可以帮助其他人能更快地阅读这些代码。我不会介绍那些基础信息,比如“什么是Cassandra”,如何部署,如何检出代码,如何编译,如何下载thrift等。我也不想介绍算法最复杂的部分,比如ae-service使用的merkle-tree如何 ,Cassandra 中不同部分都是用的 bloom filter 是什么、如何工作,以及 gossip 是如何使用的。我不认为我适于解释所有这些问题,而且在cassandra的开发者wiki上也已经介绍这些了。我要写的就是我学习cassandra的途径,以及我在这个过程中学到了什么。我没有在其他地方发现过类似文档(当我完全完成的时候,可能我会把这些写入wiki),所以我觉得这对我下次再深入新的源代码会非常有用。
最后是一个免责声明:这里仅仅是我对系统如何工作的个人理解,它们是不完整、不确切的,特此警告。注意我也只是在学习,或多或少也是Cassandra菜鸟。也请注意,Cassandra 是一个运动目标,它一直在快速开发者,任何一个代码的快照或早或晚都会发生些变化。在本文写作的时候,官方版本是 0.6.1,不过我工作在 trunk 上,这个分支将来会成为 0.7.0。
这里是我所采取的几个步骤以及我学到的东西的一个描述。
首先你需要下载代码并运行单元测试。如果你使用 eclipes,IDEA,netbeans,vi,emacs等等这些的话,可能还需要配置一下。这非常简单,这里有更多介绍。
接下来你需要读一些背景材料,这依赖于你想搞哪个部分。我希望理解读操作、写操作以及值如何删除,所以我把下面每个文档都看了差不多五遍。没错,每个五遍。它们包含了大量的信息,我发现每次读我都能被更多的一些细节所吸引。我先读过这些文档,然后读源代码,确定我理解了算法如何在类和方法中实现,然后再读文档,然后再读源代码,读单元测试(并用debugger运行它们)等等。这是这些文档:
http://wiki.apache.org/cassandra/ArchitectureInternals
http://wiki.apache.org/cassandra/HintedHandoff
http://wiki.apache.org/cassandra/ArchitectureAntiEntropy
http://wiki.apache.org/cassandra/ArchitectureSSTable
http://wiki.apache.org/cassandra/ArchitectureCommitLog
http://wiki.apache.org/cassandra/DistributedDeletes
我还看了 Google BigTable 的论文和让人着迷的亚马逊的 Dynamo 的论文,不过这都是很久以前的事情了。它们是很好的背景材料,不过对于理解实际代码并不是必须的。
好了,读完所有这些文档,我开始知道能做什么、如何做了,但我感觉我还没有到达能写新特性的阶段。在读代码几次之后,我发现我有点晕了,还是不了解诸如“值到底是不是真的被删除了”,那个累负责哪个功能,有几个Stage,Stage之间的数据流是什么样的,还有“如何标记整个列族为删除”,这是我在truncate操作中真正想做的。
Cassandra 的操作使用的并发模型在 SEDA 论文中有介绍。这个并发模型大致是这样的,和很多其他兵法系统不同,一个操作,比如一个写操作,并不是在同一个线程中开始和结束的。相反,一个操作在一个线程中开始,之后把操作(异步)交给了另一个线程,然后再传递到下一个进程,直至完成。事实上,操作并不是在线程间流转,而是在stage间流转。操作从一个stage转向另一个。每个stage都和一个线程池相关联,这个线程池在方便的时候来执行这个操作。一些操作是 IO bound 的(译注:这里应该是CPU吧,猜的),另一些则受限于磁盘或网络,所谓“方便”取决于资源的可用性。SEDA 论文把这个过程解释得非常好(很好的文章,值得一读),简单地说你从中得到的是更高级别的并发性和更好的资源管理,资源包含 CPU、磁盘、网络等。
所以,要理解 Cassandra 的数据流,你首先需要理解 SEDA。然后你需要了解 Cassandra 中有哪些 Stage,以及这些 stage 之间数据时如何流动的。
十分幸运,作为一个起点,StageManager 类中包含了一个不完整 stage 列表:
public final static String READ_STAGE = "ROW-READ-STAGE"; public final static String MUTATION_STAGE = "ROW-MUTATION-STAGE"; public final static String STREAM_STAGE = "STREAM-STAGE"; public final static String GOSSIP_STAGE = "GS"; public static final String RESPONSE_STAGE = "RESPONSE-STAGE"; public final static String AE_SERVICE_STAGE = "AE-SERVICE-STAGE"; private static final String LOADBALANCE_STAGE = "LOAD-BALANCER-STAGE";
我就不具体介绍每个 stage 都负责什么了(因为我也不知道……)但我可以说大致说,ROW-READ-STAGE 在读操作中,ROW-MUTATION-STAGE 参与了写和删除操作,而 AE-SERVICE-STAGE 负责 anti-entropy (译注:整理?不知道怎么确切用中文表达了)。这不是一个完整的 stage 列表,根据你感兴趣的代码路径,用这个方法,你可以找到更多。比如,查看文件ColumnFamilyStore你可以找到更多的stage,如FLUSH-SORTER-POOL, FLUSH-WRITER-POOL 和 MEMTABLE-POST-FLUSHER。在 Cassandra 中,stage 由 ExecutorService 的实例来唯一标识,这差不多是一个线程池,他们有全大写的名字,如 MEMTABLE-POST-FLUSHER。
我画了一张混有类和stage的图来便于理解。这不是合法的UML,但我觉得这对于了解数据在系统中如何流动是个很好的方法。这不是全部类和stage的完整的图示,仅仅是我感兴趣的一部分。
[SSTableTracker], [ColumnFamilyStore]->[Memtable (memtable_)], [CommitLog|CommitLogExecutor], [DeletionService|FILEUTILS-DELETE-POOL], [StorageLoadBalancer| lb_:LB-OPERATIONS; lbOperations_:LB-TARGET], [StorageService| consistencyManager_:CONSISTENCY-MANAGER], [StageManager| READ_STAGE; MUTATION_STAGE; STREAM_STAGE; GOSSIP_STAGE; RESPONSE_STAGE; AE_SERVICE_STAGE; LOADBALANCE_STAGE; MIGRATION_STAGE]">yUML source
可以使用一个 debugger 来读代码,运行一个单元测试是了解事情如何工作的非常棒的方法。我不是一个debugger的铁杆粉丝,但是他们有一个可取之处就是通过单步执行单元测试来学习新代码。所以我所做的证实单步执行代码中的单步执行。这非常酷。我还运行了 Hector 的单元测试,它使用 thrift 接口并运行一个嵌入的 cassandra 服务器,这个方法一针见血、界面友好而且还能学到更多东西。
接下来我所做的是使用一个工具来从已有代码中提取类图。这不是非常有用。
好,我使用的工具不是很棒,但这不是最关键的问题,问题是 cassandra 的代码书写方法使得类图对于理解代码作用很有限。UML 类图对于面向对象设计非常有效。类图的必要性在于列出类、成员以及它们的关系。比如类 A 是类 B 的一个列表,这样通过 UML 类图可以看出 A 是 B 的聚合,而且仅仅通过类图就可以学到很多。比如一架飞机有很多乘客。
Cassandra 是一个拥有坚实算法后台和优秀性能的系统,但是,老实说,依我之见,从好的面向对象实践的视角来看,它可不是一个很好的研究案例……它的类包含很多静态方法和成员,而且在很多地方,你可以看到一个类调用另一个类的静态方法。纯粹的C风格,所以我发现类图尽管从类的可视化以及类之间的关系方面有些帮助,但并不是非常有用。
我放弃了类图,继续进入下一种兔——序列图。
序列图非常适于实体之间的交互的抽象和可视化。这里,一个实例可能是一个类,一个 STAGE 或一个 thrift 客户端。很幸运,使用序列图,你不必太专注于序列图里实体的类型,你只需要把他们都表示为 actor 就行了(至少我觉得这么做就够了,希望UML大神们原谅)。
下面的图通过运行 Hector 的单元测试并使用一个(单节点)嵌入式 Cassandra 服务器得到。这个序列图并不很通用,它仅仅描述了一种可能的执行路径,而实际上可能有很多种,但我尼克让它们更简单一些,尽管有点不太精确。
我使用了一个简单的在线序列图编辑器(http://www.websequencediagrams.com)来生成他们。
读操作:
写操作:
最后提示:作为 Cassandra 的用户我应该使用 Keyspace, ColumnFamily, Column 这些名词。不过,代码中使用了 Table 这个名词。啥是 Table 呢?……原来,Table实际上就是 Keyspace…… 就是一个提示,仅此而已。
研究代码是一项艰巨而有成就感的工作,我希望这篇文章帮助你也有个好的起点,快点跑起来。
2010年4月25日,linuxfb(北邮真情流露Linux版)在老据点之一——北邮教三某实验室的会议室举行了一月一次的版聚。由于聪明的同学们都看了天气预报没来,追星的同学都因为Coly同学缺席没来,版聚史无前例的只有11人出席,不过,还是一如既往的深入、一如既往的愉快。在此感谢李东阳、彭涛和Casparant同学的分享。参加的同学在Google Wave里有记录,搜索“linuxfb with:public”就能找到了,这里不再赘述,仅仅提一下几位突出贡献同学:
李东阳这次介绍了一个ocfs2的一个bug,大概是这样的,fsstress的truncate会出错,内存中和磁盘上的元数据不一致,东阳同学在VFS的direct write位置定位了这个问题。背景是这样的:OCFS2的Direct Write不允许改变元数据,以获得更好的并发性能。但如果发现有O_DIRECT而不能directio,就送回VFS去做buffered io,可是,VFS的aio还是会检查 o_direct,回到 ocfs2_direct….,最后,该函数只查看 offset,不判断是否超出inode的范围,于是就出现了问题。最终的修改比较直接,就是要确定不要回到direct,只要确定进aio,就一定进aio,这样就不会出问题了。曲折的debug故事一直是我们比较喜欢的话题,非常有趣。
最后,bergwolf介绍了ATA的新指令TRIM,用于宣称某个块已经没有用了,可以被删除了,希望来帮助SSD更主动地垃圾回收,从而提升性能。2.6.33的内核已经支持了TRIM,btrfs和ext4也会使用TRIM。但是TRIM指令的设计师非常匪夷所思的,不能进入queue,类似barrier,这样,需要等前面的指令执行完才能执行TRIM,而TRIM完成之后才能有新的指令进入queue,一次的时延有上百毫秒,如果大量使用这个命令的话,反而会影响性能。结论是——这个命令暂时没啥好处……
总之,感谢讲话题的三位同学:lidongyang,bergwolf,casparant,也感谢永远的组织者,colyli和hzmangel,当然,我也会一如既往的记下去。
原文: http://ria101.wordpress.com/2010/02/24/hbase-vs-cassandra-why-we-moved/
原作者:Dominic Williams
原文发布日期:February 24, 2010 at 7:27 pm
译者:王旭(http://wangxu.me/blog/ , @gnawux)
翻译时间:2010年3月21-25日
我的团队近来正在忙于一个全新的产品——即将发布的网络游戏 www.FightMyMonster.com。这让我们得以奢侈地去构建一个全新的 NOSQL 数据库,也就是说,我们可以把恐怖的 MySQL sharding 和昂贵的可伸缩性抛在脑后了。最近有很多人一直在问,为什么我们要把注意力从 HBase 上转移到 Cassandra 上去。我确认,确实有这样的变化,实际上我们基本上已经把代码移植到了 Cassandra 上了,这里我将给出解释。
为了那些不熟悉 NOSQL 的读者,后面的其他文章中,我会介绍为什么我们将会在未来几年中看到地震式的从 SQL 到 NOSQL 的迁移,这正和向云计算的迁移一样重要。后面的文章还会尝试解释为什么我认为 NOSQL 可能会是贵公司的正确选择。不过本文我只是解释我们选择 Cassandra 作为我们的 NOSQL 解决方案的选择。
免责声明——如果你正在寻找一个捷径来决定你的系统选择,你必须要明白,这可不是一个详尽而严格的比较,它只是概述了另一个初创团队在有限时间和资源的情况下的逻辑。
Cassandra 的血统是否预言了它的未来
我最喜欢的一个工程师们用来找 bug 的谒语是“广度优先而非深度优先”。这可以可能对那些解决技术细节的人来说很恼人,因为它暗示着如果他们只是看看的话,解决方法就会简单很多(忠告:只对那些能够原谅你的同事说这个)。我造出这个谒语的原因在于,我发现,软件问题中,如果我们强迫我们自己在进入某行代码的细节层面之前,先去看看那些高层次的考虑的话,可以节省大量时间。
所以,在谈论技术之前,我在做 HBase 和 Cassandra 之间的选择问题上先应用一下我的箴言。我们选择切换的技术结论可能已经可以预测了:Hbase和Cassandra有着迥异的血统和基因,而我认为这会影响到他们对我们的业务的适用性。
严格的说,Hbase 和它的支持系统源于著名的 Google BigTable 和 Google 文件系统设计(GFS 的论文发于 2003 年,BigTable 的论文发于 2006 年)。而 Cassandra 则是最近 Facebook 的数据库系统的开源分支,她在实现了 BigTable 的数据模型的同时,使用了基于 Amazon 的 Dynamo 的系统架构来存储数据(实际上,Cassandra 的最初开发工作就是由两位从 Amazon 跳槽到 Facebook 的 Dynamo 工程师完成的)。
在我看来,这些不同的历史也导致Hbase更加适合于数据仓库、大型数据的处理和分析(如进行Web页面的索引等),而 Cassandra 则更适合于实时事务处理和提供交互型数据。要进行系统研究来证明这个观点超出了本文的范畴,但我相信你在考虑数据库的时候总能发现这个差异的存在。
注意:如果你在寻找一个简单的证明,你可以通过主要 committer 的关注点来进行验证:大部分 HBase 的 committer 都为 Bing 工作(M$ 去年收购了他们的搜索公司,并允许他们在数月之后继续提交开源代码)。与之对应,Cassandra 的主要 committer 来自 Rackspace,用来可以自由获得的支持先进的通用的 NOSQL 的解决方案,用来和 Google, Yahoo, Amazon EC2 等提供的那些锁定在专有的 NOSQL 系统的方案相抗衡。
Malcolm Gladwell 会说只是根据这些背景的不同就可以简单地选择了 Cassandra。不过这是小马过河的问题。但当然,闭着眼睛就进行一个商业选择是相当困难的……
哪个 NOSQL数据库风头更劲?
另一个说服我们转向 Cassandra 的原因是我们社区中的大风向。如你所知,软件平台行业里,大者恒大——那些被普遍看好的平台,会有更多人聚集在这个平台周围,于是,从长远看,你可以得到更好的生态系统的支持(也就是说,大部分支持的软件可以从社区中获得,也有更多的开发者可以雇佣)。
如果从 HBase 开始时,我的印象就是它后面有巨大的社区力量,但我现在相信,Cassandra 更加强大。最初的印象部分来源于 StumpleUpon 和 Streamy 的两位 CTO 的两个非常有说服力的出色的讲演,他们是 Web 行业中两个在 Cassandra 成为一个可选系统之前的 HBase 的两个重要的贡献者,同时也部分来源于快速阅读了一篇名为“HBase vs Cassandra: NoSQL 战役!”的文章(大部分内容都被广泛证实了)。
势头是很难确证的,你不得不自己进行研究,不过我可以找到的一个重要的标志是 IRC 上的开发者动向。如果你在 freenode.org 上比较 #hbase 和 #cassandra 的开发这频道,你会发现 Cassandra 差不多在任何时候都有两倍的开发者在线。
如果你用考虑 HBase 一般的时间来考察 Cassandra,你就能发现 Cassandra 的背后确实有非常明显的加速势头。你可能还会发现那些逐渐出现的鼎鼎大名,如 Twitter,他们也计划广泛使用 Cassandra(这里)。
注:Cassandra 的网站看起来比 HBase 的好看多了,但认真的说,这可能不仅是市场的趋势。继续吧。
深入到技术部分: CAP 和 CA 与 AP 的神话
对于分布式系统,有个非常重要的理论(这里我们在讨论分布式数据库,我相信你注意到了)。这个理论被称为 CAP 理论,由 Inktomi 的 联合创始人兼首席科学家 Eric Brewer 博士提出。
这个理论说明,分布式(或共享数据)系统的设计中,至多只能够提供三个重要特性中的两个——一致性、可用性和容忍网络分区。简单的说,一致性指如果一个人向数据库写了一个值,那么其他用户能够立刻读取这个值,可用性意味着如果一些节点失效了,集群中的分布式系统仍然能继续工作,而容忍分区意味着,如果节点被分割成两组无法互相通信的节点,系统仍然能够继续工作。
Brewer教授是一个杰出的人物,许多开发者,包括 HBase 社区的很多人,都把此理论牢记在心,并用于他们的设计当中。事实上,如果你搜索线上的关于 HBase 和 Cassandra 比较的文章,你通常会发现,HBase 社区解释他们选择了 CP,而 Cassandra 选择了 AP ——毫无疑问,大多数开发者需要某种程度的一致性 (C)。
不过,我需要请你注意,事实上这些生命基于一个不完全的推论。CAP 理论仅仅适用于一个分布式算法(我希望 Brewer 教授可以统一)。但没有说明你不能设计一个系统,在其中的各种操作的底层算法选择上进行这种。所以,在一个系统中,确实一个操作职能提供这些特性中的两个,但被忽视的问题是在系统设计中,实际是可以允许调用者来选择他们的某个操作时需要哪些特性的。不仅如此,现实世界并不简单的划分为黑白两色,所有这些特性都可以以某种程度来提供。这就是 Cassandra。
这点非常重要,我重申:Cassandra 的优点在于你可以根据具体情况来选择一个最佳的折衷,来满足特定操作的需求。Cassandra 证明,你可以超越通常的 CAP 理论的解读,而世界仍然在转动。
我们来看看两种不同的极端。比如我必须从数据库中读取一个要求具有很高一致性的值,也就是说,我必须 100%保证能够读取到先前写入的最新的内容。在这种情况下,我可以通过指定一致性水平为“ALL”来从 Cassandra 读取数据,这时要求所有节点都有数据的一致的副本。这里我们不具有对任何节点失效和网络分裂的容错性。在另一个极端的方面,如果我不特别关心一致性,或仅仅就是希望最佳性能,我可以使用一致性级别“ONE”来访问数据。在这种情况下,从任意一个保存有这个副本的节点获取数据都可以——即使数据有三个副本,也并不在意其他两个有副本的节点是否失效或是否有不同,当然,这种情况下我们读到的数据可能不是最新的。
不仅如此,你不必被迫生活在黑白世界中。比如,在我们的一个特定的应用中,重要的读写操作通常使用“QUORUM”一致性级别,这意味着大部分存有此数据的节点上的副本是一致的——我这里是个简要描述,具体写你的 Cassandra 程序之前最好还是仔细研究一下。从我们的视角看,这这提供了一个合理的节点失效与网络分裂的耐受性,同时也提供了很高的一致性。而在一般情况下,我们使用前面提到的“ONE”一致性级别,者可以提供最高的性能。就是这样。
对我们来说,这是 Cassandra 的一个巨大的加分项目。我们不仅能轻易地调整我们的系统,也可以设计它。比如,当一定数量的节点失效或出现网络连接故障时,我们的大部分服务仍然可以继续工作,只有那些需要数据一致性的服务会失效。HBase并没有这么灵活,它单纯地追求系统的一个方面(CP),这让我再次看到了 SQL 开发者和查询优化人员们之间的那道隔阂——有些事情最好能够超越它,HBase!
In our project then, Cassandra has proven by far the most flexible system, although you may find your brain at first loses consistency when considering your QUORUMs.在我们的项目之后,卡桑德拉已被证明是迄今为止最灵活的系统,虽然你可能发现一致性第一失去你的大脑在考虑您的法定人数。
在我们的项目中,Cassandra 已经证明了它是有史以来最灵活的系统,虽然你可能在对这个问题进行投票(QUORUM)的时候发现的大脑失去了一致性。
什么时候单体会比模块化强?
Cassandra 和 HBase 的一个重要区别是, Cassandra 在每个节点是是一个单 Java 进程,而完整的 HBase 解决方案却由不同部分组成:有数据库进程本身,它可能会运行在多个模式;一个配置好的 hadoop HDFS 分布式文件系统,以及一个 Zookeeper 系统来协调不同的 HBase 进程。那么,这是否意味着 HBase 有更好的模块化结构呢?
虽然 HBase 的这种架构可能确实可以平衡不同开发团队的利益,在系统管理方面,模块化的 HBase 却无法视为一个加分项目。事实上,特别是对于一些小的初创公司,模块化倒是一个很大的负面因素。
HBase的下层相当复杂,任何对此有疑惑的人应该读读 Google 的 GFS 和 BigTable 的论文。即使是在一个单一节点的伪分布式模式下来架设 HBase 也很困难——事实上,我曾经费力写过一篇快速入门的教程(如果你要试试HBase的话看看这里)。在这个指南里你可以看到,设置好 HBase 并启动它实际包含了两个不同系统的手工设置:首先是 hadoop HDFS,然后才是 HBase 本身。
然后,HBase 的配置文件本身就是个怪兽,而你的设置可能和缺省的网络配置有极大的不同(在文章里我写了两个不同的Ubuntu的缺省网络设置,以及 EC2 里易变的 Elastic IP 和内部分配的域名)。当系统工作不正常的时候,你需要查看大量的日志。所有的需要修复的东西的信息都在日志里,而如果你是一个经验丰富的管理员的话,就能发现并处理问题。
但是,如果是在生产过程中出现问题,而你又没有时间耐心查找问题呢?如果你和我们一样,只有一个小的开发团队却有远大的目标,没有经历去 7*24 的进行系统监控管理会怎么样呢?
严肃地说,如果你是一个希望学习 NoSQL 系统的高级 DB 管理员的话,那么选择 HBase。这个系统超级复杂,有灵巧双手的管理员肯定能拿到高薪。
但是如果你们是一个向我们一样尽力去发现隧道尽头的小团队的话,还是等着听听别的闲话吧
胜在 Gossip!
Cassandra 是一个完全对称的系统。也就是说,没有主节点或像 HBase 里的 region server 这样的东西——每个节点的角色是完全一样的。不会有任何特定的节点或其他实体来充当协调者的角色,集群中的节点使用称为 “Cossip” 的纯 P2P 通信协议来协调他们的行为。
对 Gossip 的详细描述和使用 Gossip 的模型超过了本文的内容,但 Cassandra 所采用的 P2P 通信模型都是论证过的,比如发现节点失效的消息传播到整个系统的时间,或是一个客户应用的请求被路由到保存数据的节点的时间,所有这些过程所消耗的时间都毫无疑问的非常的短。我个人相信,Cassandra 代表了当今最振奋的一种 P2P 技术,当然,这和你的 NOSQL 数据库的选择无关。
那么,这个基于 Gossip 的架构究竟给 Cassandra 用户带来什么显示的好处呢。首先,继续我们的系统管理主体,系统管理变得简单多了。比如,增加一个新节点到系统中就是启动一个 Cassandra 进程并告诉它一个种子节点(一个已知的在集群中的节点)这么简单。试想当你的分布式集群可能运行在上百个节点的规模上的时候,如此轻易地增加新节点简直是难以置信。更进一步,当有什么出错的时候,你不需要考虑是哪种节点出了问题——所有节点都是一样的,这让调试成为了一个更加易于进行且可重复的过程。
第二,我可以得出结论,Cassandra 的 P2P 架构给了它更好的性能和可用性。这样的系统中,负载可以被均衡地三步倒各个节点上,来最大化潜在的并行性,这个能力让系统面临网络分裂和节点失效的时候都能更加的无缝,并且节点的对称性防止了 HBase 中发现的那种在节点加入和删除时的暂时性的性能都懂(Cassandra 启动非常迅速,并且性能可以随着节点的加入而平滑扩展)。
如果你想寻找更多更多的证据,你会对一个原来一直关注 hadoop 的小组(应该对 HBase 更加偏爱)的报告很感兴趣……
一份报告胜过千言万语。我是指图表
Yahoo!进行的第一个 NOSQL 系统的完整评测。研究似乎证实了 Cassandra 所享有的性能优势,从图表上看,非常倾向于 Cassandra。
目前这些论文还是草稿,你可以从这里找到这些论文:
http://www.brianfrankcooper.net/pubs/ycsb-v4.pdf
http://www.brianfrankcooper.net/pubs/ycsb.pdf
注意:这份报告中 HBase 仅在对一个范围的记录进行扫描这一项上优于 Cassandra。虽然 Cassandra 团队相信他们可以很快达到 HBase 的时间,但还是值得指出,在通常的 Cassandra 配置中,区间扫描几乎是不可能的。我建议你可以无视这一点,因为实际上你应该在 Cassandra 上面来实现你自己的索引,而非使用区间扫描。如果你对区间扫描和在 Cassandra 中存储索引相关问题有兴趣,可以看我的这篇文章。
最后一点: 这篇文章背后的 Yahoo!研究团队正尝试让它们的评测应用通过法律部门的评估,并将它发布给社区。如果他们成功的话,我当然希望他们成功,我们将能够看到一个持续的竞争场面,不论 HBase 还是 Cassandra 无疑都会进一步提高他们的性能。
锁和有用的模块性
毫无疑问,你会从 HBase 阵营听到这样的声音:HBase 的复杂结构让它可以提供 Cassandra 的 P2P 架构无法提供的东西。其中一个例子可能就是 Hbase 提供给开发者行锁机制,而 Cassandra 则没有(在 HBase 中,因为数据副本发生在 hadoop 底层,行锁可以由 region server 控制,而在 Cassandra 的 P2P 架构中,所有节点都是平等的,所以也就没有节点可以像一个网管囊样负责锁定有副本的数据)。
不够,我还是把这个问题返回到关于模块化的争论中,这实际是对 Cassandra 有理的。Cassandra 通过在对称节点上分布式存储数据来实现了 BigTable 的数据模型。它完整地实现了这些功能,而且是以最灵活和高性能的方式实现的。但如果你需要锁、事务和其它功能的话,这些可以以模块的方式添加到你的系统之中——比如,我们发现我们可以使用 Zookeeper 和相关的工具来很简单地为我们的应用提供可扩展的锁功能(对于这个功能,Hazelcast 等系统可能也可以实现这个功能,虽然我们没有进行研究)。
通过为一个窄领域目的来最小化它的功能,对我来说,Cassandra 的设计达到了它的目的——比如前面指出可配置的 CAP 的折衷。这种模块性意味着你可以依据你的需求来构建一个系统——需要锁,那么拿来 Zookeeper,需要存储全文索引,拿来 Lucandra ,等等。对于我们这样的开发者来说,这意味着我们不必部署复杂度超出我们实际需要的系统,给我们提供了更加灵活的构建我们需要的应用的终极道路。
MapReduce,别提 MapReduce!
Cassandra 做的还不够好的一件事情就是 MapReduce!对于不精通此项技术同学简单的解释一句,这是一个用于并行处理大量数据的系统,比如从上百万从网络上抓取的页面提取统计信息。MapReduce 和相关系统,比如 Pig 和 Hive 可以和 HBase 一起良好协作,因为它使用 HDFS 来存储数据,这些系统也是设计用来使用 HDFS 的。如果你需要进行这样的数据处理和分析的话,HBase 可能是你目前的最佳选择。
记住,这就像小马过河!
因此,我停止了对 Cassandra 的优点的赞美,实际上,HBase 和 Cassandra 并不一定是一对完全的竞争对手。虽然它们常常可以用于同样的用途,和 MySQL 和 PostgreSQL 类似,我相信在将来它们将会成为不同应用的首选解决方案。比如,据我所知 StumbleUpon 使用了 HBase 和 hadoop MapReduce 技术,来处理其业务的大量数据。Twitter 现在使用 Cassandra 来存储实时交互的社区发言,可能你已经在某种程度上使用它了。
作为一个有争议的临别赠言,下面我们进入下一个话题。
注意:在继续下一个小节之前,我要指出,Cassandra 在 0.6 版本会有 hadoop 支持,所以 MapReduce 整合能获得更好的支持。
兄弟,我不能失去数据…
作为先前 CAP 理论争议的一个可能结果,可能有这样的印象,HBase 的数据似乎比 Cassandra 中的数据更安全。这是我希望揭露的最后一个关于 Cassandra 的秘密,当你写入新数据的时候,它实际上立刻将它写入一个将要存储副本的仲裁节点的 commit log 当中了,也被复制到了节点们的内存中。这意味着如果你完全让你的集群掉电,只可能会损失极少数据。更进一步,在系统中,通过使用 Merkle tree 来组织数据的过分不一致(数据熵),更加增加了数据的安全性![]()
事实上,我对 HBase 的情况并不是非常确切——如果能有更细节的情况,我回尽快更新这里的内容的——但现在我的理解是,因为 hadoop 还不支持 append,HBase 不能有效地将修改的块信息刷入 HDFS (新的对数据变化会被复制为多个副本并永久化保存)。这意味着会有一个更大的缺口,你最新的更改是不可见的(如果我错了,可能是这样,请告诉我,我回修正本文)。
所以,尽管希腊神话中的 Cassandra 非常不幸(译注:Cassandra 是希腊神话里,特洛伊的那个可怜的女先知的名字,如果你不知道详情的话,可以参考wiki),但你的 Cassandra 中的数据不会有危险。
注意:Wade Amold 指出, hadoop .21 很快就会发布,其中将会解决 HBase 的这个问题。
今天,3月20日,是你的生日,爸爸祝你生日快乐!
很久不写儿子的博客了,两周前被这小子破相的时候就想写的,可是挺忙,一直没动笔,直到今天,通宵干活之后没什么睡意,想起到了斯屹的生日,还是写几句吧,没什么条理,想到哪写到哪,微博体,哈。
如今斯屹长大了好多,我和媳妇都有点想不通,那么点一个小家伙,怎么这么快就这么大了啊,呵呵,今天我和老婆差不多同时让各自的同事惊讶,都有个这么大的娃了。
郑渊洁说的好啊,从儿子降生那天,我有了个新角色——父亲,没有儿子就没有老爸,所以,我应该感谢他,是斯屹让我的人生从此不同,也祝福他在以后的日子里能健康幸福。希望我们家庭的努力能让孩子幸福,希望我们这代人的努力,能让下一代人不必经历我们的很多痛苦,比如那个墙啥的……嗯,是啊,指着爸爸再挣钱给你买房娶媳妇是戏不大了,哈哈。
……真的语无伦次啊,刚才那阵外面风呼呼的,嗯,看来我其实是困了,儿子,早上起来再祝你生日快乐,爸爸先睡了。