kafka
基本概念
kafka的工作方式和其他MQ基本相同,只是在一些名词命名上有些不同。为了更好的讨论,这里对这些名词做简单解释。通过这些解释应该可以大致了解kafka MQ的工作方式。
- Producer (P):就是网kafka发消息的客户端
- Consumer (C):从kafka取消息的客户端
- Topic (T):可以理解为一个队列
- Consumer Group (CG):这是kafka用来实现一个topic消息的广播(发给所有的consumer)和单播(发给任意一个consumer)的手段。一个 topic可以有多个CG。topic的消息会复制(不是真的复制,是概念上的)到所有的CG,但每个CG只会把消息发给该CG中的一个 consumer。如果需要实现广播,只要每个consumer有一个独立的CG就可以了。要实现单播只要所有的consumer在同一个CG。用CG还 可以将consumer进行自由的分组而不需要多次发送消息到不同的topic。
- Broker (B):一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic。
- Partition(P):为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上。kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(多个partition间)的顺序。
可靠性(一致性)
MQ要实现从producer到consumer之间的可靠的消息传送和分发。传统的MQ系统通常都是通过broker和consumer间的确认 (ack)机制实现的,并在broker保存消息分发的状态。即使这样一致性也是很难保证的(参考原文)。kafka的做法是由consumer自己保存 状态,也不要任何确认。这样虽然consumer负担更重,但其实更灵活了。因为不管consumer上任何原因导致需要重新处理消息,都可以再次从 broker获得。
kafka的producer有一种异步发送的操作。这是为提高性能提供的。producer先将消息放在内存中,就返回。这样调用者(应用程序) 就不需要等网络传输结束就可以继续了。内存中的消息会在后台批量的发送到broker。由于消息会在内存呆一段时间,这段时间是有消息丢失的风险的。所以 使用该操作时需要仔细评估这一点。
另外,在最新的版本中,还实现了broker间的消息复制机制,去除了broker的单点故障(SPOF)。
扩展性
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的性能测试报告,它的性能基本达到了O(1)的复杂度。
3. 总结
从以上来看,个人觉得kafka比较适合用来做简单的消息传递和分发,能支持大数据量。但如果需要实现复杂的EIP模式,则不像传统MQ那么容易。 而且,因为只有partition内的消息才能保证传递顺序,如果消息的顺序很重要,又需要很好的扩展性,使用kafka实现可能会比较困难。所 以,kafka应该比较适合处理简单的事件和消息,例如数据(log)收集,大量事实数据的实时分析(kafka可与MapReduce集成)。
1、 概述
Kafka是Linkedin于2010年12月份开源的消息系统,它主要用于处理活跃的流式数据。活跃的流式数据在web网站应用中非常常见,这 些数据包括网站的pv、用户访问了什么内容,搜索了什么内容等。 这些数据通常以日志的形式记录下来,然后每隔一段时间进行一次统计处理。
传统的日志分析系统提供了一种离线处理日志信息的可扩展方案,但若要进行实时处理,通常会有较大延迟。而现有的消(队列)系统能够很好的处理实时或 者近似实时的应用,但未处理的数据通常不会写到磁盘上,这对于Hadoop之类(一小时或者一天只处理一部分数据)的离线应用而言,可能存在问题。 Kafka正是为了解决以上问题而设计的,它能够很好地离线和在线应用。
2、 设计目标
(1)数据在磁盘上存取代价为O(1)。一般数据在磁盘上是使用BTree存储的,存取代价为O(lgn)。
(2)高吞吐率。即使在普通的节点上每秒钟也能处理成百上千的message。
(3)显式分布式,即所有的producer、broker和consumer都会有多个,均为分布式的。
(4)支持数据并行加载到Hadoop中。
3、 KafKa部署结构
kafka是显式分布式架构,producer、broker(Kafka)和consumer都可以有多个。Kafka的作用类似于缓存,即活跃的数据和离线处理系统之间的缓存。几个基本概念:
(1)message(消息)是通信的基本单位,每个producer可以向一个topic(主题)发布一些消息。如果consumer订阅了这个主题,那么新发布的消息就会广播给这些consumer。
(2)Kafka是显式分布式的,多个producer、consumer和broker可以运行在一个大的集群上,作为一个逻辑整体对外提供服 务。对于consumer,多个consumer可以组成一个group,这个message只能传输给某个group中的某一个consumer.
4、 KafKa关键技术点
(1) zero-copy
在Kafka上,有两个原因可能导致低效:1)太多的网络请求 2)过多的字节拷贝。为了提高效率,Kafka把message分成一组一组的,每次请求会把一组message发给相应的consumer。 此外, 为了减少字节拷贝,采用了sendfile系统调用。为了理解sendfile原理,先说一下传统的利用socket发送文件要进行拷贝:
Sendfile系统调用:
(2) Exactly once message transfer
怎样记录每个consumer处理的信息的状态?在Kafka中仅保存了每个consumer已经处理数据的offset。这样有两个好处:1)保 存的数据量少 2)当consumer出错时,重新启动consumer处理数据时,只需从最近的offset开始处理数据即可。
(3)Push/pull
Producer 向Kafka(push)推数据,consumer 从kafka 拉(pull)数据。
(4)负载均衡和容错
Producer和broker之间没有负载均衡机制。
broker和consumer之间利用zookeeper进行负载均衡。所有broker和consumer都会在zookeeper中进行注册,且 zookeeper会保存他们的一些元数据信息。如果某个broker和consumer发生了变化,所有其他的broker和consumer都会得到 通知。