我和我的同事被扔进了一个使用Cassandra的项目,没有任何介绍。好吧,我们开始吧!
SELECT * FROM reports WHERE timestamp < '2019-01-01 00:00:00' ALLOW FILTERING; Error: 1300
显然,我们的墓碑太多了。那是什么?墓碑是指由于性能原因尚未删除的数据。墓碑应该用 nodetool repair
在 gc_grace_period
已过期,默认值为10天。现在,这个项目已经有7年的历史了,似乎没有一个作业可以运行 repair
. 根据默认的警告和错误值,1k墓碑是很多。我们发现大约140万。我们用尺子量了墓碑的数量 Tracing on
,运行select查询,并累积报告的逻辑删除。
我们试着逃跑 nodetool repair --full -pr -j 4
但我们得到 Validation failed in /10.0.3.1
. datastax的修复指南希望我们用 nodetool scrub
. 但后来我们还是得到了同样的错误。导游要我们跑 sstablescrub
,失败,出现内存不足异常。
回到2019年之前删除数据的原始问题,我们尝试运行 DELETE FROM reports WHERE timestamp < '2019-01-01 00:00:00'
. 然而, timestamp
不是我们的分区密钥,所以我们不允许删除这样的数据,这也得到了许多其他stackoverflow帖子和jira上的datasax问题的证实。每一篇文章都提到我们应该“仅仅”更改cassandra数据库的模式以适应我们的查询。首先,我们只需要做一次;其次,我们的客户希望尽快删除这些数据。
有没有一种方法可以轻松地更改cassandra数据库的模式?
有没有一种方法可以让我们找到一个至少有效的缓慢解决方案?
总而言之,我们对Cassandra还不熟悉,我们不确定如何继续。
我们想要的是
删除2019年之前的所有数据并确认已删除
有稳定的选择,避免错误
你能帮忙吗?
如果有必要的话,我们有4个节点在azure的docker中运行。cassandra的版本是3.11.6。
1条答案
按热度按时间nqwrtyyt1#
墓碑可能存在于sstables中超过10天,因为它们在压实过程中被逐出,如果长时间没有发生,那么它们就留在那里。您有以下可用选项(对于3.11.x):
如果有磁盘空间,可以使用
nodetool compact -s
这将把所有的sstable合并成几个sstable—这将给系统带来很大的负载,因为它将读取所有数据并将它们写回使用
nodetool garbagecollect
逐出旧数据和过期的墓碑-但它可能不会删除所有墓碑您可以调整特定表的参数,以便更频繁地进行压缩,例如,将压缩的最小sstables数从4减少到2,再加上一些其他选项(
min_threshold
,tombstone_threshold
等)在将来,对于修复,建议使用像收割者这样的东西,它执行令牌范围修复,减少系统负载。
大量删除数据可以通过外部工具完成,例如:
spark+spark cassandra连接器-参见此答案示例
dsbulk-您可以使用
-query
选项指定要将数据卸载到磁盘的查询(仅主键的列,并使用:start
/:end
关键字),然后加载提供-query 'DELETE FROM table WHERE primary_key = ....'
对于模式更改来说,这不是最琐碎的任务。为了使表结构与查询相匹配,您很可能需要更改主键,而在cassandra中,这只能通过创建新表并将数据加载到这些新表中来完成。对于这个任务,您还需要spark或dsbulk之类的东西,特别是当您需要使用ttl和/或writetime迁移数据时。有关更多详细信息,请参阅此答案。