Kafka架构图
1.架构图
如上图,一个kafka架构包括若干个Producer(服务器日志、业务数据、web前端产生的page view等),若干个Broker(kafka支持水平扩展,一般broker数量越多集群的吞吐量越大),若干个consumer group,一个Zookeeper集群(kafka通过Zookeeper管理集群配置、选举leader、consumer group发生变化时进行rebalance)。
2.名称解释
- Broker
消息中间件处理节点(服务器),一个节点就是一个broker,一个Kafka集群由一个或多个broker组成
- Topic
Kafka对消息进行归类,发送到集群的每一条消息都要指定一个topic
- Partition
物理上的概念,每个topic包含一个或多个partition,一个partition对应一个文件夹,这个文件夹下存储partition的数据和索引文件,每个partition内部是有序的
- Producer
生产者,负责发布消息到broker
- Consumer
消费者,从broker读取消息
- ConsumerGroup
每个consumer属于一个特定的consumer group,可为每个consumer指定group name,若不指定,则属于默认的group,一条消息可以发送到不同的consumer group,但一个consumer group中只能有一个consumer能消费这条消息
3.关系解释
- Topic & Partition
一个topic为一类消息,每条消息必须指定一个topic。物理上,一个topic分成一个或多个partition,每个partition有多个副本分布在不同的broker中,如下图3.1。
每个partition在存储层面是一个append log文件,发布到此partition的消息会追加到log文件的尾部,为顺序写人磁盘(顺序写磁盘比随机写内存的效率还要高)。每条消息在log文件中的位置成为offset(偏移量),offset为一个long型数字,唯一标记一条消息。如下图3.2
每个消费者唯一保存的元数据是offset值,这个位置完全为消费者控制,因此消费者可以采用任何顺序来消费记录,如下图3.3
图3.1
另外,对于传统的消息队列而言,一般会删除已经被消费的消息,而kafka集群会保留所有的消息。因为磁盘限制,不可能永久保留所有消息,因此kafka提供了两种策略删除数据:1.基于时间,让kafka删除2天或一周的数据;2.基于partition文件大小:让kafka在partition文件超过1GB时删除数据
图3.2
图3.3
kafka中只能保证partition中记录是有序的,而不保证topic中不同partition的顺序
- Consumer group & consumer
一个消费组由一个或多个消费者实例组成,便于扩容与容
错。kafka是发布与订阅模式,这个订阅者是消费组,而不是消费者实例。每一条消息只会被同一个消费组里的一个消费者实例消费,不同的消费组可以同时消费同一条消息,如下图
为了实现传统的消息队列中消息只被消费一次的语义,kafka保证同一个消费组里只有一个消费者会消费一条消息,kafka还允许不同的消费组同时消费一条消息,这一特性可以为消息的多元化处理提供了支持,kafka的设计理念之一就是同时提供离线处理和实时处理,因此,可以使用Storm这种实时流处理系统对消息进行实时在线处理,同时使用Hadoop这种批处理系统进行离线处理,还可以同时将数据实时备份到另一个数据中心,只需要保证这三个操作的消费者实例在不同consumer group 即可
创建一个topic(名为topic1,3个partition 0,1,2),group1有1个consumer,group2中有3个consumer,通过producer向topic1发送3条消息(key分别为1,2,3),结果group1中的1个consumer收到了所有这2条消息,group2中的3个consumer分别收到了这3条消息,如下图
- Consumer Rebalance
kafka保证了同一个消费组中只有一个消费者实例会消费某条消息,实际上,kafka保证的是稳定状态下每一个消费者实例只会卖二手手游账号平台地图消费一个或多个特定partition数据,而某个partition的数据只会被某一特定的consumer实例消费,这样设计的劣势是无法让同一个消费组里的consumer均匀消费,优势是每个consumer不用跟大量的broker通信,减少通信开销,也降低了分配难度。而且,同一个partition数据是有序的,保证了有序被消费。根据consumer group中的consumer数量和partition数量,可以分为以下3种情况:
- 若consumer group中的consumer数量少于partition数量,则至少有1个consumer会消费多个partition数据
- 若consumer group中的consumer数量多于partition数量,则会有部分consumer无法消费该topic中任何一条消息
- 若consumer group中的consumer数量等于partition数量,则正好一个consumer消费一个partition数据
测试如下,topic1中有3个partition分别为0,1,2:
- 当group1中只有1个consumer1时,该consumer1可消费这3个partition的所有数据
- 增加1个consumer2后,consumer1消费2个partition数据,consumer2消费1个partition数据
- 再增加1个consumer3后,consumer 1,2,3 分别消费 partition 1,2,3
- 再增加1个consumer4后,3个consumer可分别消费1个partition,另1个consumer4不能消费topic1任何数据
- 此时关闭consumer1,剩下的consumer可分别消费1个partition的数据
- 再关闭consumer2,剩下的consumer3可消费2个partition,consumer4可消费1个partition
- 再关闭consumer3,剩下的consumer4可消费3个partition
consumer rebalance的控制策略是由每个consumer通过Zookeeper完成的。