Cassandra - 写入不会失败,但不会插入值

标签 cassandra cql cassandra-2.0 datastax-java-driver cassandra-cli

我有一个由 3 个 Cassandra 2.0 节点组成的集群。我的应用程序编写了一个测试,尝试将一些数据写入 Cassandra 或从 Cassandra 读取一些数据。一般来说,这工作得很好。

奇怪的是,在我重新启动计算机后,这个测试将失败,因为写入后我读取了之前写入的相同值,并且得到的是 null 而不是该值,但写入时也不异常(exception)。 如果我手动截断使用的列族,测试就会通过。之后我可以按照我想要的频率执行这个测试,它一次又一次地通过。此外,Cassandra 中是否有值并不重要。结果总是一样的。

如果我查看 CLI 和 CQL-shell,会发现两种不同的 View :

cassandra-cli

enter image description here

有人知道出了什么问题吗? CLI中的时间戳在重新执行后更新,所以它似乎是一个读取问题?

我的代码的一部分: 对于插入我尝试过

Insert.Options insert =   QueryBuilder.insertInto(KEYSPACE_NAME,TABLENAME)
                .value(ID, id)
                .value(JAHR, zonedDateTime.getYear())
                .value(MONAT, zonedDateTime.getMonthValue())
                .value(ZEITPUNKT, date)
                .value(WERT, entry.getValue())
                .using(timestamp(System.nanoTime() / 1000));

Insert insert = QueryBuilder.insertInto(KEYSPACE_NAME,TABLENAME)
                .value(ID, id)
                .value(JAHR, zonedDateTime.getYear())
                .value(MONAT, zonedDateTime.getMonthValue())
                .value(ZEITPUNKT, date)
                .value(WERT, entry.getValue());

我的选择看起来像

Select.Where select = QueryBuilder.select(WERT)
            .from(KEYSPACE_NAME,TABLENAME)
            .where(eq(ID, id))
            .and(eq(JAHR, zonedDateTime.getYear()))
            .and(eq(MONAT, zonedDateTime.getMonthValue()))
            .and(eq(ZEITPUNKT, Date.from(instant)));

一致性级别为 QUORUM(两者)和复制因子 3

最佳答案

我想说这似乎是时间戳问题,因为截断可以解决问题。在 Cassandra 中,最后一次写入获胜,这可能是由于使用 System.nanoTime() 造成的问题

This method can only be used to measure elapsed time and is not related to any other notion of system or wall-clock time.

...

The values returned by this method become meaningful only when the difference between two such values, obtained within the same instance of a Java virtual machine, is computed.

http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#nanoTime()

这意味着与重新启动后的写入相比,重新启动之前发生的写入可能“在将来”执行。这不会使查询失败,但由于存在可用的“更新”值,因此写入的值根本不可见。

您是否要求对插入时间戳使用亚毫秒精度?如果可能的话,我建议使用 System.currentTimeMillis() 而不是 nanoTime()。

http://docs.oracle.com/javase/7/docs/api/java/lang/System.html#currentTimeMillis()

如果您需要使用亚毫秒精度,则可以将 System.currentTimeMillis() 与某种范围在 0-999 之间的原子计数器一起使用,然后将其用作时间戳。然而,如果多个客户端同时插入同一行,这就会中断。

关于Cassandra - 写入不会失败,但不会插入值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31612199/

相关文章:

java - Cassandra 数据库。 com.datastax.driver.core.exceptions.InvalidQueryException : unconfigured table person

node.js - Cassandra:操作超时

java - Cassandra java 查询性能 count(*) 或 all().size()

python - 多节点 Cassandra 集群和不一致的客户端读取请求

java - 在 Java 中使用 apache Spark 查询 cassandra 时速度很慢。

hadoop - 数据库基准测试 : Cassandra vs. BigTable 与 Hadoop(s)

hadoop - 使用 cassandra 和 pig 进行数据清理

Cassandra 时间序列排序

java - cassandra中varchar/文本的最大长度

cassandra - 哪个版本的 Astyanax 与 Cassandra 2.0.1 兼容,或者哪些其他 Java 驱动程序与 Cassandra 2.0.1 兼容