kafka 分区数和吞吐量的关系
点击上方蓝字“极客运维”一起运筹帷幄
分区(partition)概念
要讲 kafka 分区数和吞吐量的关系,首先得理解什么是分区(partition)。
Partition
是作用于具体的 Topic
而已的,而不是一个独立的概念。 Partition
能水平扩展客户端的读写性能,是高吞吐量的保障。通俗的讲, Partition
就是一块保存具体数据的空间,本质就是磁盘上存放数据的文件夹,所以 Partition
是不能跨 Broker
存在的,也不能在同一个 Broker
上跨磁盘。对于一个 Topic
,可以根据需要设定 Partition
的个数。数据持久化时,每条消息都是根据一定的分区规则路由到对应的 Partition
中,并 append
在 log
文件的尾部(这一点类似于 HDFS
),如上图;在同一个 Partition
中消息是顺序写入的且始终保持有序性;但是不同 Partition
之间不能保证消息的有序性(高吞吐量的保障)。 kafka
就是通过使用分区的设计将 topic
的消息打散到多个分区分布保存在不同的 broker
上,实现了 producer
和 consumer
消息处理的高吞吐量。
吞吐量关系
在 kafka
中, Partition
并不是最小的数据存储单元。 Partition
下还可以细分成 Segment
,每个 Partition
是由一个或多个 Segment
组成。但 patition
是 kafka
并行操作的最小单元。在 producer
和 broker
端,向每一个分区写入数据是可以完全并行化的,此时,可以通过加大硬件资源的利用率来提升系统的吞吐量,例如对数据进行压缩。在 consumer
端, kafka
只允许单个 partition
的数据同时被一个 consumer
线程消费。因此,在 consumer
端,每一个 Consumer Group
内部的 consumer
并行度完全依赖于被消费的分区数量。因此,通常情况下,在一个 Kafka 集群中, partition
的数量越多,意味着可以到达的吞吐量越大。
我们可以粗略地通过吞吐量来计算 kafka
集群的分区数量。假设对于单个 partition
, producer
端的可达吞吐量为 p, Consumer
端的可达吞吐量为 c,期望的目标吞吐量为 t,那么集群所需要的 partition
数量至少为 max(t/p,t/c)
。在 producer
端,单个分区的吞吐量大小会受到批量大小、数据压缩方法、确认类型(同步/异步)、复制因子等配置参数的影响。经过测试,在 producer
端,单个 partition
的吞吐量通常是在 10MB/s 左右。在 consumer
端,单个 partition
的吞吐量依赖于 consumer
端每个消息的应用逻辑处理速度。因此,我们需要对 consumer
端的吞吐量进行测量。
分区扩展
虽然随着时间的推移,我们能够对分区的数量进行添加,但是对于基于 Key
来生成的这一类消息不太一样。当 producer
向 kafka
写入基于 key
的消息时, kafka
通过 key
的 hash
值来确定消息需要写入哪个具体的分区。通过这样的方案, kafka
能够确保相同 key
值的数据可以写入同一个 partition
。 kafka
的这一能力对于一部分顺序要求的业务应用是极为重要的,例如对于同一个 key
的所有消息, consumer
需要按消息的顺序进行有序消费。如果 partition
的数量发生改变,那么上面的有序性保证将不复存在。为了避免上述情况发生,通常的解决办法是多分配一些分区,以满足未来的需求。
此外,我们还可以基于当前的业务吞吐量为 kafka
集群分配较小的 broker
数量,随着业务增长,再向集群中增加更多的 broker
,然后将适当比例的 partition
迁移到新增加的 broker
中去(迁移可以参考我之前的文章)。通过这样的方法,可以在满足各种应用场景(包括基于 key
消息的场景)的情况下,保持业务吞吐量的扩展性。
在规划分区数时,除了吞吐量,还有一些其他因素值得考虑,后续再聊。