python kafka怎么对多个分区同时消费 kafka一个partition多customer_服务器

上图之所以故意把partition和comsumer的数量画不一致,是想表示,一个comsumer可以去消费多个partition,这里大家要明白,consumer和partition不是一对一的关系,可以是一对多。

你可能会在网上搜资料的时候看到很多人都这么说:“topic是一个逻辑上的概念,它不是一个物理概念”,然后补充到,“partition是一个物理概念”。

一开始看的时候确实很想不懂是什么意思,但其实可以这么理解,topic只是为了方便消费者消费时的“定位”,消费者知道自己需要监听(listener)的是哪个,仅此而已,但其实消费者真的去拿信息的时候,是按照partition去拿的。

比如有一个topic名为“topic-test”,我们假设它有三个分区partition。那么这三个分区的名字分别为“topic-test-partition1”、“topic-test-partition2”、“topic-test-partition3”。因为不同的partition一般是分布在不同的broker上的(在集群的环境下,如果你只有一台机器那就会放在同一个broker),所以消费者consumer就会去不同的broker根据topic去找到所有的partition。这样说可能也不太清楚,看图就比较清楚了。

python kafka怎么对多个分区同时消费 kafka一个partition多customer_kafka_02

这里补充一个点,每个分区只能由同一个消费组内的一个消费者(consumer)来消费,但可以由不同的消费组来消费,没有限制,这里可以理解为kafka发布消息时是以广播的形式向所有消费者发送。

这里就涉及到并发的问题。kafka对消息进行分区的理由也在此,因为消息被分成了好多个分区被一个消费组消费,那么当消费组里有3个消费者的时候,消费处理的并发量就是3。(这里的并发量用的不是很恰当,不过大概的逻辑是这个意思)

所以这里最好有这样的关系

partition数量 <= 消费组里消费者数量 + 1

消费者太多会导致某些消费者没有分区可以读取,消费者太少会导致多出来的分区没有消费者去消费,或者说分配不均匀。所以这里优化一下上面的公式应该是

partition数量 <= (消费组里消费者数量 )* N + 1

这里的 + 1 是为了防止有服务宕机,宕机时就有新的服务器顶上,这个应该很好理解吧,不要去纠结于为什么是1就可以了,这里只是举个栗子。

# 副本replication

这里也应该补充一下,图里没有画出来的副本,其实kafka在每次接受信息时都会复制出多个副本到多个broker上的。复制的单位是partition,也就是说,以上图为例的话,topic-0-partition-1在写到broker(192.168.201.127)的时候,也会复制出来两个topic-0-partition-1副本存放到另外的两台broker。当然,这里并不是说kafka都会把partition备份到每一台broker上,一般不会这样,备份太多会导致性能下降,所以这个数量也是很有考究的,这取决于你能接受同时有多少台broker会宕机。

# 消费组内的消费者共享读取到的partition

准确地说,同个组内的消费者会共享彼此读取到的同个topic的partition,这也就是为什么说kafka只能保证单个partition内的消息顺序,而无法保证总的消息顺序。

如果你向kafka发送新登上四皇宝座的人名时,这是后你想要从文字上表达你的震惊之情,你打算分四次发送,“小!”,“丑!”,“巴!”,“基!”,(你没有指定key值),然后四个partition把你的信息都打乱了,变成了“基!巴!丑!小!”那事情就大条了。

这里也可以说一下,一般来说单条发送的信息是不会被分配到不同的partition上的,每一条在对应的partition上。

所以当你对消息的顺序要求十分严格的话,你可以只设置一个partition,或者你在send()的时候指定一个“key”,有了key之后就会分配到同一个partition上(哈希散列函数,输入同一个值得到同一个结果)。