冷热隔离 & 5 倍冷读效率
一直以来,Apache Kafka 的用户深受 KAFKA-7504[1] 的困扰,这是迄今为止还未解决的一个 Kafka 性能问题。当 Apache Kafka 集群出现冷读时,如果冷读不能快速结束,越来越多的追尾读业务也会被拖慢到进入冷读状态,同时逐渐对流量的写入产生巨大的影响。
Apache Kafka 冷读问题
Apache Kafka 的读写链路引入了两个关键的技术:Page Cache[2] 和零拷贝 SendFile[3] 系统调用。
Page Cache 极大地简化了 Kafka 内存管理的负担,完全由内核来负责。但存在冷热无法分离的问题,如果有业务持续在冷读,会跟热数据互相争抢内存资源,导致追尾读能力持续下降。
SendFile 是 Kafka 零拷贝的关键技术,但该调用行为发生在 Kafka 的网络线程池,如果执行 SendFile 时需要从磁盘上拷贝数据(冷读场景),会在一定程度上阻塞该线程池。又因为该线程池是处理 Kafka 请求的入口,包括写请求,SendFile 的阻塞行为将导致 Kafka 的写入受到巨大的影响。
AutoMQ 冷热隔离架构
AutoMQ 从设计的第一天起就充分考虑到了异步的消息中间件所面临的冷热隔离问题。在 AutoMQ 的架构中,有 3 个关键的数据链路:
写入链路:数据以 Direct IO 的形式持久化写入到 WAL 存储当中,该过程不会依赖 Page Cache,数据写穿到 WAL 即返回客户成功,跟数据的读取链路完全分开。
追尾读链路:对于追尾读场景,数据直接从 AutoMQ 自建的 Cache 中读取。AutoMQ 的 Cache 组件类似于 Page Cache,当对冷热数据进行了分区隔离,也会在驱逐策略中充分考虑到消费者的关注度,以提高内存的效率。
冷读链路:对于冷读场景,数据直接从 S3 存储中读取,并通过预读策略来构建冷读 Cache。得益于对象存储的超高吞吐,以及冷热隔离的机制,AutoMQ 在冷读效率方面相较于 Apache Kafka 有数倍的提升。
AutoMQ 冷读性能评测
以下表格的结果来自于 AutoMQ vs Kafka 的实测(AutoMQ vs. Apache Kafka 性能对比▸),显示在相同负载和机型下相比 Kafka,AutoMQ 冷读时可以保证不影响写入吞吐和延迟的情况下,拥有和 Kafka 相同水准的冷读性能。
对比项 | 冷读过程中发送耗时 | 冷读过程中对发送流量影响 | 冷读效率 (冷读 4TiB 数据耗时) |
---|---|---|---|
AutoMQ | 小于 3ms | 读写隔离,维持 800 MiB/s | 42 分钟 |
Apache Kafka | 大约 800ms | 相互影响,下跌到 150 MiB/s | 215 分钟 |
从结果可以看出,AutoMQ 在冷读期间对发送的延迟没有任何影响,但 Apache Kafka 会恶化到秒级延迟,同时写入流量会持续下跌。在冷读效率方面,读取 4TiB 的数据,AutoMQ 会有 5 倍的效率提升。
冷热隔离的优势
AutoMQ 解决掉冷热隔离的性能问题过后,使得 AutoMQ 的架构对多租户更加友好。虽然 AutoMQ 得益于秒级的扩缩容能力,推荐为每一个业务配置单独的集,不需要通过混部来降本。但对于很多流量非常小的业务来讲,混部在一个集群里面可以有效地降低集群的数量,AutoMQ 冷热隔离的特性彻底解决了多租户场景下带来的稳定性问题。
另一方面,AutoMQ 充分发挥了对象存储高吞吐的特性,带来了 5 倍的冷读效率提升,能够在业务需要数据回放时快速满足业务需求。
引用
[1] Kafka 冷读性能问题来源:https://issues.apache.org/jira/browse/KAFKA-7504
[2] Linux Page Cache: https://en.wikipedia.org/wiki/Page_cache
[3] Linux SendFile: https://man7.org/linux/man-pages/man2/sendfile.2.html