如何在不停机的情况下在 Cassandra 中进行大量更新?

How to do huge updates in Cassandra without downtime?

我有一个非常庞大的 Cassandra table,大约有 1300 万个条目。此 table 用作一种查找 table。这意味着没有写入,只有读取。我使用Datastax Enterprise 4.8(包括Cassandra 2.1)。

因此,内容是非常静态的,但会不时(每隔几个月)更新内容。问题是,旧数据可能会过时并出现新数据。但旧数据不会被覆盖(它保留在 table 中)。有必要删除旧数据以获得干净的数据库。

我有一个要求...更新期间数据库必须可用。新旧数据并存的短时间段(几分钟)是可以的。

我已经想到了以下解决方案:

以下哪种解决方案最好?或者更好的是,有没有更优雅地解决我的问题的解决方案?

好的,经过大量测试,这是我的发现。所有提到的测量都基于 1300 万个数据集。

写自己的SSTable

我编写了一个创建 SSTables 的小 Java 工具。 Here you can find a good example how to do this with the CQLSSTableWriter. After the creation of the SSTable I have used the sstableloader 命令行工具(Cassandra 自带)将其导入 Cassandra。

结论

  • SSTable 的创建非常快(约 10 分钟)
  • SSTable 的导入非常慢(~ 6 小时)
  • 你必须注意使用与你的 Cassandra 版本完全相同的 java 库版本 (cassandra-all.jar),否则创建的 SSTable 可能会与 Cassandra 不兼容

使用 CQL 和版本列导入

我编写了一个 Java 小工具来执行 CQL 命令以将数据集插入 Cassandra。此外,我添加了一个版本列,因此在导入后,我可以删除旧数据。缺点是,我唯一的分区键是版本本身,所以我可以轻松删除旧数据集。为了解决这个问题,我用 Solr and use Solr queries 索引了 table 以在 table 中搜索。事实上,数据不分布在单个节点之间对我们来说没问题,搜索仍然很有魅力。至少数据在几个节点之间是复制的。

结论

  • 导入的持续时间还可以(~ 1.5 小时)
  • Cassandra 节点的负载急剧上升,我仍然需要研究这对 "normal users" 的体验有何影响(但快速检查表明这仍然很好)

结果

我将使用第二种解决方案,因为它速度更快,而且您不必关注正确的库版本。在我所有的工具中,我都使用线程,所以这里我也有一个大的调整螺丝来找到并发性和线程开销之间的最佳平衡。最后,我在我的工具中使用了少量线程(~8),但使用了 Datastax Java 驱动程序的 executeAsync 方法。