Jul*_*lia 5 cql cassandra cassandra-cli datastax-java-driver cassandra-2.0
我有一个由 3 个 Cassandra 2.0 节点组成的集群。我的应用程序编写了一个测试,尝试将一些数据写入 Cassandra 或从 Cassandra 读取一些数据。一般来说,这工作得很好。
\n\n好奇的是,在我重新启动计算机后,此测试将失败,因为写入后我读取了之前写入的相同值,并且我得到的是 null 而不是该值,但写入时也不例外。\n如果我手动截断使用的列族,测试将通过。之后我可以按照我想要的频率执行这个测试,它一次又一次地通过。此外,Cassandra 中是否有值并不重要。结果总是一样的。
\n\n如果我查看 CLI 和 CQL-shell,会发现两种不同的视图:
\n\n\n\n\n\n有谁知道出了什么问题吗?CLI中的时间戳在重新执行后更新,所以这似乎是一个读取问题?
\n\n我的代码的一部分:\n对于我尝试过的插入
\n\nInsert.Options insert = QueryBuilder.insertInto(KEYSPACE_NAME,TABLENAME)\n .value(ID, id)\n .value(JAHR, zonedDateTime.getYear())\n .value(MONAT, zonedDateTime.getMonthValue())\n .value(ZEITPUNKT, date)\n .value(WERT, entry.getValue())\n .using(timestamp(System.nanoTime() / 1000));\nRun Code Online (Sandbox Code Playgroud)\n\n和
\n\nInsert insert = QueryBuilder.insertInto(KEYSPACE_NAME,TABLENAME)\n .value(ID, id)\n .value(JAHR, zonedDateTime.getYear())\n .value(MONAT, zonedDateTime.getMonthValue())\n .value(ZEITPUNKT, date)\n .value(WERT, entry.getValue());\nRun Code Online (Sandbox Code Playgroud)\n\n我的选择看起来像
\n\nSelect.Where select = QueryBuilder.select(WERT)\n .from(KEYSPACE_NAME,TABLENAME)\n .where(eq(ID, id))\n .and(eq(JAHR, zonedDateTime.getYear()))\n .and(eq(MONAT, zonedDateTime.getMonthValue()))\n .and(eq(ZEITPUNKT, Date.from(instant)));\nRun Code Online (Sandbox Code Playgroud)\n\n一致性级别为 QUORUM(两者均适用)和复制因子 3
\n小智 5
我想说这似乎是时间戳问题,因为截断解决了问题。在 Cassandra 中,最后一次写入获胜,这可能是由于使用 System.nanoTime() 引起的问题,因为
此方法只能用于测量经过的时间,与系统或挂钟时间的任何其他概念无关。
...
仅当计算在同一 Java 虚拟机实例中获得的两个此类值之间的差异时,此方法返回的值才有意义。
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 之间的原子计数器一起使用,然后将其用作时间戳。然而,如果多个客户端同时插入同一行,这就会中断。
| 归档时间: |
|
| 查看次数: |
3872 次 |
| 最近记录: |