Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在不停机的情况下在Cassandra中进行大量更新?_Java_Datastax Enterprise_Cql3_Cassandra 2.1 - Fatal编程技术网

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

Java 如何在不停机的情况下在Cassandra中进行大量更新?,java,datastax-enterprise,cql3,cassandra-2.1,Java,Datastax Enterprise,Cql3,Cassandra 2.1,我有一个非常大的卡桑德拉表,大约有1300万个条目。此表用作查找表的一种。这意味着没有写操作,只有读操作。我使用的是Datastax Enterprise 4.8(包括Cassandra 2.1) 因此,内容是非常静态的,但不时(每隔几个月)会更新内容。问题是,旧数据可能会过时,而新数据会出现。但旧数据不会被覆盖(它会保留在表中)。为了有一个干净的数据库,有必要删除旧数据 我有一个要求。。。数据库必须在更新期间可用。在短时间内(几分钟),新旧数据并存是可以的 我已经考虑过以下解决方案: 直接将

我有一个非常大的卡桑德拉表,大约有1300万个条目。此表用作查找表的一种。这意味着没有写操作,只有读操作。我使用的是Datastax Enterprise 4.8(包括Cassandra 2.1)

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

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

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

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

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

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

写自己的SSTable 我已经编写了一个小型Java工具来创建SST表。您可以找到一个很好的示例,说明如何使用CqlStableWriter执行此操作。创建SSTable之后,我使用命令行工具(Cassandra附带)将其导入Cassandra

结论

  • SSTable的创建非常快(大约10分钟)
  • SSTable的导入非常慢(约6小时)
  • 您必须注意使用与cassandra版本完全相同的java库版本(cassandra all.jar),否则可能会发生创建的SSTable与cassandra不兼容的情况
使用CQL和版本列导入 我编写了一个小型Java工具,它执行CQL命令将数据集插入Cassandra。此外,我还添加了一个version列,因此在导入之后,我可以删除旧数据。缺点是,我唯一的分区密钥是版本本身,因此我可以轻松删除旧数据集。为了解决这个问题,我用索引表来搜索该表。事实上,数据不分布在单个节点之间对我们来说是可以的,搜索仍然像一个魅力。至少在多个节点之间复制数据

结论

  • 导入的持续时间正常(约1.5小时)
  • Cassandra节点的负载大幅增加,我仍然需要调查这是如何影响“普通用户”的体验的(但快速检查表明这仍然很好)
结果
我将使用第二种解决方案,因为它更快,而且您不必考虑正确的库版本。在我所有的工具中,我都使用线程,所以这里我还有一个很大的调整螺丝,可以在并发性和线程开销之间找到最佳平衡。最后,我在我的工具中使用了少量线程(~8个),但是使用了Datastax Java驱动程序的方法。

您的意思是数据必须可用吗?因为截断然后插入将在数据库不关闭的情况下工作。对不起,忘了提及。是,数据必须可用(旧数据或新数据)。问题是,如果我截断表,插入新数据大约需要30分钟。这差不多是30分钟的停机时间。是否可以使用名称中的版本号创建一个新表,并将新数据写入该表,然后将应用程序/用户切换到使用该表?更新是该表的全新版本吗?@mikea这或多或少是我的第三个解决方案。我还有一个集群应用程序(除了集群Cassandra)。因此,我还必须实现一种机制来通知我的所有应用程序表已更改。这就是我不喜欢这个想法的原因。