如何决定kafka集群中话题的分区的数量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何决定kafka集群中话题的分区的数量相关的知识,希望对你有一定的参考价值。

参考技术A 如何决定kafka集群中topic,partition的数量,这是许多kafka用户经常遇到的问题。本文列举阐述几个重要的决定因素,以提供一些参考。
分区多吞吐量更高

一个话题topic的各个分区partiton之间是并行的。在producer和broker方面,写不同的分区是完全并行的。因此一些昂贵的操作比如压缩,可以获得更多的资源,因为有多个进程。在consumer方面,一个分区的数据可以由一个consumer线程在拉去数据。分区多,并行的consumer(同一个消费组)也可以多。因此通常,分区越多吞吐量越高。
基于吞吐量可以获得一个粗略的计算公式。先测量得到在只有一个分区的情况下,Producer的吞吐量(P)和Consumer的吞吐量(C)。那如果总的目标吞吐量是T的话,max(T/P,T/C)就是需要的最小分区数。在单分区的情况下,Producer的吞吐量可以通过一些配置参数,比如bath的大小、副本的数量、压缩格式、ack类型来测得。而Consumer的吞吐量通常取决于应用程序处理每一天消息逻辑。这些都是需要切合实际测量。
随着时间推移数据量的增长可能会需要增加分区。有一点需要注意的是,Producer者发布消息通过key取哈希后映射分发到一个指定的分区,当分区数发生变化后,会带来key和分区映射关系发生变化。可能某些应用程序依赖key和分区映射关系,映射关系变化了,程序就需要做相应的调整。为了避免这种key和分区关系带来的应用程序修改。所以在分区的时候尽量提前考虑,未来一年或两年的对分区数据量的要求。
除了吞吐量,还有一些其他的因素,在定分区的数目时是值得考虑的。在某些情况下,太多的分区也可能会产生负面影响。

分区多需要的打开的文件句柄也多

每个分区都映射到broker上的一个目录,每个log片段都会有两个文件(一个是索引文件,另一个是实际的数据文件)。分区越多所需要的文件句柄也就越多,可以通过配置操作系统的参数增加打开文件句柄数。

分区多增加了不可用风险

kafka支持主备复制,具备更高的可用性和持久性。一个分区(partition)可以有多个副本,这些副本保存在不同的broker上。每个分区的副本中都会有一个作为Leader。当一个broker失败时,Leader在这台broker上的分区都会变得不可用,kafka会自动移除Leader,再其他副本中选一个作为新的Leader。Producer和Consumer都只会与Leader相连。
一般情况下,当一个broker被正常关机时,controller主动地将Leader从正在关机的broker上移除。移动一个Leader只需要几毫秒。然当broker出现异常导致关机时,不可用会与分区数成正比。假设一个boker上有2000个分区,每个分区有2个副本,那这样一个boker大约有1000个Leader,当boker异常宕机,会同时有1000个分区变得不可用。假设恢复一个分区需要5ms,1000个分区就要5s。
分区越多,在broker异常宕机的情况,恢复所需时间会越长,不可用风险会增加。

分区多会增加点到点的延迟

这个延迟需要体现在两个boker间主备数据同步。在默认情况下,两个boker只有一个线程负责数据的复制。

根据经验,每个boker上的分区限制在100*b*r内(b指集群内boker的数量,r指副本数量)。
分区多会增加客户端的内存消耗

kafka0.8.2后有个比较好的特色,新的Producer可以允许用户设置一个缓冲区,缓存一定量的数据。当缓冲区数据到达设定量或者到时间,数据会从缓存区删除发往broker。如果分区很多,每个分区都缓存一定量的数据量在缓冲区,很可能会占用大量的内存,甚至超过系统内存。
Consumer也存在同样的问题,会从每个分区拉一批数据回来,分区越多,所需内存也就越大。
根据经验,应该给每个分区分配至少几十KB的内存。
总结

在通常情况下,增加分区可以提供kafka集群的吞吐量。然而,也应该意识到集群的总分区数或是单台服务器上的分区数过多,会增加不可用及延迟的风险。本回答被提问者采纳

生产环境一键创建kafka集群

    前段时间公司的一个kafka集群出现了故障,由于之前准备不足,当时处理的比较慌乱。如:由于kafka的集群里topic数量较多,并且每个topic的分区数量和副本数量都不是一样的,如果按部就班的一个一个的去创建队列,估计集群恢复时黄瓜菜都凉了。

    对于kafka集群出现故障,最快的处理办法,就是重建集群,然后在新的集群上将队列相关信息全部按原集群重建一遍。本人利用端午假期,写了一个python脚本(这是第二次撸python,能用就好,各位要求不要太高哈),可以实现一键功能。

    1.首先将此脚本(topic.py),放到kafka的bin目录下;

    2.执行python topic.py命令

    3.输入原集群的zookeeper地址,回车

    4.输入新集群的zookeeper地址,回车

    5.控制台输出topic创建相关的信息,检查新集群,可以发现旧集群中所有的topic全部按原样重新在新集群中创建了一遍

    topic.py脚本如下:

import os
from sys import stdin
import re

print ‘input source kafka zookeeper address. eg:127.0.0.1:2181‘
value = stdin.readline().replace("
", "")
print ‘input target kafka zookeeper address. eg:127.0.0.1:2181‘
target = stdin.readline().replace("
","")
value2 = ‘./kafka-topics.sh  --describe --zookeeper ‘ +value 
value2 = value2+‘ | grep ^Topic‘
output = os.popen(value2)
text = output.readline()
while (text ):
	strs = text.split()
	outtemp = os.popen(‘./kafka-topics.sh --create --topic ‘+strs[0].replace("Topic:","") +‘ --partitions ‘+strs[1].replace("PartitionCount:","") + ‘ --replication-factor ‘ +strs[2].replace("ReplicationFactor:","")+ ‘ --if-not-exists --zookeeper ‘ + target) 
	print outtemp.readline()
	text = output.readline()
	outtemp.close()
output.close()

  

    

以上是关于如何决定kafka集群中话题的分区的数量的主要内容,如果未能解决你的问题,请参考以下文章

2、kafka如何选定分区数量

kafka分区数量限制

如何为Kafka集群选择合适的Partitions数量

如何为Kafka集群选择合适的Partitions数量

如何为Kafka集群选择合适的Topics/Partitions数量

Kafka的分区机制