Apache Cassandra 4.0:使用 Java 16 ZGC 控制尾部延迟 | foojay

21-06-23 banq

使用 Apache Cassandra 4.0,您不仅可以直接获得 Apache Cassandra 提交者添加的性能改进,还可以获得利用 JVM 本身七年改进的能力。本文重点介绍与 Java 8 上的 Cassandra 3.11 相比,Cassandra 4.0 与 Java 16 结合提供的 Java 垃圾收集改进。
与 Apache Cassandra 社区中的许多其他人一样,我非常高兴地看到 4.0 版本终于发布了。Cassandra 4.0有 很多很多改进。一项比看起来更重要的增强功能是增加了对 Java 9 及更高版本的支持。这并非微不足道,因为 Java 9 对 Cassandra 等最注重性能的 Java 项目所依赖的一些内部 API 进行了更改(您可以在此处阅读更多相关信息 )。
这很重要,因为在 Cassandra 4.0 中,您不仅可以获得 Apache Cassandra 提交者对性能的直接改进,还可以利用 JVM(Java 虚拟机)本身七年的改进。
在这里,我想重点介绍与 Java 8 上的 Cassandra 3.11 相比,Cassandra 4.0 与 Java 16 结合提供的 Java 垃圾收集方面的改进。
 

垃圾回收挑战
一方面,垃圾收集是 Java 比 C++ 等传统系统语言效率更高的主要原因。正如 JVM 架构师 Cliff Click 曾经写过的那样,“使用 GC 编写许多并发算法非常容易,而使用显式自由则完全不可能甚至完全不可能。” Cassandra 充分利用了这种能力。
但是执行垃圾收集意味着必须暂时暂停 JVM 以确定哪些对象不再使用并且可以安全地处理掉。这些 GC 暂停会导致对客户端请求的响应时间延迟,即延迟增加。
并非所有请求都受此影响——只有少数请求在 Cassandra 的请求处理线程为 GC 暂停时正在运行。因此,性能影响仅在尾部延迟中可见,即 99% 或 99.9% 的测量值,对应于最慢的 1% 或 0.1% 的请求。
与许多事情一样,优化 GC 涉及权衡,原始 Java GC 设计更多地关注提高吞吐量而不是减少暂停时间。快进到 2021 年,我们拥有具有 64 核/128 线程的通用服务器级 CPU——我们有大量可用的吞吐量。是时候将其中一些周期花费在较低的暂停时间上了。
Z 垃圾收集器 (ZGC) 旨在解决这种情况,特别是为了保证暂停时间低于 10 毫秒。ZGC 作为实验性功能添加到 Java 11 中, 在 Java 15 中推广到生产,并  在 Java 16 中进一步改进
为了展示 ZGC 如何提高 Cassandra 性能,我们比较了三种环境中的吞吐量和延迟:在 JDK 8 上运行的 Cassandra 3.11 使用其默认的 CMS GC 设置,Cassandra 4.0 在具有相同设置的 JDK 8 上运行,以及 Cassandra 4.0 在 JDK 16 上运行与 ZGC。我很高兴地报告,ZGC 令人信服地实现了其设计目标,使 Cassandra 能够在 99% 时提供几乎恒定的延迟,而在 99.9% 时仅略有上升!
点击标题
 

结论
在不切换到 ZGC 的情况下,Cassandra 4.0 为键/值和表格工作负载提供了适度但真正的吞吐量改进。
将 Cassandra 4.0 与 Java 16 中的 ZGC 相结合,进一步提高了键/值和时间序列工作负载的吞吐量,并令人信服地展示了 ZGC 的设计目标,使 GC 暂停时间在 Cassandra 4.0 的所有测试工作负载中都不是问题。
ZGC 从 Java 15 开始即可投入生产;对于想要坚持使用 LTS 版本的企业,ZGC 将是今年晚些时候升级到 Java 17 LTS 版本的首要原因之一。ZGC 是最重要的性能“免费午餐”之一,它就是有效的——这里显示的结果是 ZGC 开箱即用的,无需额外调整。