1 整体环境说明
1.1 硬件环境
1、 磁盘:SATA磁盘2块,磁盘阵列为RAID1
2、 CPU****:2个4核CPU。具体参数:Intel(R) Xeon(R) CPU E5405 @ 2.00GHz
3、 内存:8G(8*1G)
4、 网卡:1000Mb/s
1.2 软件环境
1、 kafka版本:kafka_2.11-2.11.0.0
2、 kafka集群数量:3
3、 zookeeper版本:zookeeper-3.4.12
4、 zookeeper集群数量:3
5、 zookeeper使用单独的集群,不使用kafka自带zookeeper
2 服务器自身瓶颈测试
由于kafka是的吞吐量特别大,所以先考虑集群服务器的自身瓶颈。如磁盘IO瓶颈。由于kafka做的集群所以需要相互传输数据,所以要考虑网卡瓶颈。
2.1 测试磁盘IO瓶颈
2.1.1 磁盘IO写入瓶颈
1、使用以下命令测试磁盘IO的写入瓶颈
# sync;time -p bash -c "(dd if=/dev/zero of=test.dd bs=1M count=20000)"
解释:在当前目录下创建一个test.dd的文件,写入20000个1M的数据。
2、使用iostat命令监测磁盘io情况。
使用命令
# iostat -x 1
解释:扩展查看io性能,每1秒钟刷新一次。
注意:如果没有iostat。请执行yum install sysstat –y命令进行安装iostat命令
3、结果展示
(1)磁盘写入IO结果
# sync;time -p bash -c "(dd if=/dev/zero of=test.dd bs=1M count=20000)"
记录了20000+0 的读入
记录了20000+0 的写出
20971520000字节(21 GB)已复制,221.314 秒,94.8 MB/秒
real 221.67
user 0.01
sys 21.20
磁盘写入IO为94.8 MB/秒
(2)iostat命令结果
关注wkB/s和%util两个参数
wkB/s:每秒写入设备的数据量(单位:KB)
%util:消耗在I/O请求中的CPU时间百分比(设备带宽利用率)。如果该值接近100%说明设备出现了瓶颈。
2.1.2 磁盘IO读取瓶颈
1、使用以下命令测试磁盘IO的读取瓶颈
# hdparm -tT --direct /dev/sda
解释:hdparm命令是显示与设定硬盘的参数。-t参数为评估硬盘的读取效率(不经过磁盘cache)。-T参数为评估硬盘的读取效率(经过磁盘cache)
注意:如果没有hdparm命令可以直接yum –y install hdparm即可
2、使用iostat命令监测磁盘io情况。
使用命令
# iostat -x 1
3、结果展示
# hdparm -tT --direct /dev/sda
/dev/sda:
Timing O_DIRECT cached reads: 326 MB in 2.00 seconds = 162.83 MB/sec
Timing O_DIRECT disk reads: 322 MB in 3.01 seconds = 106.88 MB/sec
解释:经过磁盘cache的磁盘读取为162.83 MB/sec
未经过磁盘cache的磁盘读取为106.88 MB/sec
2.2 磁盘性能总结
以我的服务器SATA磁盘2块,磁盘阵列为RAID1的配置。磁盘写入数据瓶颈为94.8 MB/秒。读取数据瓶颈经过磁盘cache的磁盘读取为162.83 MB/秒,未经过磁盘cache的磁盘读取为106.88 MB/秒。如果kafka集群的写入速度和读取数据的速度达到这个数值,或者iostat的输出结果%util的值接近100%。说明磁盘已经到达一个瓶颈。会影响压测数据的准确性。
2.3 网卡性能总结
我的网卡是千兆网卡,传输数据可以达到1000Mb/s,由于我们使用的单位都为MB/s。所以把Mb换算成MB。1000Mb/s=125MB/s。也就是说传输熟读到达125MB/s的时候是网卡的瓶颈。会影响压测数据的准确性。
3 Kafka测试前期准备
3.1 影响测试结果配置分析
Kafka的性能测试主要测试kafka的吞吐量,kafka吞性能为生产者在向kafka传入消息时的写入量,kafka的吐性能为消费者在kafka集群中消费的能力,也就是读取量。
3.1.1 Borker相关
Kafka的borker是kafka集群的缓存代理,消息中间件处理结点,一个Kafka节点就是一个broker,多个broker可以组成一个Kafka集群。下面是相关broker的参数分析。
1、num.partiton
topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列。
Partition的数量选取也会直接影响到Kafka集群的吞吐性能。例如我们接口如果开了多个线程去消费kafka的数据,当Partition数量相对于流入流出的数据量显得较少,或由于业务逻辑和Partition数量没有匹配好造成个别Partition读写数据量大,大量的读写请求集中落在一台或几台机器上时就会很影响效率。
2、Default.replication.factor
Replication参数为kafka集群副本数。这个参数决定了kafka的高可用性。也决定了kafka的吞吐量。此数据运算和broker个数和broker上的分区数量都有关系。正常broker为3replication设置为1最好。因为3个节点的集群可以宕机一台可以继续工作,而3个replication可以保证宕机两个节点正常工作。所以多replication会造成资源浪费。如果数据不需要持久化和数据不重要并且写入量特别大的话,可以考虑replication为0。
3、num.network.thread
用于接收并处理网络请求的线程数,默认为3。其内部实现是采用Selector模型。启动一个线程作为Acceptor来负责建立连接,再配合启动num.network.threads个线程来轮流负责从Sockets里读取请求,一般无需改动,除非上下游并发请求量过大。
4、写入数据每条大小
'{"indexdiy":"catalina","input_type":"log","message":"[2018-09-26 12:30:13,030] [org.apache.tomcat.util.net.NioSelectorPool] [INFO] [Using a shared selector for servlet write/read]","offset":17600578,"project_tag":"catalina","source":"/opt/tomcat7/logs/catalina.out","type":"log"}'
以上面一条日志为例。此条日志大小为283B。所以我们测试基准为200B和500B。
3.1.2 Consumer相关
Consumer为kafka的消费者,同一个topic消费者越多越快,但是需要注意的是,消费者的数量不能超过topic的分区数量,因为每个topic的每个分区只能被一个消费者消费,多出来的消费者会无信息可消费。导致资源浪费。
3.2 测试命令详解
1、创建topic命令
# ./kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test -7
--replication-factor:指定副本个数
--partitions:指定分区个数
--topic:指定topic名
2、查看topic命令
# ./kafka-topics.sh --zookeeper 10.10.4.11:2181 --list
3、查看指定topic的详细内容
# ./kafka-topics.sh --zookeeper 10.10.4.11:2181 --topic test_property --describe
5、 写入数据
# ./kafka-producer-perf-test.sh --num-records 10000000 --topic test-ref-9 --record-size 500 --throughput 100000 --producer-props bootstrap.servers=10.10.4.11:9092,10.10.4.12:9092,10.10.4.13:9092
--num-records:记录的条数
--topic:指定topic的名字
--record-size:一条记录大小。
--throughput:吞吐数量
--producer-props bootstrap.servers=IP:9092,IP:9092,IP:9092:指定kafka集群
注意:-- throughput参数为写入数量,如果结果接近此数量,建议*10再测试一次。因为和此结果相近说明kafka没有到达瓶颈。
6、消费数据
# ./kafka-consumer-perf-test.sh --messages 10000000 --threads 3 --zookeeper localhost:2181 --num-fetch-threads 3 --topic test-ref-8
--messages:指定消费条目数
--threads:指定线程数
--num-fetch-threads 3:指定消费人数
注意:执行以上命令在kafka****家目录下的/bin****下执行命令
4 Kafka写入性能测试
在测试kafka写入性能测试的时候一边检测系统的cpu使用情况、内存使用情况和磁盘IO情况。
4.1 测试kafka的partition参数
4.1.1 创建不同partition的topic并写入数据1000万条数据。
1、 创建一个副本,partition分别为1、3、6、12的topic分别为test-0、test-1、test-2、test-3
2、 向topic内写入1000万条500B的数据,一次写入100万条,replication为1。并且开启另一个窗口使用iostat命令实时监控磁盘IO情况。
4.1.2 测试结果
1、写入数据如下表
3、 磁盘IO情况
由于磁盘IO瓶颈在94.8 MB/秒得出的数据只有partition为1的情况下在60MB/秒。所以大多数情况下%util处于一个100%的状态。在partition为1的情况下是隔两秒会出现%util值为100%。
4.2 kafka的partition参数总结
由于压力测试没有到达kafka的瓶颈,而是到达了服务器的瓶颈。所以以上数据仅供参考。如想测试更准确的数据。需要性能更好的磁盘来做测试。
在其他数据相同,而partition不同的时候。结论是partition越多写入速度越快。但是partition数量越多会照成kafka集群可用性越差。所以建议,在实际生产环境。有多少个broker,partition数就为多少。这样可以保证kafka集群的高可用性。可以保证n-1/2个节点宕机而不影响kafka集群使用。
4.3 测试Kafka的replication参数
4.3.1 创建不同replication的topic并写入数据1000万条数据。
1、创建一个副本,replication分别为2和3的topic为test-4、test-5。和之前创建的test-1。一起做测试
2、向topic内写入1000万条500B的数据,一次写入100万条,partition为3(因为我的broker是3个)。并且开启另一个窗口使用iostat命令实时监控磁盘IO情况。
4.3.2 测试结果
1、写入数据如下表
2、磁盘IO情况
由于磁盘IO瓶颈在94.8 MB/秒得出的数据只有replication为3的情况下在70MB/秒。所以大多数情况下%util处于一个100%的状态。在replication为3的情况下也是一直%util值为100%。
4.4 kafka的replication参数总结
由于压力测试没有到达kafka的瓶颈,而是到达了服务器的瓶颈。所以以上数据仅供参考。如想测试更准确的数据。需要性能更好的磁盘来做测试。
在其他数据相同,而replication不同的时候。结论是replication越少写入速度越快。但是replication数量越少会照成kafka集群可用性越差。所以建议,在实际生产环境。Kafka集群broker为3的时候replication为1,可以保证一台节点宕机集群可用。其他架构需继续深入研究。
4.5 测试Kafka的network.thread参数
1、 修改配置文件network.thread的参数为1,重启kafka进行对test-1进行写入测试。
2、 和之前test-1的数据进行对比。
4.5.1 测试结果
1、写入数据如下
2、磁盘IO情况
磁盘已经到达瓶颈。
4.6 Kafka的network.thread参数总结
从结果可看出kafka的network.thread参数越多写入速度越快。但是增加的非常不明显。除非写入速度要求极高的情况,或者机器性能足够好。其他情况建议使用默认值3即可。
4.7 测试kafka的单条数据大小参数
1、 修改命令--record-size参数。
2、 同往test-1里写入进行测试
4.7.1 测试结果
1、写入数据如下
2、磁盘IO情况
磁盘已经到达瓶颈。
4.8 Kafka的单条数据大小参数总结
从结果显示证明如果写入kafka的数据量单条越小,传输速度越快。正常我们的日志大约在300B每条,最大为500B每条。所以我们按照最大的数据量进行传输来测试写入量。
5 Kafka写入数据测试整体总结
在kafka写入数据的时候,主要参数在于partition的数量、replication的数量及单条数据的大小。对于线程数对写入速度并不是特别影响。在测试的时候观察cpu使用情况和内存使用情况。Kafka在有写入的时候对于本身的内存要求不大,jvm设置为1G就可以,但是kafka机制是kafka先写入系统页缓存内,所以需要的内存比较大。不建议和使用内存较大的应用部署在一台机器上,如elasticsearch。如果服务器内存较大,建议kafka使用4G左右jvm。Kafka对cpu要求不是特别大。一般两核以上就可以。
6 Kafka读取性能测试
在测试kafka读取性能测试的时候一边检测系统的cpu使用情况、内存使用情况和磁盘IO情况。
注意事项:写入数据后等一段时间再进行测试,因为可能有些数据还在内存中,所以看不出磁盘IO的瓶颈。
6.1 测试kafka的partition参数
1、由于之前已经写入1000万数据,可以直接在test-0、test-1、test-2、test-3的topic 并且Consumer为3、线程为3。直接读取这些数据进行测试。
6.1.1 测试结果
1、读取数据如下表
2、磁盘IO情况
磁盘IO有时会到达瓶颈,但是次数不多。
6.2 Kafka的partition参数总结
压测结果证明partition越多速度越快,实际情况我们建议和之前一样。有多少个broker,partition数就为多少。这样可以保证kafka集群的高可用性。可以保证n-1/2个节点宕机而不影响kafka集群使用。详细情况kafka写入测试的partition总结。
6.3 测试Kafka的consumer参数
以test1为测试topic。分别使用1、3、6个consumer来进行读取测试。
6.3.1 测试结果
1、写入数据如下表
2、磁盘IO情况
磁盘IO有时会到达瓶颈,但是次数不多。
3、 使用软件KafkaOffsetMonitor监控不同consumer的滞留情况lag为滞留信息条目数
(1)一个consumer三个partition
(2)三个consumer三个partition
(3)三个consumer六个partition
6.4 kafka的consumer参数总结
从测试结果可以看出,consumer这个参数不是越多越好,而是和topic的partition相同时性能最优,如果consumer大于partition的时候,测试开始会报错,内容大意为,有xx个consumer是没有分区可以消费的。这个参数可以根据项目本身去定义。但是不要超过topic的partition数目。但是consumer少会有消息滞留现象。
6.5 测试Kafka的线程参数
通过test-1 topic进行测试。
6.5.1 测试结果
1、 写入数据如下表
2、 磁盘IO
6.6 kafka的线程参数总结
从测试结果来看线程数并不影响kafka的写入速度。
7 Kafka读取性能总结
Kafka写入性能主要在于partition参数和consumer参数。Partition参数和的具体值可以直接参考写入性能总结,这里不再赘述。Consumer的性能测试来看,只要不多于partition的数量都是可以的。如果broker的数量比较多,建议多设置几个。
Kafka读取对于replication无关,因为replication不参与读取,只做容灾备份的。对线程数也没那么大的关系。
读取数据对cpu负载不是特别高,2核以上够用,如果是实时读取数据,对磁盘来说性能要求并不高,因为短时间内,一些数据都是在内存里可以直接取到的。
8 Kafka整体性能总结
对于ELK集群来说,整体性能还是比较好的,一般影响测试结果都是磁盘的瓶颈造成的。对于磁盘来说用SATA磁盘就可以,因为kafka的写入读取机制都是顺序写入、读取的。SATA顺序读写速度大约在53MB/s和SSD的顺序读取都是差不多的。如果做RAID建议做RAID5。
Kafka对于CPU和内存要求不是特别大,一般CPU建议在8核以上,内存建议在8G以上。如果服务器性能好kafka的jvm建议设置4G。
Kafka在我的测试环境下,broker为3的集群情况下。Replication参数为1,partition参数为3,线程数为3,consumer数为3,输入读取的文件大小为500B。整体kafka的写入速度为242665条/秒,传输大小为115.71 MB/秒。读取速度为241390条/秒,传输大小为115MB/秒。
但是以上数据几乎都是遇到了磁盘IO的瓶颈,数据不是特别准确,希望可以有更好的环境,对kafka进行更全面的测试。
最后贴上整体数据
生产