摘要:Kafka是一个支持分区的(Partition)、多副本的(Replica)、基于Zookeeper协调的分布式消息系统,它最大的特性就是能够实时处理大量数据,满足日志收集、消息系统、用户活动跟踪、流式处理等各种应用场景。Kafka作为时下最流行的开源消息中间件,目前正被广泛的应用于银行业系统间的消息传输。本次采用Kafka自带工具进行性能压测实验,获取多种参数条件下的Kafka吞吐率,为Kafka在银行业软件中的应用提供参考依据。
一 Kafka原理简介
为便于大家理解本次测试实验内容,包括各类参数如Partition、Replica等概念的涵义,本节首先简要介绍Kafka的基本原理。以下所有Kafka相关知识均学习自Kafka中文官网。
1.1 Kafka平台
Apache Kafka是一个分布式流处理平台,如图1所示。流处理平台有以下三种特性:
1)发布和订阅流式的记录,这一方面与消息队列或者企业消息系统类似。
2)储存流式的记录,并且有较好的容错性。
3)可以在流式记录产生时就进行处理。
Kafka使用4类核心的API提供消息发布订阅服务和流处理服务,包括The Producer API、The Consumer API、The Streams API、The Connector API。本次测试工具使用The Producer API、The Consumer API。

图1:Kafka介绍图
1.2 Topic、Partition、Replica概念
Topic主题:每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic,Kafka中的Topics总是多订阅者模式。对于每一个Topic, Kafka集群都会维持分区日志Partition,如图2所示。

图2:Kafka分区日志图
Partition分区:分区是物理上的概念,每个Topic包含一个或多个日志的分区Partition,Partition均匀分布在Kafka集群的服务器上。每个服务器在处理数据和请求时,共享这些分区。每一个分区都会在已配置的服务器上进行备份Replica,确保容错性。
Replica副本:Kafka 允许 Topic 的 Partition 拥有若干副本,每个分区Partition都有一个 leader 和零或多个followers节点 ,副本数是leader和follows节点数总和。所有的读写操作都由 leader处理,所有的followers 节点都同步 leader 节点的日志,日志中的消息和偏移量都和leader 中的一致。当集群中的节点出现故障时,能自动进行故障转移,保证数据的可用性。
ISR(In-SyncReplica)高可用机制:Kafka 动态维护同步状态的备份集合ISR,在这个集合中的节点(包含leader和部分Replica)都是和leader 保持高度一致的, ISR 集合发生变化会在 ZooKeeper 注册,当leader宕机了,ISR中的follower会自动选举成为新的 leader,从而实现高可用。
二 Kafka吞吐率测试方法与工具介绍
2.1 测试方法
Kafka系统吞吐率受其各种参数影响,如分区Partition数量、副本Replica数量、单台broker中背景Partition数量、消息大小、消息发送/接收实例数等参数。本次使用Kafka自带测试工具Kafka-producer-perf-test.sh和Kafka-consumer-perf-test.sh向Kafka消息中间件加压,测试各种不同参数条件下Kafka系统的吞吐率。测试示意图如图3所示。

图3:测试方法图
2.2 测试工具
1)Kafka-producer-perf-test.sh发送参数如表1所示
表1:发送工具参数说明表
--topic | 发送的topic名称 |
--num-records | 发送的消息总量 |
--throughput | 每秒发送的消息量 |
--producer.config | 发送的配置文件 |
--record-size | 发送的消息字节数 |
2)Kafka-consumer-perf-test.sh接收参数如表2所示
表2:接收工具参数说明表
--topic | 发送的topic名称 |
--messages | 接收的消息总量 |
--producer.config | 发送的配置文件 |
--threads | consumer线程数 |
bootstrap.Servers | consumer.properties中配置Kafka集群的IP及端口 |
group.id | consumer.properties中配置消费者组 |
三 Kafka吞吐率测试分析
本次测试Kafka机器使用3台28C256G Kafka物理机(操作系统均为Oraclelinux7.4),Kafka发送和接收测试脚本部署在另外4台28C256G物理机(操作系统均为redhatlinux6.7),每次测试均向一个topic发送消息或从一个topic接收消息,分析各类参数对消息吞吐率的影响如下。
3.1 Partition分区数设置为1、4、8、16
1)发送测试
表3:分区参数对发送吞吐率影响表
Partition | Replica | 发送速率TPS(笔/秒) | 发送吞吐率(MB/秒) | 共同条件 |
1 | 3 | 130215 | 127.16 | 12个发送进程,消息大小均为1k |
4 | 3 | 201082 | 196.44 | |
8 | 3 | 223257 | 218.02 | |
16 | 3 | 329573 | 321.84 |
如表3所示,在发送进程数量不是瓶颈的条件下,测试发现分区数量越多,消息发送吞吐率越高,分布式提高了消息发送的吞吐率。
2)接收测试
表4:分区参数对接收吞吐率影响表
Partition | Replica | 接收速率TPS(笔/秒) | 接收吞吐率(MB/秒) | 共同条件 |
1 | 3 | 1116617.78 | 1090.43 | 4个consumer进程,消息大小均为1k |
4 | 3 | 2840931.73 | 2774.32 | |
8 | 3 | 2950735.33 | 2881.57 | |
16 | 3 | 2948347 | 2879.23 |
如表4所示,消息接收性能优于消息发送性能,消息接收的吞吐率随着分区数量增多而上升。当分区数从1个增加到4个时,接收吞吐率从1090MB/s提升到2774MB/s,但是当分区数从4个增加到16个时,因为受到Kafka物理机网络带宽的限制(单台机器网络带宽限制为1000MB/s,三台物理机的带宽上限约为3000MB/s),接收吞吐率无变化。本次测试中分区数对吞吐率的影响收到了网络带宽的影响。
3.2 Replica副本数设置为1、2、3
1)发送测试
表5:副本参数对发送吞吐率影响表
Partition | Replica | 发送速率TPS(笔/秒) | 发送吞吐率(MB/秒) | 共同条件 |
8 | 1 | 776177 | 757.98 | 12个发送进程,消息大小均为1k |
8 | 2 | 269315 | 262.99 | |
8 | 3 | 211336 | 206.39 |
如表5所示,在发送进程数量不是瓶颈的条件下,相同分区数情况下,副本的数量越多,消息发送的吞吐率越低。因为副本的消息同步时间会影响消息发送的效率,只有当一个消息被所有的副本节点加入到日志中时,消息方能发送成功。虽然副本数量会影响消息吞吐率,但是为保证集群高可用性,当集群中的节点出现故障时,所有副本的数据一致,能自动进行故障转移,保证数据的可用性。所以副本数量的设置需要应用系统根据实际情况决定在高可用和性能之间如何取舍。
2)接收测试
表6:副本参数对接收吞吐率影响表
Partition | Replica | 接收速率TPS(笔/秒) | 接收吞吐率(MB/秒) | 共同条件 |
8 | 1 | 2971773.85 | 2902.1 | 4个consumer进程,消息大小均为1k |
8 | 2 | 2966907.03 | 2897.35 | |
8 | 3 | 2957996.06 | 2888.65 |
如表6所示,接收测试受到Kafka物理机网络带宽的限制,不同副本情况下消息接收吞吐率接近3000MB/s,无法说明副本数对消息接收吞吐率的影响。
3.3 消息大小设置为500byte、1k、4k、10k
1)发送测试
表7:消息大小对发送吞吐率影响表
消息大小 | 总TPS(笔/秒) | 发送吞吐率(MB/秒) | 共同条件 |
500 bytes | 448533 | 213.83 | 12个发送进程,使用topic均为8个Partition,3个副本。 |
1k | 213403 | 208.41 | |
4k | 51207 | 200.01 | |
10k | 21616 | 211.1 |
如表7所示,在发送进程数量不是瓶颈的条件下,消息大小在500byte~10k范围内,并未对消息吞吐率造成影响,故判断消息大小并非影响消息发送吞吐率的关键参数。
2)接收测试
表8:消息大小对接收吞吐率影响表
消息大小 | 总TPS(笔/秒) | 接收吞吐率(MB/秒) | 共同条件 |
500 bytes | 5660809.98 | 2966.27 | 4个consumer进程,使用topic均为8个Partition,3个副本。 |
1k | 2976664.12 | 2906.87 | |
4k | 734620.53 | 2869.59 | |
10k | 296890.3 | 2899.3 |
如表8所示,接收测试受到Kafka物理机网络带宽的限制,不同副本情况下消息接收吞吐率接近3000MB/s,无法说明消息大小对消息接收吞吐率的影响。
3.4发送/接收实例数分别为1、4、8
1)发送测试
表9:实例数对发送吞吐率影响表
生产者实例数 | 总TPS(笔/秒) | 发送吞吐率(MB/秒) | 共同条件 |
1 | 6366 | 62.17 | 使用topic均为8个Partition,3个副本,消息大小为10k。
|
4 | 17498 | 170.88 | |
8 | 19294 | 188.39 | |
12 | 21616 | 211.1 |
如表9所示,随着消息发送者实例数的增加,消息发送的吞吐率增加,但是并非线性增长,在Partition数量为8个时,4个消息发送实例下发送的性能已经达到170MB/s,再增加消息发送实例数,发送性能提升不明显,造成资源的浪费。故消息发送实例数的设置需要根据Partition数量设置,并非越多越好。
2)接收测试
表10:实例数对接收吞吐率影响表
消费者实例数 | 总TPS(笔/秒) | 接收吞吐率(MB/秒) | 共同条件 |
1 | 813133.88 | 794.07 | 使用topic均为8个Partition,3个副本,消息大小为1k |
4 | 3076083.01 | 3003.97 | |
8 | 3414678.2 | 3304.62 |
如表10所示,消息接收的吞吐率随着实例数增多而上升。当实例数从1个增加到4个时,接收吞吐率从794MB/s提升到3003MB/s,而当实例数从4个增加到8个时,因为受到Kafka物理网络带宽的限制,接收吞吐率无变化。本次测试中消费者实例数对吞吐率的影响收到了网络带宽的影响。
3.5单台broker的Partition总数
1)发送测试
表11:背景Partition数对发送吞吐率影响表
单台broker背景 Partition数 | 测试partiton数 | 总TPS(笔/秒) | 总吞吐率(MB/秒) | 共同条件 |
500 | 8 | 182392 | 178.11 | 12个发送进程,消息大小均为1k,测试Partition数为8,副本数为3,背景Partition压力为500笔/s |
2000 | 8 | 147853 | 144.37 | |
4000 | 8 | 40548 | 39.6 |
如表11所示,单台Kafka broker上的Partition越多,消息发送的吞吐率降低明显。背景Partition数量以及相应副本的同步消耗了Kafka的资源,故导致消息发送吞吐率降低明显。
2)接收测试
表12:背景Partition数对接收吞吐率影响表
单台broker背景 Partition数 | 测试partiton数 | 总TPS(笔/秒) | 总吞吐率(MB/秒) | 共同条件 |
500 | 8 | 2686519.673 | 2623.547 | 4个consumer进程,消息大小均为1k,测试Partition数为8,副本数为3,背景Partition压力为500笔/s |
2000 | 8 | 2610031.878 | 2548.858 | |
5000 | 8 | 2619654.983 | 2558.255 |
如表12所示,当单台Kafkabroker上的Partition达到500~5000个时,消息接收吞吐率与无背景Partition情况下相比,吞吐率降低了约300MB/s左右(背景Partition吞吐率约为0.5MB/s,可忽略不计),可见Kafkabroker上的背景Partition对Kafka资源有一定的消耗。同时不同Partition背景数量对消息接收吞吐率无影响。
本次实验了Kafka Partition、Replica、消息大小、发送/接收实例数、背景Partition数量参数对消息吞吐率的影响,并提供了具体的吞吐率数据,以期对后续Kafka在本行的应用提供参考依据。




