使用kafka如何选择分区数及kafka性能测试

 更新时间:2021年08月09日 10:50:39   作者:引领时尚S  
这篇文章主要介绍了使用kafka如何选择分区数及kafka性能测试,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

kafka选择分区数及kafka性能测试

1、简言

​ 如何选择合适的分区,这是我们经常面临的问题,不过针对这个问题,在网上并没有搜到固定的答案。因此,今天在这里主要通过性能测试的工具来告诉如何选择相对应的kafka分区。

2、性能测试工具

​ 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分区数据,来保证我们集群的稳定运行。

当然,如果想要测试其他参数,可以使用下图的方式,同理我们的生产者压测也可以通过此方式知道每个参数的含义

3、分区数决定吞吐量?

​ 分区是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的文件描述符:

image-20190320202019338

当我们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分区数。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • spring实现动态切换、添加数据源及源码分析

    spring实现动态切换、添加数据源及源码分析

    这篇文章主要给大家介绍了关于spring实现动态切换、添加数据源及源码分析的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09
  • Java中的字符流FileReader与FileWriter详解

    Java中的字符流FileReader与FileWriter详解

    这篇文章主要介绍了Java中的字符流FileReader与FileWriter详解,在Java中,使用Unicode约定存储字符,字符流自动允许我们逐字符读/写数据,有助于执行16位Unicode的输入和输出,它是以reader和writer结尾的,需要的朋友可以参考下
    2023-10-10
  • Java棋类游戏实践之单机版五子棋

    Java棋类游戏实践之单机版五子棋

    这篇文章主要为大家详细介绍了Java棋类游戏中的五子棋实现方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • SpringBoot静态资源与首页配置实现原理深入分析

    SpringBoot静态资源与首页配置实现原理深入分析

    最近在做SpringBoot项目的时候遇到了“白页”问题,通过查资料对SpringBoot访问静态资源做了总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-10-10
  • SpringBoot实现数据预热的方式小结

    SpringBoot实现数据预热的方式小结

    这里用到的数据预热,就是在项目启动时将一些数据量较大的数据加载到缓存中(笔者这里用的Redis),那么在项目启动有哪些方式可以实现数据预热呢,本文就来给大家讲讲几种实现数据预热的方式,需要的朋友可以参考下
    2023-09-09
  • Java中的ArrayList.trimToSize()方法详解

    Java中的ArrayList.trimToSize()方法详解

    这篇文章主要介绍了Java中的ArrayList.trimToSize()方法详解,前几天看了Java ArrayList,没有明白trimToSize()这个方法是什么意思,所以看了一下源码并且debug一下自己的一个例子,明白了其中的含义,需要的朋友可以参考下
    2023-11-11
  • Java集合类之TreeSet的用法详解

    Java集合类之TreeSet的用法详解

    这篇文章主要为大家详细介绍了Java集合类中TreeSet的用法,文中的示例代码讲解详细,对我们学习Java有一定的帮助,感兴趣的可以了解一下
    2022-08-08
  • Java并发系列之AbstractQueuedSynchronizer源码分析(概要分析)

    Java并发系列之AbstractQueuedSynchronizer源码分析(概要分析)

    这篇文章主要为大家详细介绍了Java并发系列之AbstractQueuedSynchronizer源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-02-02
  • SpringBoot测试时卡在Resolving Maven dependencies的问题

    SpringBoot测试时卡在Resolving Maven dependencies的问题

    这篇文章主要介绍了SpringBoot测试时卡在Resolving Maven dependencies的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • Java 8 Time Api 使用方法技巧

    Java 8 Time Api 使用方法技巧

    这篇文章主要介绍了Java 8 Time Api 使用方法技巧,Java 8为Date和Time引入了新的API,以解决旧java.util.Date和java.util.Calendar的缺点,更多相关内容需要的小伙伴可以参考一下
    2022-05-05

最新评论