2010年2月

[译]Cassandra内部架构

最近想看看Cassandra的源码,于是去看他们的wiki,先把一个概述翻了,当誓师,hoho

原文链接:http://wiki.apache.org/cassandra/ArchitectureInternals

General

概述

Configuration file is parsed by DatabaseDescriptor (which also has all the default values, if any)

DatabaseDescriptor是专门解析配制文件的,配制的默认值也跟这定义。

Thrift generates an API interface in Cassandra.java; the implementation is CassandraServer, and CassandraDaemon ties it together. 

Cassandra.java调用Thrift(一个apache的跨语言框架)产生一个API接口,CassandraServer负责实现,CassandraDaemon把二者联系起来。

CassandraServer turns thrift requests into the internal equivalents, then StorageProxy does the actual work, then CassandraServer turns it back into thrift again

CassandraServer把thrift请求丢到一个内部容器里,然后StorageProxy来完成具体的工作,CassandraServer再把它拿回到thrift。

StorageService is kind of the internal counterpart to CassandraDaemon. It handles turning raw gossip into the right internal state.

StorageService是一个类似内部CassandraDaemon的玩艺儿。它就是为了让那些还没处理过的请求待在他们应该在的位置上。

AbstractReplicationStrategy controls what nodes get secondary, tertiary, etc. replicas of each key range. Primary replica is always determined by the token ring (in TokenMetadata) but you can do a lot of variation with the others. RackUnaware just puts replicas on the next N-1 nodes in the ring. RackAware puts the first non-primary replica in the next node in the ring in ANOTHER data center than the primary; then the remaining replicas in the same as the primary.

AbstractReplicationStrategy控制节点等级。每一个键的副本都有顺序。主副本是由定义在TokenMetadata里的token ring决定的,但是在其他副本上你可以有很大的发挥空间。RackUnaware只负责把副本送到环上另外N-1个节点。RackAware把把第一个非主副本放到不同于主副本的另外一个数据中心的后续节点上;剩下的副本就跟主副本在一起了。

MessagingService handles connection pooling and running internal commands on the appropriate stage (basically, a threaded executorservice). Stages are set up in StageManager; currently there are read, write, and stream stages. (Streaming is for when one node copies large sections of its sstables to another, for bootstrap or relocation on the ring.) The internal commands are defined in StorageService; look for registerVerbHandlers.

MessagingService统筹链接并在合适的阶段运行内部命令(其实就是个线程池)。各个阶段由StageManager发起;目前包括读,写和流阶段。(流,是当一个节点需要拷贝一个大段数据到另外的节点时,提供环上的引导和重定位。)内部命令在StorageService中定义,参考registerVerbHandlers。

- 阅读剩余部分 -

写在腊月二十九

腊月二十九,我坐在办公室里。办公室很清静,三两同事在远处敲着键盘,这个时候办公室不是一个合适的氛围。

今年是自己出来以后的第一个春节,此前的那些印象已经模糊了,因为可以在随便想回家的时候就回去,因为周围的人们也都一样,大家还在无忧无虑的过着梦一样的校园生活。不用面对无奈的生活,不用面对反常的社会,只要简单的做好自己。而现在,有人还在为工作奔波着,有人还在准备考研...大家都在各自忙碌着,而到了这个时候,这些,我也更想念大家,想念曾经那种日子,那种不可能再回来的日子。

往年春节总要想想给爸妈带点什么东西,今年呢,忙忙碌碌的,实在是没想起来买什么东西...想来想去,爸妈需要什么,还是回去多陪陪爸妈吧。

上午出门的时候,冷,很冷,还有风,冷的有年味。路上的人多是提着大包小包的行李,匆匆忙忙的赶路,想起网易的一个春节专题栏目 1/10流浪的中国,我也在流浪啊。几个小时以后,我也会这般样子走在回家的路上,不知道是高兴呢,还是有些凄凉。唉,天都这么凉了,还是幸福一点吧,就要回家了。

想想有很多话要说,坐下又写不出来,只祝福大家新年快乐,祝福爸妈身体健康,祝福,祝福...

我看“结对编程”

在公司的一个项目的第二次迭带中,团队决定尝试使用结对编程的方式。我从未尝试过这种编程方式,但仅从想像中去衡量,其实我并不喜欢这种方式,也不认为这种方式会提高我个人的工作效率,又或者对我个人成长真的有那么大的利好,以至于我们要迫不及待的去进行。但团队中几乎全部同事同时认为这是一件大好事,因此我决定还是用一天的时间去试试,去体验一把,再做定论。

当我结束一天的结对编程后,回到家里小总结了一下,虽然跟上面提到的想像中的场景不太一样,但结论仍然是:我个人对这事不太感冒。但出于这样的考虑,可能是由于初试这种工作方式,不得要领,又是戴着些许情绪的,所以结果会比较负面,我决定再去尝试一天,而且努力去适应它,但如果一天工作结束后,结果仍然很不乐观,那么我认为这是一中不好的工作方式,至少对我来说是不好的。

------------以上是周一晚上记录在google docs上的------------

今天白天我再次让自己尝试结对,一个上午的时间...我下午决定放弃结对,中午跟Team吃饭的时候,讨论到这个话题,谈到了“因人而异”,确实这个工作法真的是因人而异。

------------以上是周二晚上的记录------------

题记:今天周五,team周会,我们谈到了“结对编程”的问题,还有之前我查了一些关于“结对编程”的资料,这里我就说说我对“结对编程”这种工作方式的看法。

首先,我们要明确,“结对编程”这仍然是一个处在试验阶段的工作方法,我去查了一些学术资料,无一例外,所有的文章对“结对编程”的介绍都是持试验态度,分别介绍其优劣。另外一些文章中,虽有对“结对编程”大肆追捧的,却也在一部分,没有一边倒的迹象。但在国内的一些文章中,这个比例的确较高。

本文,我也不讲“结对编程”的优劣势,网上到处都有,稍后文章后面附上一些资料,只聊聊这一周我的感受。

在我看来,“结对编程”作为一种工作方式的诞生,是对“编程”这个工作本质的一种转移。或者说在某些变成活动中“结对”并不合适,而在另外一些则可以。“结对编程”的优势无非在于:提高代码可读性,减少项目个人依赖,降低错误率,促进个人成长。但我们看这些特性,事实上并不属于一个绝对意义,或者说纯粹意义上的编程(hack理念的编程),而是一种代码工业化的最需要具有的性质。

但这种工业化需要的性质,通过“结对”方式也不能保证达到,因为不同的程序员有着不同的工作习惯,有些人就是喜欢单独工作,不希望别人的干扰,当“结对”时,会大大降低他的工作效率和工作质量,这就适得其反了。

说道具体的工作中,往往我们容易使用一些极端做法去做事,这明显是存在问题的。例如在项目中大规模使用“结对编程”的工作方式,而没有考虑到这种仍然处在试验中的工作方式到底是否适合我们这个团队,到底是否适合团队中的每个人。

在工作方法的选择上需要因事而异,更需要因人而异,谨慎选择。

- 阅读剩余部分 -