介绍:
Kafka是一个高吞吐量的分布是消息系统 ,原本开发自LinkedIn,用作LinkedIn的活动流(activity stream)和运营数据处理管道(pipeline)的基础。现在它已为多家不同类型的公司作为多种类型的数据管道(data pipeline)和消息系统使用。
现在Kafak作为apache的项目,被apache托管。
企业应用的背景:
企业集成的基本特点是把企业中现存的本不相干的各种应用进行集成。例如:一个企业可能想把财务系统和仓管系统进行集成,减少部门间结算和流通的成本和时间,并能更好的支持上层决策。但这两个系统是由不同的厂家做的,不能修改。另外企业集成是一个持续渐进的过程,需求变化非常频繁。这对MQ系统的要求是要非常灵活,可定制性要求高。所以常见的MQ系统通常都可以通过复杂的xml配置或插件开发进行定制以适应不同企业的业务流程的需要。他们大多数都能通过配置不同程度的支持EIP中定义一些模式。但设计目标并没有很重视扩展性和性能,因为通常企业级应用的数据流和规模都不会非常大。即使有的比较大,使用高配置的服务器或做一个简单几个节点的集群就可以满足了。
大规模的service是指面向公众的向facebook,google,linkedin和taobao这样级别或有可能成长到这个级别的应用。相对企业集成来讲,这些应用的业务流程相对比较稳定。子系统间集成的业务复杂度也相对较低,因为子系统通常也是经过精心选择和设计的并能做一定的调整。所以对MQ系统的可定制性及定制的复杂性要求并不高。但由于数据量会非常巨大,不是几台Server能满足的,可能需要几十甚至几百台,且对性能要求较高以降低成本,所以MQ系统需要有很好的扩展性。
kafka正是一个满足SaaS要求的MQ系统,它通过降低MQ系统的复杂度来提高性能和扩展性。
使用场景:
可靠性(一致性)
MQ要实现从producer到consumer之间的可靠的消息传送和分发。传统的MQ系统通常都是通过broker和consumer间的确认(ack)机制实现的,并在broker保存消息分发的状态。即使这样一致性也是很难保证的(当然kafka也支持ack)。kafka的做法是由consumer自己保存状态,也不要任何确认。这样虽然consumer负担更重,但其实更灵活了。因为不管consumer上任何原因导致需要重新处理消息,都可以再次从broker获得。
kafka的producer有一种异步发送的操作。这是为提高性能提供的。producer先将消息放在内存中,就返回。这样调用者(应用程序)就不需要等网络传输结束就可以继续了。内存中的消息会在后台批量的发送到broker。由于消息会在内存呆一段时间,这段时间是有消息丢失的风险的。所以使用该操作时需要仔细评估这一点。
高可用性
Kafaka可以将log文件复制到其他topic的分隔点(可以看成是server)。当一个server在集群中fails,可以允许自动的failover到其他的复制的server,所以消息可以继续存在在这种情况下。
扩展性
kafka使用zookeeper来实现动态的集群扩展,不需要更改客户端(producer和consumer)的配置。broker会在zookeeper注册并保持相关的元数据(topic,partition信息等)更新。而客户端会在zookeeper上注册相关的watcher。一旦zookeeper发生变化,客户端能及时感知并作出相应调整。这样就保证了添加或去除broker时,各broker间仍能自动实现负载均衡。
负载均衡
负载均衡可以分为两个部分:producer发消息的负载均衡和consumer读消息的负载均衡。
producer有一个到当前所有broker的连接池,当一个消息需要发送时,需要决定发到哪个broker(即partition)。这是由partitioner实现的,partitioner是由应用程序实现的。应用程序可以实现任意的分区机制。要实现均衡的负载均衡同时考虑到消息顺序的问题(只有一个partition/broker上的消息能保证按顺序投递),partitioner的实现并不容易。个人认为这一点还有待改进。
consumer读取消息时,除了考虑当前的broker情况外,还要考虑其他consumer的情况,才能决定从哪个partition读取消息。具体的机制还不是很清楚,需要做更深入的研究。
性能
性能是kafka设计重点考虑的因素。使用多种方法来保证稳定的O(1)性能。
kafka使用磁盘文件保存收到的消息。它使用一种类似于WAL(write ahead log)的机制来实现对磁盘的顺序读写,然后再定时的将消息批量写入磁盘。消息的读取基本也是顺序的。这正符合MQ的顺序读取和追加写特性。
另外,kafka通过批量消息传输来减少网络传输,并使用java中的sendfile和0拷贝机制减少从读取文件到发送消息间内存数据拷贝和内核用户态切换的次数。
根据kafka的性能测试报告(https://cwiki.apache.org/confluence/display/KAFKA/Performance+testing),它的性能基本达到了O(1)的复杂度。
一些特点:
总结
Kafk和其它绝大多数消息系统的区别,是有下面这几个比较重要的设计决策:
附:Kafka在LinkedIn中的应用:
在LinkedIn中部署后的各系统形成的拓扑结构
下面的示意图所示是在LinkedIn中部署后各系统形成的拓扑结构。
要注意的是,一个单个的Kafka集群系统用于处理来自各种不同来源的所有活动数据。它同时为在线和离线的数据使用者提供了一个单个的数据管道,在线活动和异步处理之间形成了一个缓冲区层。我们还使用kafka,把所有数据复制(replicate)到另外一个不同的数据中心去做离线处理。
我们并不想让一个单个的Kafka集群系统跨越多个数据中心,而是想让Kafka支持多数据中心的数据流拓扑结构。这是通过在集群之间进行镜像或“同步”实现的。这个功能非常简单,镜像集群只是作为源集群的数据使用者的角色运行。这意味着,一个单个的集群就能够将来自多个数据中心的数据集中到一个位置。下面所示是可用于支持批量装载(batch loads)的多数据中心拓扑结构的一个例子:
请注意,在图中上面部分的两个集群之间不存在通信连接,两者可能大小不同,具有不同数量的节点。下面部分中的这个单个的集群可以镜像任意数量的源集群。要了解镜像功能使用方面的更多细节。
原创文章,欢迎转载,转载请标明出处 http://write.blog.csdn.net/postedit/40818711