3

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

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

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

我已经考虑过以下解决方案:

  • 直接把新表写成SSTable,和旧表交​​换
  • 将更新作为批处理进行,并在开始时截断旧数据
  • 创建一个新表(使用新名称)并在程序中更改使用的表(在运行时)
  • 添加版本列,使用新版本添加新数据,然后删除旧数据(使用旧版本)

这些解决方案中哪一个是最好的?或者更好的是,有没有一种解决方案可以更优雅地解决我的问题?

4

1 回答 1

1

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

编写自己的 SSTable

我编写了一个创建 SSTables 的小型 Java 工具。在这里,您可以找到如何使用 CQLSSTableWriter 执行此操作的一个很好的示例。创建 SSTable 后,我使用sstableloader命令行工具(Cassandra 附带)将其导入 Cassandra。

结论

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

使用 CQL 和版本列导入

我编写了一个小型 Java 工具,它执行 CQL 命令以将数据集插入 Cassandra。另外,我添加了一个版本列,所以在导入之后,我可以删除旧数据。缺点是,我唯一的分区键是版本本身,所以我可以轻松删除旧数据集。为了解决这个问题,我使用 Solr 为该表建立了索引,并使用 Solr 查询在该表中进行搜索。事实上,数据不在单个节点之间分布对我们来说是可以的,搜索仍然像魅力一样工作。至少数据在几个节点之间被复制。

结论

  • 导入的持续时间还可以(~ 1.5 小时)
  • Cassandra 节点的负载大幅增加,我仍然需要调查这如何影响“普通用户”的体验(但快速检查表明这仍然很好)

结果

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

于 2016-03-03T11:56:13.363 回答