Pafka 0.2.0 介绍:基于分级存储架构优化,提升 Kafka 系统性能
来源:原创 如需转载,请注明来自 memark.io 技术社区
1. Pafka 0.2.0 Release Notes
Pafka 0.2.0 已于近期发布(https://github.com/4paradigm/pafka)。Pafka 基于流行的开源消息队列系统 Apache Kafka 开发,引入基于分级存储架构的优化,来提升消息队列系统的整体性能。本次版本相比较于上一个版本 Pafka 0.1.1,主要引入的新特性如下:
- 基于分级存储架构(tiered storage architecture)优化,使用高性能的持久内存 PMem 作为 Pafka 的第一级存储,较低性能 HDD 或者 SSD 作为第二级存储
- 引入自动化的后台数据迁移策略,基于分级存储架构实现容量和性能的平衡
- 使用 llpl (https://github.com/pmem/llpl) 的 libpmem 接口重写了部分 PMem 相关代码,进一步提升了 PMem 上的读写性能和稳定性
2. 分级存储架构和数据迁移策略
本次 Pafka 0.2.0 版本的更新最为重要的特性为在 Kafka 的架构基础上,引入了分级存储以及相应的迁移策略,以此在某些场景下以较低成本提升 Kafka 的性能,并能取得容量和性能的平衡性。如下图所示,随着持久内存 PMem 的引入,我们的存储体系已经在层级上变得更为丰富。数据中心普遍不再是使用 HDD 作为唯一的存储介质,SSD 以及高速 PMem 均可以作为存储介质。在此次 Pafka 0.2.0 版本中,我们为 Kafka 优化引入分级存储的能力,使用 PMem 作为第一级高速持久化存储,使用其他较慢速存储介质(SSD/HDD)作为第二级存储介质,来提升 Kafka 整体的吞吐,并且实现性能和容量的平衡。

基于分级存储策略,Pafka 0.2.0 引入了一个重要的新参数来控制数据迁移,称为迁移阈值(storage.migrate.threshold)。该参数可以理解为系统在平衡状态下,PMem 上存储的数据容量。Pafka 会尽量保持较新的数据存储在 PMem 上,而将较旧的数据迁移到速度较慢的二级存储上。其背后的基本逻辑是较新的数据更有可能会在近期被消费(当然实际场景较为复杂,并不一定完全适配)。在不同场景下,该值的设置具有不同的效果,以下在场景测试中将会详细解释。
如下图显示了整体系统基于两级存储的架构和流程图,包含了数据存储逻辑和后台的数据迁移策略。简单来说,数据写入会优先选择速度较高的 PMem,PMem 被写满以后才会写入低速设备。此外,Pafka 在后台运行着一个数据迁移机制。当 PMem 上存储的数据量大于 threshold 的时候,迁移机制就会启动把较老的数据从 PMem 迁移到 HDD;以此类推,当 PMem 上存储的数据量小于 threshold 的时候,较新的数据会从 HDD 迁移到 PMem。当然在某些场景下,数据迁移可能会引入额外的 overhead,因此迁移功能也作为功能开关可配置。

3. 测试脚本
我们提供了一个可以在多机运行多个Producer/Consumer客户端的脚本,以方便对Pafka进行压测。测试脚本位置:bin/bench.py
可以通过运行以下命令,来查看bench.py的可配置参数:
./bin/bench.py --help
测试环境
- 每台测试机器需要配置成”不需要密码“访问,即当前机器ssh测试机器,不需要输入密码,可以直接访问。
- Pafka的代码每台机器存在,且位于相同目录(可以使用NFS,不需要复制多份)
测试Producer的性能
命令示例如下:
bin/bench.py --threads 16 --hosts "node-1 node-2" --num_records 100000000 --type producer
以上命令,会在node-1、node-2两个节点,每个节点启动16个Producer进程(每一个Producer分别生成一个Topic),总共会生成100, 000, 000条records。
测试Consumer的性能
命令示例如下:
bin/bench.py --threads 16 --hosts "node-1 node-2" --num_records 100000000 --type consumer
4. 典型场景测试
硬件配置
Broker机器配置:
项目 | 配置 |
CPU | Intel(R) Xeon(R) Gold 6252 CPU (24 cores) * 2 |
PMem | 128 GB * 6 |
Network | 100 Gbps |
HDD | RAID-5,提供大约 500 MB/sec 的带宽性能 |
Client机器配置(2台)
项目 | 配置 |
CPU | Intel(R) Xeon(R) Gold 6132 CPU (14 cores) * 2 |
Network | 100 Gbps |
注意,服务器上一般会有两个 socket 用来插 PMem(即如上表 PMem 实际可以达到 128 GB x 12),此次测试中仅使用一个 socket。如果用户期望将两个 socket PMem 都可以用上,可以在服务器上起两个 brokers,或者使用 Linux 虚拟化磁盘管理工具 LVM (Logical Volume Manager),将两个 socket PMem 合并成一个再给 Pafka 使用。在后续版本中,我们将会在 Pafka 内部直接支持多个 socket PMem 的管理使用。
Pafka配置
下面列出一些和标准kafka配置(config/server.properties)有区别的配置:
# 100 Gbps IP
listeners=PLAINTEXT://172.29.100.24:9092
# 线程相关
num.network.threads=32
num.io.threads=16
# pmem相关配置
storage.pmem.path=/mnt/mem/pool/
storage.pmem.size=670000000000
storage.hdd.path=/mnt/hdd0/kafka/
storage.migrate.threshold=0.5
storage.migrate.threads=4
log.channel.type=mix
log.pmem.pool.ratio=0.99
log.preallocate=true
Producer配置
batch.size=163840
场景描述
Pafka 0.2.0 为 Kafka 在某些特定场景下的性能需求提供了低成本的弹性解决方案。用户不再需要额外配置高成本的物理机来扩充 Kafka 集群,而只需要配置持久内存,来达到相应的需求。此种方案在总成本、物理空间占用、功耗上等均具有显著的优势。在此我们主要测试两个优势场景:
- 场景一:突发性高流量场景。比如在线购物平台上,每隔一个小时会发放特定的优惠产品或者优惠券,那么在这部分短期的时间内(可能几分钟),预期会有突发性的高流量产生。传统的 Kafka 平台上,为了应付这种偶发性的高吞吐需求,需要额外配备物理机,但是在大部分情况下,这些物理机却是处于一个空闲的状态,因为高吞吐需求只是间隔性偶发的出现。这种情况下,基于 PMem 的分级存储策略可以使用高性能的 PMem 来为瞬间的高吞吐需求来提供保障。
- 场景二:稳定高吞吐需求场景。比如外卖平台或者在线音乐视频平台,可能需要在若干个小时内均保持比较平均的数据压力。在这种场景下,如果用户对于 Kafka 数据持久化的容量要求不是特别高(可以通过 log.retention 相关参数进行调整),可以在保持一定的持久化数据容量前提下(比如整体容量为 PMem 的两倍),通过 PMem 来提升整体的吞吐。
场景一测试结果:突发性高流量场景
在此场景下,我们模拟生产者会在大部分时间下以较低速率来产生数据,在一定的间隔以后,生产者会突然增大数据产生量。在此实验中,我们将高速率数据产生的间隔调整到差不多能满足使用 PMem 来承接高流量,同时消费者同步持续消费数据,来观察 Pafka 对于这种突发流量的支撑情况。相关关键参数设置和说明如下:
- storage.migrate.threshold = 0.5:此参数设置预留了一半的 PMem 空间用来处理高吞吐需求,适当调小这个参数会使得能够支撑的数据压力高峰吞吐更高、维持时间更长,但是过于小会影响到消费者的性能。因此大部分情况下,我们都建议使用默认的 0.5 作为取值。
- log.retention 相关参数:没有做特定限制,即默认不会自动清理 Kafka 日志文件,如果 PMem 存不下,会自动启用二级存储。

场景一:突发性高流量场景
如上图所示,我们考察了两个场景,区别为高速率数据产生时候的峰值。左图在最高 8 GB/sec 的吞吐下,我们测试时间内(约半个小时),可以容纳两个波峰,每个波峰可以支持的时间大约是 1 分钟左右。右图如果把吞吐峰值下降到 2.5 GB/sec,则在半个小时内可以支撑三个波峰,每个大约能持续时间 2 分钟左右。
总体来说,Pafka 能支撑的突发性高流量波峰持续时间和间隔的基本计算方式如下。
- 高吞吐可以持续的时间为预留的 PMem 容量(比例上即为:1 – storage.migrate.threshold)被突发性高流量所填满需要的时间。比如我们 PMem 预留了 500 GB,如果突发性高流量的速率为 5 GB/sec(这里指每一个 Kafka broker节点所接收到的速率),那么可以支撑的时间大约为 100 sec。
- 相邻突发性高流量至少需要间隔的时间,本质上为预留的 PMem 容量被后台迁移到二级存储的时间。比如我们预留了 500 GB,二级存储磁盘写速率为 500 MB/sec,那么间隔时间需要多于 1000 sec。
当然,实际场景较为复杂,需要根据业务需求进行硬件和参数配置的具体选择。
场景二测试结果:稳定高吞吐需求场景
当场景的流量需求是稳定的场景下,使用分级存储架构亦可以提升系统整体吞吐。但是这里注意,由于 PMem 容量限制,对于不同数据容量下的性能表现会有比较大的区别。在此次实验中,我们通过控制 log.retention.bytes 的参数来控制数据大小。在此实验中我们也让消费者持续消费,同时考察生产者和消费者性能。相关关键参数设置如下:
- storage.migrate.threshold = -1:此次实验关闭了自动迁移机制,避免迁移带来的额外的 overhead。
- log.retention.bytes:设置为相对应的值来控制整体 log 文件大小,用户也可以根据实际场景使用时间相关的参数来控制大小。

场景二:稳定高吞吐需求场景
如上图所示,当 retention_size=pmem_size 的时候,即把所有的数据容量控制在 PMem 容量大小以内,此种场景下可以达到最好的性能,大约为 6 GB/sec。当我们扩展容量超过 PMem 的时候,Pafka 会自动删除旧数据,因此在 PMem 上也会相应的空出容量给新数据,因此在总体上亦能改善性能。我们可以看到,当整体存储需求容量为 1.5x/2x 于 PMem 容量的时候,相比较于仅仅使用 HDD 的方案,Pafka 的分级存储方案依然可以提升大约 1-2 倍的整体吞吐。实际场景中,如果配备更大的 PMem 容量,其能带来的提升效果更好。
5. Pafka 0.3.0 开发计划
Pafka 将会不断进行技术迭代创新和优化,下一个稳定版本 Kafka 0.3.0,将会带来以下主要更新:
- Pafka 第一级存储介质将会泛化为普通文件接口,使得不仅仅 PMem 可以作为第一级存储介质,其他高性能存储设备(如 SSD) 也能作为第一级存储介质。SSD 主要带来容量的优势,虽然在性能带宽上会逊于PMem,但是在单台服务器上可以配置到几个 TB 级别的一级存储。此种情况下,对于高吞吐需要维持较长时间的场景(比如外卖平台可能需要维持2-3个小时的高峰吞吐),Pafka 可以更好的进行支持。而不再像当前仅仅支持 PMem 作为第一级存储的场景,虽然可以提供较大的峰值支持,但是维持时间亦较短。
- 我们将会提供一个易用的硬件配置计算器。由于分级存储机制的引入,根据各种场景的需求,如何做到最优化配置(最小成本投入,且满足场景性能需求),将会成为一个比较复杂的问题。用户需要综合考虑各级存储介质的性能和容量的配置。Pafka 硬件配置计算器将会解决这个问题,用户可以根据自己的场景需求输入,计算器自动为用户计算出最优化配置,并且可以显示相比较于 Kafka 原始方案的成本对比。
- Pafka 将会重新基于 Kafka 3.0.0 重新适配。
Pafka 0.3.0 版本预期将在2021年底发布,敬请关注我们的社区动态。
6. 社区支持
Github: https://github.com/4paradigm/pafka
技术支持和讨论:Slack Workspace
Email: contact@memark.io
One thought on “Pafka 0.2.0 介绍:基于分级存储架构优化,提升 Kafka 系统性能”