Cassandra集群读延迟高:单查询访问SSTables过多优化咨询
Cassandra集群单查询访问SSTables过多导致读延迟高的优化方案
问题根因
当前异常的核心原因是默认SizeTieredCompactionStrategy(STCS)的合并规则与业务写入模式不匹配:STCS要求凑够min_threshold个大小相近的SSTable才会触发合并,当前配置的min_threshold=4,当SSTable大小出现梯度断层时,就会出现无待执行compaction任务、但单查询需要跨十几个甚至二十个SSTable读数据的情况,和观测到的compaction数天触发一次、99分位读需要访问20个SSTable的现象完全吻合。
业务表的tablehistogram输出显示99分位读延迟达到129ms,远高于正常水平,完全符合读放大过高的特征:
Percentile SSTables Write Latency Read Latency Partition Size Cell Count (micros) (micros) (bytes) 50% 10.00 51.01 43388.63 179 3 75% 14.00 73.46 62479.63 642 12 95% 17.00 126.93 107964.79 5722 124 98% 20.00 152.32 129557.75 14237 310 99% 20.00 182.79 129557.75 24601 535 Min 0.00 14.24 51.01 51 0 Max 24.00 74975.55 268650.95 14530764 263210
当前表的compaction配置存在STCS默认参数适配性差的问题:
AND bloom_filter_fp_chance = 0.01 AND caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'} AND comment = '' AND compaction = {'class': 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy', 'max_threshold': '32', 'min_threshold': '4'} AND compression = {'chunk_length_in_kb': '64', 'class': 'org.apache.cassandra.io.compress.LZ4Compressor'} AND crc_check_chance = 1.0 AND dclocal_read_repair_chance = 0.1 AND default_time_to_live = 7776000 AND gc_grace_seconds = 86400 AND max_index_interval = 2048 AND memtable_flush_period_in_ms = 0 AND min_index_interval = 128 AND read_repair_chance = 0.0 AND speculative_retry = '99PERCENTILE';
紧急优化手段(低峰期操作,快速降低SSTable数量)
- 针对延迟异常的表手动触发全量合并:执行
nodetool compact <keyspace名称> <表名>,执行完成后单查询访问的SSTable数量会直接落到1~3的正常区间,读延迟会出现明显下降。注意该操作会占用一定磁盘IO,务必在业务低峰期执行。 - 如果单表数据量超过TB级、全量合并对资源占用过高,可以先执行
nodetool flush将所有memtable数据刷盘,再执行nodetool compact -s <keyspace名称> <表名>触发拆分式合并,将单次合并的资源压力打散,避免影响业务。
长期配置优化(从根源避免SSTable堆积)
- 替换Compaction策略:从表配置的
default_time_to_live=7776000(90天自动过期)判断,该表属于带TTL的时序类业务表,直接将默认STCS替换为TimeWindowCompactionStrategy(TWCS),按固定时间窗口合并SSTable,窗口内的数据会被合并成少量大文件,过期数据可以直接整文件删除,不会产生残留小SSTable。配置示例:
ALTER TABLE <keyspace名称>.<表名> WITH compaction = { 'class': 'org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy', 'compaction_window_unit': 'DAYS', 'compaction_window_size': '1', 'max_threshold': '16', 'min_threshold': '2' };
- 如果该表不属于时序类场景、需要继续使用STCS,直接调低合并触发阈值:将
min_threshold从4降到2,降低小SSTable触发合并的门槛,避免因为凑不够4个大小相近的SSTable导致合并迟迟不触发;同时将max_threshold从32降到8~16,避免单次合并处理过多SSTable导致资源尖刺。 - 开启墓碑自动清理适配TTL场景:新增compaction参数
'tombstone_threshold': '0.1'、'tombstone_compaction_interval': '86400'、'unchecked_tombstone_compaction': 'true',只要SSTable中过期墓碑占比超过10%就触发合并清理,避免过期数据占用空间导致SSTable数量虚高。
配套读性能优化
- 调低布隆过滤器假阳性率:将
bloom_filter_fp_chance从0.01调整为0.001,小幅提升内存占用的前提下,大幅降低无效SSTable磁盘探查次数,减少跨SSTable读的开销。 - 按需开启行缓存:如果业务读存在明显热点分区,将
caching配置中的rows_per_partition从NONE调整为热点分区的平均行数(比如100),直接将热点行缓存在内存中,不需要访问磁盘SSTable。
注意:所有compaction配置修改后不会立刻重写存量SSTable,存量文件会在后续compaction周期中逐步按新规则合并,要快速见效还是需要配合低峰期手动合并操作。
内容的提问来源于stack exchange,提问作者Anurag Rana
相关产品推荐
相关产品推荐

