kafka 相关调研很多,其中以FrankHui大神(http://my.oschina.net/ielts0909)的kafka系列文章非常精彩,悲催的是,前期调研时候没有看到,老老实实的看完了Apache kafka官方文档(http://kafka.apache.org/introduction.html),但还是云里雾里,和同事讨论的时候发现很多细节都没有琢磨清楚,再看kafka孵化MQ产品MetaQ(http://www.iteye.com/magazines/107)的相关资料和FrankHui的系列博文,对照官方设计文档,有了更清楚的认识。
kafka比较新颖的特色如以下:
1 结合实时数据和离线大数据两种数据处理业务,因此方便有相关需求的同志不需要搭建hadoop专门处理离线数据,而后又搭建storm等来处理实时数据;
2 采取文件系统作为数据存储介质,而不是像ZeroMq之类的基于内存的mq,设计体现的好处是既能保证高吞吐率的同时,又能保证极端情况下数据的恢复,更好的是,极大节约了内存成本。当然为了媲美基于内存MQ的读写性能,kafka做了一些巧妙的设计,最突出的就是利用顺序读写代替基于BTree的读写方式和Zero-copy(具体技术细节见https://www.ibm.com/developerworks/linux/library/j-zerocopy/)。另外,持久化的问题也迎刃而解。
3 利用consumer存储消费信息,而非传统的broker存储,这样好处是避免的broker存储时对Message的多标签化。具体而言,如果由broker存储消息,一条Message的消费分为broker下发->consumer确认消费->broker确认3个状态,中间涉及两次网络通信,期间可能引起各种原因导致的重下发,而重下发又涉及到消息回滚的排序方式。简而言之,如果重下发的消息入队首,能够立刻下发,减小延迟,但是可能出现该消息错误引起的队列阻塞;入队尾,可能产生很长时间的延迟。
如果换consumer存储消息,可以避免上述麻烦,感觉这个设计很赞,但是其存在基础是基于kafka顺序读写的设计方式。具体这样做有什么可能的弊端呢?自己当初设计类似流程的时候都在扣标签细节,怎么没有想到这个思路?思维太固化了还是新方案有什么缺陷?(欢迎讨论)
4 利用游标offset来标注消费数据,可以非常方便的回滚信息。
5 利用语义分区实现partition,并且保证一个分区发给一个消费组里面的一个consumer,由于partition中消息有序,从而保证该consumer的接收消息有序,从而实习数据收发一致性,并同时保证负载均衡。
kafka可能的问题:
1 负载均衡问题:如果有些生产者产生的消息远多于其它生产者,按每个代理对TCP连接进行平均分配可能会导致每个代理接收到的消息总数并不平均;
2 消息推拉方式:kafka采用producer push消息,consumer poll消息的方式,可能会出现一些应用场景不匹配问题;
3 partitions 没有副本控制。
以上问题我在kafka 0.8中已经看到有所更新,衷心佩服各位大牛!
接下去我去继续写一些关于源码和具体调试中关于kafka的一些想法。新人报道,知识水平,表达方式各方面都存在欠缺,希望大家海涵,同时也希望大家一定要多多指出不足,多多交流,谢谢。