Kafka中消息分配策略
非淡泊无以明,非宁静无以致远
Question
关于kafka
中partation
和consumer
的是如何执行分配的。今早骑自行车的时候突然想起这个问题。它是怎么分配的,我记得我看到好几次相关的介绍文章,现在却想不起来?
sense
很多时候,我们在看完一篇技术文档时,感觉对其中的内容都了解了,其实不然。这也是所谓的被动输入和主动输出的区别所在。相比主动输出而言,被动输入缺少了深层思考的态度。得到一些老师的课里就谈到过主动输出的重要性。
很多概念都已经记不起来了,文章的内容可能也不够准确,但重在思考和想法的过程:
Thinking
partaion
是数据的存储单位,一个topic
至少存在一个partation
。consumer
使用主动拉数据的方式来消费消息,这就是所有已知概念。那么partation
和consumer
是如何分配的呢?这里我们假设消息数据总量是一样的。
首先,应该存在一个类似LVS
的负载均衡器,因为当consumer
增加或者减少时,对应的分配策略也需要做相应的调整。在consumer
注册成为消费者时,提交的信息中有consumer Group
的概念,这非常好理解,即同一个组的consumer
会独立处理一份数据。同时,因为有了Group
,我们在管理的时候就会简单很多。当然,所有的讨论都是以一个Group
为前提的。
1:1
从最简单的开始考虑,假设现在partation
和consumer
的数量比例是1:1
,那就没有那么多事了,简单明了。
1:2
假设是1:2
呢?问题来了,好比现在只有一个数据,但有AB
两个线程都要读它,且A
和B
中有且只有一个能读到。这种情况在计算机中相当普遍,通用的处理方式就是加锁,以保证数据只被其中一个线程处理。但加锁就意味着性能开销,尤其是高并发的场景。
继续按照这个思路来考虑,两个consumer
同时向一个partation
发起请求,需要一个全局锁来控制每个消息只能返回给请求中的一个。相比较1:1
的方式,这样的性能肯定是提高了不少。
2:1
假设是2:1
呢?这个也很直观,两份数据,但只有一个消费者,那肯定都需要这一个消费者来处理了,就跟CPU
任务调度还有些类似。
如果跟1:2
的分配策略比较呢?这里通过将原来的一份数据平均分成两份,去掉了1:2
中加锁的开销,但只有一个connsumer
来消费数据。好比是单核CPU
任意处理数据跟双核CPU
加锁处理数据。
2:2
假设是2:2
呢,我们可以平均分配partation
和consumer
,而且这样系统性能却得到最大提升,不仅去掉了锁的开销,还有两个线程来同时消费。
结论
通过上面的对比,我们可以清楚的发现,通过调整partation
和consumer
的数量就可以将系统性能达到最大,完全不需要引入锁机制。这样想的话,分配就很简单了。