作者:Zarten
知乎专栏:Python爬虫深入详解
知乎ID: Zarten
简介: 互联网一线工作者,尊重原创并欢迎评论留言指出不足之处,也希望多些关注和点赞是给作者好的鼓励 !
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完成的。
参考文章: