我们有一个运行Cassandra 2.2.14的新集群,并留下了压缩来"自行排序"。这是在我们的UAT环境中,所以负载很低。我们运行STCS。
我们看到永远在生长的墓碑。我知道,一旦sstable符合压缩条件,压缩最终会处理数据。这种情况对我们来说并不常见,所以我启用了一些设置作为测试(我知道它们很激进,这纯粹是为了测试):
'tombstone_compaction_interval': '120',
'unchecked_tombstone_compaction': 'true',
'tombstone_threshold': '0.2',
'min_threshold': '2'
这确实导致了一些压缩的发生,但是丢弃的tombstone数量很低,也没有低于阈值(0.2)。在应用了这些设置之后,我可以从sstablemetadata中看到以下内容:
Estimated droppable tombstones: 0.3514636277302944
Estimated droppable tombstones: 0.0
Estimated droppable tombstones: 6.007563159628437E-5
请注意,这只是一个CF,还有更糟糕的CF(90%的逻辑删除,等等)。以此为例,但所有CF都有相同的症状。
表格统计:
SSTable count: 3
Space used (live): 3170892738
Space used (total): 3170892738
Space used by snapshots (total): 3170892750
Off heap memory used (total): 1298648
SSTable Compression Ratio: 0.8020960426857765
Number of keys (estimate): 506775
Memtable cell count: 4
Memtable data size: 104
Memtable off heap memory used: 0
Memtable switch count: 2
Local read count: 2161
Local read latency: 14.531 ms
Local write count: 212
Local write latency: NaN ms
Pending flushes: 0
Bloom filter false positives: 0
Bloom filter false ratio: 0.00000
Bloom filter space used: 645872
Bloom filter off heap memory used: 645848
Index summary off heap memory used: 192512
Compression metadata off heap memory used: 460288
Compacted partition minimum bytes: 61
Compacted partition maximum bytes: 5839588
Compacted partition mean bytes: 8075
Average live cells per slice (last five minutes): 1.0
Maximum live cells per slice (last five minutes): 1
Average tombstones per slice (last five minutes): 124.0
Maximum tombstones per slice (last five minutes): 124
这里显而易见的答案是,这些墓碑没有资格被拆除。
gc_grace_conds设置为10天,并且尚未移动。我把其中一个sstable转储到json,我可以看到可以追溯到2019年4月的墓碑:
{"key": "353633393435353430313436373737353036315f657370a6215211e68263740a8cc4fdec",
"cells": [["d62cf4f420fb11e6a92baabbb43c0a93",1566793260,1566793260977489,"d"],
["d727faf220fb11e6a67702e5d23e41ec",1566793260,1566793260977489,"d"],
["d7f082ba20fb11e6ac99efca1d29dc3f",1566793260,1566793260977489,"d"],
["d928644a20fb11e696696e95ac5b1fdd",1566793260,1566793260977489,"d"],
["d9ff10bc20fb11e69d2e7d79077d0b5f",1566793260,1566793260977489,"d"],
["da935d4420fb11e6a960171790617986",1566793260,1566793260977489,"d"],
["db6617c020fb11e6925271580ce42b57",1566793260,1566793260977489,"d"],
["dc6c40ae20fb11e6b1163ce2bad9d115",1566793260,1566793260977489,"d"],
["dd32495c20fb11e68f7979c545ad06e0",1566793260,1566793260977489,"d"],
["ddd7d9d020fb11e6837dd479bf59486e",1566793260,1566793260977489,"d"]]},
所以我不认为gc_grace_conds是这里的问题。我已经对列族文件夹中的每个Data.db文件运行了手动用户定义的压缩(只有一个Data.db单独的文件,一次一个)。压缩已运行,但tombstone值几乎没有变化。旧数据仍然存在。
事实上,我可以确认昨天已经进行了维修。我还可以确认维修一直在定期进行,日志中没有显示任何问题。
所以维修是可以的。压实很好。我所能想到的就是重叠的SSTables。
最后的测试是对柱族进行完全压实。我使用JMXterm在3个SSTables上执行了用户定义的(而不是nodetool compact)。这导致了一个单一的SSTable文件,其中包含以下内容:
Estimated droppable tombstones: 9.89886650537452E-6
如果我查找上面的示例EPOCH(1566793260),它是不可见的。关键也不是。所以它被压缩了,或者卡桑德拉做了什么。在1.2亿行转储中,包含tombstone("d")标志的行总数为1317行。EPOCH值都在10天内。好的
因此,我假设-6值是一个很小的百分比,sstablemetadata在显示它时遇到了问题。那么,成功吧?但拆除这些旧墓碑需要一次全面的压实。据我所知,全面压实只是最后一搏。
我的问题是-
- 如何确定重叠的sstables是否是我的问题?我看不出数据不会压缩的任何其他原因,除非它是重叠相关的
- 如何在不执行完全压缩的情况下解决重叠的sstables?恐怕几周后这种情况还会再次发生。我不想被困在必须定期执行完整的压缩以阻止墓碑
- 创建重叠sstable的原因是什么?这是数据设计问题,还是其他问题
干杯。
回答您的问题:
如何确定重叠的sstables是否是我的问题?我看不出数据不会压缩的任何其他原因,除非它是重叠相关的。
如果tombstone不是通过使用TTL生成的,那么更多时候tombstone和阴影数据可以定位到不同的sstable中。当使用STCS并且对集群的写入量很低时,很少会触发压缩,这会导致逻辑删除停留很长时间。如果您有tombstone的分区键,那么在节点上运行nodetool getsstables -- <keyspace> <table> <key>
将返回本地节点中包含该键的所有sstable。您可以转储sstable内容以进行确认。
如何在不执行完全压缩的情况下解决重叠的sstable?恐怕几周后这种情况还会再次发生。我不想被困在必须定期执行完整的压缩以阻止墓碑。
"nodetool compacting-s"中有一个新选项,可以进行主要的压缩,并将输出分割为4个不同大小的sstable。这解决了之前的主要压实问题,即产生单个大的sstable。如果可丢弃的tombstone比率高达80-90%,则由于大多数tombstone已被清除,因此生成的sstable大小将更小。
在更新的版本Cassandra(3.10+)中,有一个新的工具nodetool garbagecollect,用于清理tombstone。但是,该工具存在局限性。并不是所有的墓碑都能被它移除。
总而言之,对于您的情况,即存在重叠的sstable和低活动量/较少的压缩频率,您必须找出所有相关的sstable并使用用户定义的压缩,或者使用"-s"进行主要压缩。https://docs.datastax.com/en/dse/5.1/dse-admin/datastax_enterprise/tools/nodetool/toolsCompact.html
创建重叠sstable的原因是什么?这是数据设计问题,还是其他问题?
tombstone的快速增长通常表明存在数据建模问题:无论应用程序是插入null,还是定期删除数据,或者使用收集和更新而不是追加。如果您的数据是时间序列,请检查使用TTL和TWCS是否有意义。