首页 > 解决方案 > 修复 Cassandra 数据库

问题描述

我和我的同事被扔进了一个没有介绍就使用 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 墓碑很多。我们发现大约 1.4M。我们用 测量了墓碑的数量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 上的 DataStax 问题所证实。每篇文章都提到我们应该“只是”改变 Cassandra 数据库的模式以适应我们的查询。首先,我们只需要这样做一次;其次,我们的客户希望尽快删除这些数据。

  1. 有没有办法轻松更改 Cassandra 数据库的架构?
  2. 有没有一种方法可以让我们做出一个至少有效的缓慢解决方案?

总而言之,我们是 Cassandra 的新手,我们不确定如何进行。

我们想要的是

  1. 删除 2019 年之前的所有数据并确认已删除
  2. 有稳定的选择,避免错误 1300

你能帮我吗?

如果有必要知道的话,我们有 4 个节点在 Azure 上的 Docker 中运行。Cassandra 的版本是 3.11.6。

标签: databasecassandra

解决方案


Tombstones 可能在 SSTables 中存在超过 10 天,因为它们在压缩过程中被驱逐,如果很长一段时间没有发生,那么它们就呆在那里。您有以下可用选项(适用于 3.11.x):

  • 如果您有磁盘空间,您可以使用nodetool compact -s将所有 SSTables 组合成几个 SSTables 来强制压缩 - 这会给系统带来大量负载,因为它会读取所有数据并将它们写回
  • 用于nodetool garbagecollect驱逐旧数据和过期的墓碑 - 但它可能不会删除所有墓碑
  • 您可以调整特定表的参数,以便更频繁地进行压缩,例如,将压缩的最小 SSTable 数量从 4 减少到 2,以及一些其他选项min_threshold,tombstone_threshold等)

将来,对于修复,建议使用Reaper之类的东西,它执行令牌范围修复,从而减少系统负载。

数据的大规模删除可以通过外部工具来完成,例如:

  • Spark + Spark Cassandra 连接器 -例如,请参阅此答案
  • DSBulk - 您可以使用该-query选项指定您的查询将数据卸载到磁盘(仅主键的列,并使用:start/:end关键字),然后加载提供的数据-query 'DELETE FROM table WHERE primary_key = ....'

对于模式更改 - 这不是最简单的任务。为了使您的表结构与查询相匹配,您很可能需要更改主键,而在 Cassandra 中,这仅通过创建新表并将数据加载到这些新表中来完成。对于该任务,您还需要 Spark 或 DSBulk 之类的东西,尤其是当您需要使用 TTL 和/或 WriteTime 迁移数据时。有关更多详细信息,请参阅此答案


推荐阅读