本文内容来自于Jay Kreps于2014年在LinkedIn发布的一篇文章,英文原文见Benchmarking Apache Kafka: 2 Million Writes Per Second (On Three Cheap Machines)。Jay Kreps是Kafka的早期作者之一,也是提供商业版本Kafka的Confluent公司联合创始人兼CEO。尽管该文发布于2014年4月份,使用的版本是0.8.1,但其结果在五年后的今天依然具有很大的参考价值。因为尽管Kafka如今已经发展到2.3版本,但其核心架构在这5年间并未发生过大的调整,新的版本改动更多的都是在完善和丰富其Stream特性。

作者使用了6台机器,每台机器配置如下:

  • Intel Xeon 2.5 GHz processor with 6cores
  • Six 7200 RPM SATA drives
  • 32GB of RAM
  • 1Gb Ethernet(即千兆网卡)

其中每台机器上面的6块硬盘没有做任何RAID,直接挂载使用,6块硬盘的线性写入能力约为822MB/秒。测试中,使用3台机器部署Kafka,另外3台作为压力机以及部署Zookeeper。整个测试过程中,没有对Kafka进行任何调优。下面介绍测试过程。

测试生产者性能

写入性能测试共进行了4组,不同测试变化的是副本确认机制和写入线程数,其它参数配置均相同。因为有6块硬盘,所以创建了一个包含6个分区的Topic,每个磁盘分布一个分区。写入的消息大小都是100字节,共写入5千万条消息。另外,写的过程中没有任何读取操作。

场景1:1个写线程,无副本复制

测试场景:1个producer线程,数据只写1份(即只有leader replica,无follower replica)

测试结果:821,557 records/秒 或 78.3 MB/秒

结果分析:此时判断应该是网卡基本饱和。因为上面统计的测试结果只计算了原始数据(即每条100字节),但实际发送的时候,每条消息还会附加约22字节的元数据信息,每个请求还会附加topic、partition等信息,所以网络上的数据肯定是大于上述结果的。

场景2:1个写线程,3 replica,异步复制

测试场景:1个producer线程,3份数据(1个leader replica,2个follower replica),副本复制采用异步方式,即写入请求在leader replica将数据写入本地日志之后就返回了,无需等待2个follower replica写。

测试结果:786,980 records/秒 或 75.1MB/秒

结果分析:因为是follower是异步复制的,所以和场景1没有follower时的性能相近。

场景3:1个写线程,3 replica,同步复制

测试场景:和场景2类似,单复制过程采用同步方式,即只有当leader和2个follower都将数据持久化之后,写请求才会返回。

测试结果:421,823 records/秒 或 40.2MB/秒

结果分析:同步复制的延迟导致TPS下降了很多。

场景4:3个写线程,3 replica,异步复制

测试场景:和场景2类似,但使用3个producer线程。为了避免网络瓶颈,3个线程分布在3台机器上。

测试结果:2,024,032 records/秒 或 193MB/秒

结果分析:性能基本上是随着写线程数近线性增长的的。

测试消费者性能

测试消费者性能时,使用的是前面测试生产者产生的数据,即5千万条消息,每个消息100字节,3 replica。测试期间,没有任何生产者。另外,对于Kafka的消费者,需要明确两点:

  1. 在kafka中,只有leader replica对外提供服务,follower replica只是作为冗余,并不对外提供服务。所以消费者的性能与是否有follower replica及其个数没有关系。
  2. 一个消息只有follower replica完成复制后才对消费者可见,这与生产者是同步确认还是异步确认没有关系。

场景5:1个消费者

测试场景:1个消费者线程

测试结果:940,521 records/秒 或 89.7MB/秒

结果分析:读取速度基本达到网卡瓶颈了。

场景6:3个消费者

测试场景:3个消费者线程,分布在3台机器上,同时消费同一个topic

测试结果:2,615,968 records/秒 或 249.5 MB/秒

结果分析:基本上是接近线性增长的

生产者消费者一起

前面测的都是单独的生产者或者消费者的场景,实际中往往是一边生产一边消费,所以作者再测试了一下这种场景。

场景7:生产者消费者协调

测试场景:1个生产者线程,1个消费者线程,6个分区,3个replica,异步复制

测试结果:795,064 records/秒 或 75.8MB/秒(消费者的性能)

结果分析:上面的测试结果是消费者的性能,对比场景2可知该性能其实就是生产者的性能上限。所以,对于Kafka模型而言,消费者和生产者基本是互不影响的。而且二者一起的时候,往往还能更好的利用Page Cache。

通过这一系列的测试可以看到Kafka的性能是非常高的,这得益于它精良的设计。测试过程中使用到的脚本及配置见这里