5

Cassandra的调优总结 - InfoQ 写作平台

 3 years ago
source link: https://xie.infoq.cn/article/54877e8201b70a5136c51f8e1
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Cassandra 的调优总结

发布于: 2021 年 07 月 23 日

Cassandra 的吞吐量随着更多的 CPU 内核、更多的 RAM 和更快的磁盘而提高,虽然 Cassandra 可以在测试或开发环境的小型服务器上运行,但是线上的生成环境至少需要 2 个内核和至少 8GB 的 RAM。典型的生产服务器具有 8 个或更多内核和至少 32GB 的 RAM。

  • Cassandra 堆应该不小于 2GB,并且不超过系统 RAM 的 50%,堆大小通常在系统内存的 ¼ 到 ½ 之间,不要将所有内存都用于堆,因为它也用于堆外缓存和文件系统缓存。

  • 小于 12GB 的堆应该考虑 ParNew/ConcurrentMarkSweep 垃圾收集

  • 大于 12GB 的堆应该考虑 G1GC,因为对于较大的堆,G1 的性能优于 CMS

  • 调整 GC 时始终启用 GC 日志记录,Cassandra 的 GCInspector 类记录了超过 200 毫秒的垃圾收集的信息。如果频繁打印 GC 日志,这表明 JVM 上的垃圾收集压力过大。除了调整垃圾收集选项外,其他策略还包括添加节点和降低缓存大小等

  • 出于性能的考虑,Xmx Xms 应该被设置为同样的值

业务场景优化

一般来说,使用 Cassandra 的场景分为三种:频繁写入、频繁读取、混合。在绝大部分业务中基本都是频繁写入和频繁读取

在讲业务场景优化之前先总结一下 GC 的一些结论以便于好理解后续的一些优化手段。对于 GC 来说,一般涉及清除垃圾与对象升级等过程,有如下相关结论:

  • 清除垃圾的过程是很快的

  • 升级对象相对与清除垃圾比较缓慢,它需要涉及到对象的复制

  • 升级对象越多,需要的时间越长,你配置的堆内存空间越大,越能进行更多的对象升级,但是也意味着你需要消耗更多的时间

一般来说 Cassandra 的写入性能较高,它的写入流程如下图:

(图片来源于网络)

  • 在 Commit log 中记录数据

  • 将数据写入内存表(memtable)

  • 从内存表中刷新数据

  • 将数据存储在磁盘上的 SSTables 中

在写入之后,后续还会涉及到 Compaction(压实)操作,所以在要优化频繁写入产生频繁 GC 的情况下要特别考虑需要被分配对象内存的部分:Memtable 和压实过程

对于 Memtable 来说,Memtable 所占据的空间是可以配置的,对于 Memtable 相关的对象可以分配到内存并且可以保留一段时间,我们可以通过 memtable_heap_space_in_mb 参数指定 Memtable 的大小。如果没有指定它会设置为堆内存容量的 1/4 作为其默认值。接下来还可以进行调整新生代的空间大小,从而减少 GC 停顿的频次。

对于压实来说,compaction_throughput_mb_per_sec 可以配置压实操作的吞吐量,并且压实操作可能会产生大量的垃圾以及大量短暂存活的对象。您应该根据自己的业务场景来选择不同的压实策略:

  • Size Tiered Compaction Strategy(STCS)

  • 默认压缩策略,推荐用于写入密集型的工作负载。或者当其他策略不适合工作负载时,作为后备很有用,也可以用于处理 LCS 策略的 I/O 过高的情况。

  • Leveled Compaction Strategy(LCS)

  • 推荐用于读取密集型工作负载。LCS 相比于其他策略会产生更多的 IO,如果你的 IO 已经是你的瓶颈了,切换到 LCS 带来的额外 IO 开销可能会抵消它所带来的优势。

  • Time Window Compaction Strategy(TWCS)

  • 适用于时间序列类型或任何有 TTL(存活时间)限制的数据库表。对于这种数据的频繁写入来说,相比 TimeWindowCompactionStrategy 这种压实策略,LeveledCompactionStrategy 这种压实策略不仅会产生更多的 I/O 并吃掉大量的 CPU 资源,同时还会产生远远更多的内存垃圾。

具体的优缺点可以参考:

对于读取频繁的工作模式来说,它与 Memtable 的关联就不大了,相反由于读取操作会从磁盘上拉出数据并创建临时的对象,频繁读取的工作负载会生成很多的短时存活对象。这些对象通常存活不过一秒,有时可能只存活几毫秒而已。所以在这种模式下我们更应该关注新生代与堆内存的大小。因为:

  • 对象的升级过程是缓慢的

  • 很多对象被升级会很容易导致老年代的空间被填满

所以在频繁读取的工作负载下,我们需要增加我们的堆内存和新生代的空间大小,不然可能就会产生更多的 GC 和停顿。同时增加 XX:MaxTenuringThreshold 的值也可以让对象留在新生代,而不是被升级(升级去老年代可能会占用大部分老年代空间,然后触发 full gc)。其次还可以调整-XX:SurvivorRatio=4 而不是用其默认值 8,让他拥有更大的 Survivor 空间。注意这里调整老年代空间所得到的收益不是很大。

以上的优化只是对一些常见手段的总结,优化的效果如何还需要根据具体业务场景来分析,其它可以调整的东西还有很多,比如:

  • 调整缓存的大小

  • 调整写入的线程数和读取线程数。

  • 关闭读修复的特性

  • 删除数据的时候调整 gc_grace_seconds 来更快的删除不要数据

  • 其它还可以根据业务调整数据一致性策略等

对于新手来说,你可能不能进行有效的优化,你所能做的只有按照思路多动手、多试试,进行适当的压测、不断地修改参数这样才能找到对于自己业务合适的调优配置。不要妄想着一蹴而就。以上知识讲的只是 Cassandra 的皮毛,记录下来一方面是为了后续遇到问题好查阅,一方面也想总结分享给大家。想要详细学习可以查阅

Cassandra 官方文档:https://cassandra.apache.org/doc/latest/getting_started/index.html

第三方教程:https://docs.datastax.com/en/cassandra-oss/3.0/cassandra/cassandraAbout.html


Recommend

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK