赞
踩
如何选择合适的分区,这是我们经常面临的问题,不过针对这个问题,在网上并没有搜到固定的答案。因此,今天在这里主要通过性能测试的工具来告诉如何选择相对应的kafka分区。
kafka本身提供了比较的性能测试工具,我们可以使用它来测试适用于我们机器的kafka分区。
分别创建三个topic,副本数设置为1。
bin/kafka-topics.sh --zookeeper zk --create --replication-factor 1 --partitions 15 --topic test1
bin/kafka-topics.sh --zookeeper zk --create --replication-factor 1 --partitions 150 --topic test2
bin/kafka-topics.sh --zookeeper zk --create --replication-factor 1 --partitions 100 --topic test3
采用生产者性能测试工具来测试:
num-records 100万条消息
record-size 20480 每条消息是20K
throughput 用来进行限流控制 当设置为0的时候不限流(尽量还是限流,否则很有可能kafka顶不住压力),所以这里设置为每秒钟30000条消息数
bin/kafka-producer-perf-test.sh --topic topic --num-records 1000000 --record-size 20480 --throughput 30000 --producer-props bootstrap.servers="server01" acks=1
我们看实际的效果
15个分区结果
1000000 records sent, 6411.448282 records/sec (125.22 MB/sec), 253.02 ms avg latency, 1680.00 ms max latency, 108 ms 50th, 1026 ms 95th, 1173 ms 99th, 1650 ms 99.9th.
50个分区
1000000 records sent, 6274.549174 records/sec (122.55 MB/sec), 259.04 ms avg latency, 2163.00 ms max latency, 56 ms 50th, 1087 ms 95th, 1334 ms 99th, 2077 ms 99.9th.
100个分区
1000000 records sent, 6417.990912 records/sec (125.35 MB/sec), 253.42 ms avg latency, 2594.00 ms max latency, 38 ms 50th, 1154 ms 95th, 1331 ms 99th, 2537 ms 99.9th.
从中我们可以看出,分区数并不是越多越好,在吞吐量到达一定程度的时候,我们不一定要增大分区数,因为分区数过大,不会提升吞吐量(可以测试一下1000个分区甚至10000个分区,吞吐量会下降,这里就不一一演示),且会造成错误(后面解释)
bin/kafka-consumer-perf-test.sh --topic test5 --messages 100000 --broker-list "kafka-node1,kafka-node2"
消费者测试结果,我们知道kafka出来的数据单元为message,所以我们的messages就是kafka消费的条数
start.time(开始时间), end.time(结束时间), data.consumed.in.MB(消费的消息总量,单位为M), MB.sec(消费吞吐量(MB/S)), data.consumed.in.nMsg(消费的消息总数), nMsg.sec(按消息个数计算的吞吐量), rebalance.time.ms(再平衡的时间,单位为ms), fetch.time.ms(拉取消息的持续时间,单位为ms), fetch.MB.sec(每秒拉取消息的字节大小,MB/S), fetch.nMsg.sec(每秒拉取消息的个数)
2019-03-19 20:05:54:470, 2019-03-19 20:06:09:001, 1954.3359, 134.4942, 100062, 6886.1056, 3904, 10627, 183.9029, 9415.8276
这是消费者拉取数据测试的结果,我们也可以多测不同分区的几组数据,获得一个合适的kafka分区数据,来保证我们集群的稳定运行。
当然,如果想要测试其他参数,可以使用下图的方式,同理我们的生产者压测也可以通过此方式知道每个参数的含义
分区是kafka中最小的并行操作单元,对生产者而言,每一个分区的数据写入是完全可以并行化的;但是,对消费者而言,kafka只允许单个分区中的消息被一个消费者线程消费,一个消费组的消费并行度完全依赖于所消费的分区数。如果按照这种方法看来,如果一个主题中的分区数越多,理论上所能达到的吞吐量就越大,那么事实真的如此么?
我们可以使用我们生产者与消费者测试工具进行相应的测试。(可以看根据上面的,多测几组数据)
实际测试过程中,我们可以发现,开始的时候,随着分区的增长,相应的吞吐量也跟着上涨,一旦分区数超过了某个阈值后,整体的吞吐量是不升反降的,也就是说,并不是分区数越多,吞吐量就越大
。因此我们在实际的选择分区过程中,要尽量的多测几组数据,找到一个合适的值,这也告诉我们,在实际生产者过程中,我们自己要去做好测试,而不是去想当然的得出结论。实践,是检验真理的唯一标准。
并且,一味的增加分区数并不能使我们的吞吐量得到提升,还会因为超过系统的默认值,引起kafka进程崩溃。本人在生产环境中,将kafka分区数设置的过大,曾导致在实时流环境中,kafka进程多次崩溃。迫不得已的修改系统参数。我们可以试着在一台普通的linux机器上创建包含10000个分区的主题,执行完成后通过jps
查看kafka进程是否还存在,一般情况下,会导致kafka进程崩溃,这个时候,我们可以打开kafka的日志服务文件,发现日志服务文件中出现大量的异常。
java.io.IOException: Too many open files
这是一种常见的linux系统错误,通常意味着文件描述符不足
。这一般发生在创建线程,创建socket,打开文件的场景下,在linux的系统的默认设置下,它只有1024。
我们可以通过ulimit -n
命令查看,当然,我们也可以查看kafka的文件描述符:
当我们kafka进程崩溃后,这里的文件描述符将是0,表明它已经达到了上限。当然,对于大数据集群来说,文件描述符太小也不太合适,我们可以适当增加这个参数的值。但是,我们并不能无限制的去增加kafka的分区数,这是没有必要的。我们只需要通过压测的方式寻找最适合自己kafka的分区数就OK了。
并且,kafka的分区数还会影响系统的可用性。
我们知道,kafka通过多副本机制来实现集群的高可用和高可靠性,每个分区都会有一至多个副本,每个副本存在于不同的broker节点,并且只有leader副本对外提供服务,在kafka集群内部,所有的副本都采用自动化的方式进行管理,并确保所有副本中的数据都能保持一定程度的同步。当broker发生故障时,leader副本所属宿主的broker节点上的所有分区都将暂时处于不可用的状态,此时,kafka会自动在其他follwer副本中选举出新的leader用于接收客户端的请求。整个过程由kafka控制器负责,分区在进行leader角色切换的过程中会变得不可用,对于单个分区来说,它是非常短暂的,但是如果集群中的某个broker节点宕机,那么就会有大量的分区需要进行leader角色切换,这个切换的过程中会消耗一笔可观的时间。
分区数越多,也会让kafka的正常启动和关闭的耗时变得越长,与此同时,主题的分区数越多,不仅会增加日志清理的耗时,而且在被删除的过程中也会耗费更多的时间,对旧版的kafka而言,分区数越多,也会增加他们的开销,不过这个问题在新版的生产者和消费者的客户端已经得到解决了。
如果我们的kafka集群数量比较少的话(小几十台),假设我们有3台broker节点,我们可以设定分区数为3,6,9。当然,最好的办法还是结合我们的压测去判断,尽量选择合适的kafka分区数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。