Cassandra 的调优总结
硬件选择
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
评论 (2 条评论)