导读:本期聚焦于云朵创作的《Cassandra压缩策略如何调整才能兼顾读写性能与磁盘占用?》,敬请观看详情。磁盘空间一路飙升,读延迟越来越不稳定,这往往是Cassandra的compaction策略没有调对。本文围绕SizeTieredCompactionStrategy和LeveledCompactionStrategy两大主流压缩策略展开,分析它们各自的适用场景、空间放大与读放大特性,并给出写多读少、读多写少以及时序数据等典型负载下的选择建议。文中还结合实际参数配置演示了tombstone清除、sstable数量控制、压缩任务限流等调优手法,帮助你在写入吞吐、读取延迟和磁盘占用之间找到平衡点。

Cassandra的数据写入遵循LSM-Tree模型,所有写入先落Memtable,刷盘后生成SSTable,再依靠compaction机制把多个SSTable合并整理。可以说,compaction策略直接决定了这个集群的读写性能曲线和磁盘占用水位。策略选错或者参数没调好,常见的结果就是:磁盘空间莫名其妙涨了一倍,读延迟P99时不时飙高,或者压缩线程把CPU和IO全部吃光。这篇文章结合实际运维经验,聊聊如何针对不同负载调整Cassandra的压缩策略。

Cassandra压缩策略如何调整才能兼顾读写性能与磁盘占用?

两大主流策略的原理与取舍

Cassandra内置了多种compaction策略,最核心的是SizeTieredCompactionStrategy(简称STCS)和LeveledCompactionStrategy(简称LCS)。理解它们的工作方式,是做任何调优的前提。

STCS的思路很简单:把大小相近的SSTable分到一组,当同组数量达到阈值(默认min_threshold为4,max_threshold为32)时触发合并。它实现简单、写入放大低,适合写入量大的场景。但缺点也很明显:合并是全量的,新旧数据混合在一起,空间放大严重,极端情况下磁盘占用可以达到真实数据量的两倍以上。而且SSTable数量不可控,读取时可能需要扫描很多文件,读放大随时间推移不断恶化。

LCS则完全不同。它把SSTable组织成多层,L0层接收从Memtable刷下来的新文件,每往下一层,数据量大约是上一层的10倍(由fanout参数控制)。每一层的SSTable之间key范围互不重叠,读取时最多每层查一个文件,读放大稳定且很小。代价是写入放大明显更高,因为一个L1的SSTable被合并时,可能需要把L2中所有与其key范围重叠的文件一起重写。经验数据是LCS的写放大大约是STCS的3到10倍,对SSD比较友好,对HDD机械盘则要谨慎评估。

简单总结:写多读少、允许空间放大的场景用STCS;读延迟敏感、要求磁盘占用可预测的场景用LCS。另外还有一个TimeWindowCompactionStrategy(TWCS),专门为时序数据设计,后面单独说。

如何修改策略与关键参数

修改压缩策略不需要重启节点,直接修改表的属性即可,线上操作时建议一个数据中心一个数据中心地滚动执行,避免全集群同时触发大量compaction任务。

-- 查看当前策略
DESCRIBE TABLE metrics.hourly_data;

-- 将表切换为 LeveledCompactionStrategy
ALTER TABLE metrics.hourly_data WITH
  compaction = {
    'class': 'LeveledCompactionStrategy',
    'sstable_size_in_mb': '160'
  };

-- 切换为 TimeWindowCompactionStrategy
ALTER TABLE metrics.sensor_readings WITH
  compaction = {
    'class': 'TimeWindowCompactionStrategy',
    'compaction_window_size': '1',
    'compaction_window_unit': 'HOURS',
    'expired_sstable_frequency_seconds': '86400'
  };

切换策略后,Cassandra并不会立即重写所有现有SSTable,而是随着新数据写入和后台合并逐步过渡。所以切换后的一段时间内,磁盘占用反而可能上升,因为新旧两种布局的文件并存,这一点务必提前和业务方沟通,预留足够磁盘余量,一般建议至少留出50%的空闲空间。

几个值得关注的参数:sstable_size_in_mb控制LCS每层的目标文件大小,默认160MB,增大可以减少文件数和compaction频率,但会提高单次合并的IO压力;min_thresholdmax_threshold控制STCS触发合并的SSTable数量门槛;tombstone_threshold(配合tombstone_compaction_interval)决定了删除标记占比达到多少时触发一次清理合并,默认0.2,如果表有大量删除或TTL过期,适当调低到0.1能更快回收空间。

tombstone清除与读放大治理

调优压缩策略绕不开tombstone问题。Cassandra的删除和TTL过期都会产生tombstone记录,读取时必须跨SSTable检查这些墓碑,如果清理不及时,读放大和读延迟会持续恶化,甚至触发toomany-tombstones告警导致读取失败。

第一个手段是让表级别TTL承担过期职责,尽量少用应用层显式DELETE。TTL数据由TWCS或LCS在compaction时自然清除,而显式删除产生的墓碑必须等到gc_grace_seconds(默认86400秒,即10天)之后才能被丢弃。如果业务可以接受,把gc_grace_seconds调小到一天,配合TWCS的窗口机制,能让过期数据以小时级别被物理清除。

第二个手段是监控并及时处理高墓碑率的SSTable。可以通过nodetool compactionstats观察压缩队列,用sstablemetadata工具查看单个文件中tombstone的比例。对于墓碑占比超过30%的表,手动执行一次major compaction往往能立刻降低读放大:

# 查看压缩任务执行情况
nodetool compactionstats -h 127.0.0.1

# 对单表手动触发 major compaction(会带来较大IO压力,避开业务高峰)
nodetool compact mykeyspace mytable

# 压缩限流,限制压缩使用的吞吐量,单位MB/s
nodetool setcompactionthroughput 64

第三个手段是压缩限流。compaction默认可以使用50MB/s的IO吞吐,当磁盘IO成为瓶颈时,如果放任压缩全速运行,会导致读写请求排队;反过来如果限得太死,压缩积压又会推高磁盘水位。建议根据磁盘类型设置:SSD上可以放到128MB/s甚至不限制,HDD上保守地保持32到64MB/s,并通过nodetool compactionstats中的pending任务数持续观察调整。

不同负载下的选型建议

结合实际运维经验,给出几类典型负载的推荐配置。

写多读少的日志类、事件流水类表,首选STCS。这类表数据写入后极少回读,读放大不敏感,STCS的低写放大能保护磁盘寿命和写入吞吐。需要注意的是,如果这类表设置了TTL且数据量大,STCS回收空间很慢,应该改用TWCS。例如数据按天过期,就把窗口设为24小时,每个窗口的SSTable在整体过期后可以被直接整体删除,几乎是零写放大的空间回收方式。

读延迟敏感的用户画像、账户、元数据类表,首选LCS。这类表要求P99读延迟稳定,LCS每层最多查一个文件的特性能把读延迟控制在很小的波动范围内。同时LCS的空间放大约为1.1倍,磁盘容量规划可以做得非常精确。前提是磁盘必须是SSD,且写入量在集群可承受范围内。

混合负载如果拿不准,一个务实的做法是先用LCS观察一周的compaction指标:重点看流量监控中的压缩读写总量与业务写入量的比值。如果写放大超过20倍,说明这块盘扛不住LCS,再退回STCS或考虑TWCS。调优没有银弹,核心思路永远是:先明确业务对读延迟、写吞吐、磁盘占用三者的优先级排序,再让压缩策略为最敏感的那一项服务。

Cassandra压缩策略LeveledCompactionStrategySizeTieredCompactionStrategy修改时间:2026-09-05 23:52:50

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260905/51225.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。