1. 介绍

如何确定kafka的分区数相信是大家在使用kafka过程中比较关心的一个问题。早些时候,阿里的rocket mq在github上有和kafka比较(这里和老版本的kafka比较,估计是0.8的,现在是0.10.x)的说明。不过现在已经换掉了,而且也看到rocket mq支持集成kafka。可见kafka还是确实越来越受到市场认可。那篇老文章可以看网上这篇博文:RocketMQ与Kafka对比(18项差异)

文中提到了“Kafka单机超过64个队列/分区,Load会发生明显的飙高现象,队列越多,load越高,发送消息响应时间变长”这个问题。针对这个问题,其实kafka的开发者已经专门写过博文讨论过,见:How to choose the number of topics/partitions in a Kafka cluster?

本文对该片博文内容做一些说明和总结。

2. 分区数和吞吐量

一般来说,其他参数固定的情况下,增加分区数可以提升并行度从而来提高吞吐量。实际每个分区的吞吐性能受到诸多因素影响(各种配置、硬件情况等)。可以参考评测的资料(使用的kafka版本有点老,现在肯定更好了!)Benchmarking Apache Kafka: 2 Million Writes Per Second (On Three Cheap Machines)。每个分区的吞吐量在MB/s数量级一般来说是没有问题的。

3. 设定多少分区数

分区数的设定,需要一定的前瞻性。考虑未来2年后的吞吐性能要求作为现在设定分区数的依据是比较合理的。

4. 增加分区数的风险

3.1 增加分区对数据分布的影响

一般来说分区数还是提前固定好为宜。增加分区数会使得发送的数据在分区上的分布改变。kafka有个保证,即相同key的可以被hash到一个分区上。如果分区数改变了,这种保证就无法做到了。这回影响消费者的消费。当然,如果消费者不关心在一个分区内的数据的key值,那么这样做也是没问题的。

3.2 更多Open File Handles

增加分区数导致文件增多,从而需要创建更多的文件句柄。这在文件管理上会有额外的开销。

3.3 影响可用性

当一个broker异常关闭时,由于分区增多导致选举leader耗时更久,这样使得分区的不可用时间变长。如果出问题的broker正好是controller那就更加倒霉了,因为要新failover到一个新的controller,这也会耗不少时间。由于增加了分区数,failover的时候,新的controller获取元信息需要花更久时间。

3.4 增加end-to-end延迟

消费者消费需要等replication完毕。如果分区数多了,这个也可能增加几十毫秒甚至更多的延迟。这对实时性要求较高的应用会产生影响。

如果是实时性应用,对延迟很敏感的。建议每个broker上的分区数控制在: 单broker分区个数=100 乘以 broker数量 乘以 复制份数

3.5 导致客户端需要更多的内存

发送者发送到每个分区的时候,都有对应的缓存。分区数的增多,也需要增加相应的缓存。

4. 总结

  1. 延迟性高的应用(分区复制延迟在10毫秒以内): 考虑使用公式: 单broker分区个数=100 乘以 broker数量 乘以 复制份数 来设置分区数
  2. 延迟性不是很高的应用或者相对来说瓶颈在客户端上的: 可视尽量按照吞吐量需求设置较大的分区数