Cassandra - 写入不会失败,但不会插入值
Cassandra - Write doesn't fail, but values aren't inserted
我有一个由 3 个 Cassandra 2.0 节点组成的集群。我的应用程序我写了一个测试,试图写入和读取一些数据 into/from Cassandra。一般来说,这工作正常。
奇怪的是,在我重新启动计算机后,这个测试会失败,因为在写入之后我读取了我之前写入的相同值并且在那里我得到了 null 而不是值,但是写入时也不例外.
如果我手动截断使用的列族,测试将通过。之后我可以按我想要的频率执行这个测试,它一次又一次地通过。此外,Cassandra 中是否有值并不重要。结果总是一样的。
如果我查看 CLI 和 CQL-shell 有两种不同的观点:
有人知道哪里出了问题吗?重新执行后,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长得像
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)));
Consistencylevel 是 QUORUM(对于两者)和 replicationfactor 3
我想说这似乎是时间戳的问题,因为截断解决了这个问题。在 Cassandra 中,最后一次写入获胜,这可能是由于使用 System.nanoTime() since
引起的问题
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 之间的原子计数器一起使用,然后将其用作时间戳。但是,如果多个客户端同时插入同一行,这将中断。
我有一个由 3 个 Cassandra 2.0 节点组成的集群。我的应用程序我写了一个测试,试图写入和读取一些数据 into/from Cassandra。一般来说,这工作正常。
奇怪的是,在我重新启动计算机后,这个测试会失败,因为在写入之后我读取了我之前写入的相同值并且在那里我得到了 null 而不是值,但是写入时也不例外. 如果我手动截断使用的列族,测试将通过。之后我可以按我想要的频率执行这个测试,它一次又一次地通过。此外,Cassandra 中是否有值并不重要。结果总是一样的。
如果我查看 CLI 和 CQL-shell 有两种不同的观点:
有人知道哪里出了问题吗?重新执行后,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长得像
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)));
Consistencylevel 是 QUORUM(对于两者)和 replicationfactor 3
我想说这似乎是时间戳的问题,因为截断解决了这个问题。在 Cassandra 中,最后一次写入获胜,这可能是由于使用 System.nanoTime() since
引起的问题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 之间的原子计数器一起使用,然后将其用作时间戳。但是,如果多个客户端同时插入同一行,这将中断。