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

时间:2016-02-16 10:10:35

标签: java datastax-enterprise cql3 cassandra-2.1

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

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

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

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

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

哪种解决方案最好?或者甚至更好,是否有解决方案可以更加优雅地解决我的问题?

1 个答案:

答案 0 :(得分:1)

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

编写自己的SSTable

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

<强>结论

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

使用CQL和版本列导入

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

<强>结论

  • 导入的持续时间正常(约1.5小时)
  • Cassandra节点的负载量大幅上升,我仍然需要调查这会如何影响“普通用户”的体验(但快速检查表明这仍然没问题)

结果

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