【问题标题】:cassandra high volume writes sometimes silently failcassandra 大量写入有时会默默失败
【发布时间】:2016-03-29 06:02:06
【问题描述】:

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

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

[CassandraClient] - 在 2015 年 12 月 22 日星期一 22:54:04 UTC 添加到 /10.0.0.118[SharedPool-Worker-1] 上的交易内存表

[CassandraClient] - 在 2015 年 12 月 22 日星期一 22:54:04 UTC 附加到 /10.0.0.118[SharedPool-Worker-1] 上的提交日志

[CassandraClient] - 使用的协调器 /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

【问题讨论】:

    标签: java cassandra datastax datastax-java-driver


    【解决方案1】:

    写入成功并且某些记录丢失的事实是 C* 正在覆盖丢失的行的症状。您可能会看到这种行为的原因是滥用绑定语句。

    通常人们准备陈述:

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

    然后他们会发布类似的内容:

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

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

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

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

    【讨论】:

    • 我不认为这是正确的。我只是尝试完全这样做,我得到了预期的百万行。
    • @AndreasWederbrand 抱歉,我写的是 PreparedStatement,但我真正的意思是 BoundStatement。 ps.bind(...)new BoundStatement(ps).bind(...) 的别名。我要更新答案。感谢您指出这一点。
    猜你喜欢
    • 2013-11-01
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 2011-04-09
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多