java - cassandra 大量写入有时会默默地失败

标签 java cassandra datastax datastax-java-driver

我正在使用 Datastax Cassandra java 驱动程序记录实时交易数据。我为 Cassandra 配置了单个节点、复制因子 1 和一致性级别 ALL。

我经常有不记录但不会失败的写入。 java客户端没有抛出任何错误,异步执行成功回调被调用。 Trace 似乎没有显示任何异常:

[CassandraClient] - Adding to trades memtable on /10.0.0.118[SharedPool-Worker-1] at Mon Dec 22 22:54:04 UTC 2015

[CassandraClient] - Appending to commitlog on /10.0.0.118[SharedPool-Worker-1] at Mon Dec 22 22:54:04 UTC 2015

[CassandraClient] - Coordinator used /10.0.0.118

但是,当我查看 cassandra shell 中的数据时,请注意跳过的 ID(忽略错误日期):

cqlsh:keyspace> select * from trades where [...] order by date desc limit 10;

 date                     | id     | price  | volume
--------------------------+--------+--------+------------
 1970-01-17 19:00:19+0000 | 729286 | 435.96 |  3.4410000
 1970-01-17 19:00:19+0000 | 729284 | 436.00 | 17.4000000
 1970-01-17 19:00:19+0000 | 729283 | 436.00 |  0.1300000
 1970-01-17 19:00:19+0000 | 729277 | 436.45 |  5.6972000
 1970-01-17 19:00:19+0000 | 729276 | 436.44 |  1.0000000
 1970-01-17 19:00:19+0000 | 729275 | 436.44 |  0.9728478
 1970-01-17 19:00:19+0000 | 729274 | 436.43 |  0.0700070
 1970-01-17 19:00:19+0000 | 729273 | 436.45 |  0.0369260
 1970-01-17 19:00:19+0000 | 729272 | 436.43 |  1.0000000
 1970-01-17 19:00:19+0000 | 729271 | 436.43 |  1.0000000

为什么有些插入会悄无声息地失败?指示指向时间戳问题,但我没有检测到模式。

类似问题:Cassandra - Write doesn't fail, but values aren't inserted

可能与:Cassandra update fails silently with several nodes 有关

最佳答案

写入成功但一些记录丢失的事实表明 C* 正在覆盖丢失的行。您可能看到这种行为的原因是滥用了绑定(bind)语句。

通常人们准备语句:

PreparedStatement ps = ...;
BoundStatement bs = ps.bind();

然后他们发出类似的东西:

for (int i = 0; i < myHugeNumberOfRowsToInsert; i++) {
    session.executeAsync(bs.bind(xx));    
}

这实际上会产生奇怪的行为,因为绑定(bind)语句 在大多数 executeAsync 调用中都是相同的,并且如果循环足够快以排队(比如) 在驱动程序触发第一个查询之前的 6 个查询,所有提交的查询共享相同的绑定(bind)数据。一个简单的解决方法是实际发出不同的 BoundStatement:

for (int i = 0; i < myHugeNumberOfRowsToInsert; i++) {
    session.executeAsync(new BoundStatement(ps).bind(xx));    
}

这将保证每个语句都是唯一的,并且根本不可能覆盖

关于java - cassandra 大量写入有时会默默地失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34424886/

相关文章:

mysql - 包含相关数据的非常大的表。什么样的 DBMS 是最佳的,以及如何对其建模?

java - 如何选择一个图片目录(使用单选按钮)以 Java for Android 显示?

audio - 在 Java 中交替播放 2 个不同的频率

cassandra - 在 Cassandra Docker 中启用 Thrift

c++ - 将结果存储在 C++ 中的 Map 中,然后对其进行迭代,然后打印出来?

datastax - 如何使用用户定义的函数获取 cassandra 的 blob 列的大小?

linux - 使用 Linux Shell 脚本远程连接到 Cassandra 实例

cassandra - 如何在Cassandra CQL中列出所有实例化 View 表

java - Return 和 Break 语句之间的区别

java - Hibernate - 自定义插入数据库