Cassandra - 使用TimeUUID复制时间戳?

时间:2016-07-20 07:40:14

标签: cassandra cql cql3

我的传感器频繁地将数据写入日志文件。我想将这些日志存储到Cassandra中并与Spark一起处理它们。

我考虑过使用TimeUUID列来存储我的时间戳以自动保存订单。我的查询将大量使用范围查询,因此我认为这可能是理想的。但是,由于日志记录的频率,我的日志可以包含重复的时间戳。日志没有流式传输到cassandra;我只处理历史数据。时间戳将是我的复合主键的一部分。我想不出一个可行的列,我可以将其拉入行键以使具有重复时间戳的行唯一。

documentation说:“minTimeuuid和maxTimeuuid函数返回的值不是真正的UUID,因为这些值不符合RFC 4122指定的基于时间的UUID生成过程。这些函数的结果与现在的功能不同,它们是确定性的。“

强制使用TimeUUID的日期时,而不是使用now,这可能最终会覆盖以前的数据。

我将使用Java / Scala将我的历史数据从.json批量插入到Cassandra。 (Cassandra 3.0.8 | CQL规范3.4.0 |本地协议v4)

如何在数据中包含重复的时间戳?

  1. 我是否将TimeUUID(现在)用于我的主键并将实际日期/时间存储在不同的列中?这将使我失去已经订购实际日期/时间的好处。
  2. 我是否必须确保我的Java / Scala应用程序将生成有效的,唯一的TimeUUID?如果是这样,我可以使用任何常见的库吗?
  3. 还是有其他(更好)的选择吗?

    由于

2 个答案:

答案 0 :(得分:3)

您使用timeuuids作为唯一标识符的想法是正确的方法。如果操作正确,您将不会有重复项。 timeuuid是type 1 uuid,其中不包含时间戳,还包含一些熵,以保证即使在同一时间点也能保持唯一性。

那么,现在问题仍然存在 - 您应该如何为历史数据生成时间表?如您所述,minTimeuuid / maxTimeuuid函数不适合生成正确的版本1 uuid。没关系,因为那不是他们的目的。当您使用时间范围查询数据时,稍后您将需要它们:

SELECT * FROM sensor_readings
   WHERE sensor_id = 123
   AND ts > maxTimeuuid('2016-07-15 00:00+0000')
   AND ts < minTimeuuid('2016-07-17 00:00+0000')

不幸的是,CQL没有提供为给定时间戳生成它们的函数(从CQL 3.3开始),因此您的客户端必须生成uuid。有一些Java库可以做到这一点。有关建议,请参阅this question。一定要选择一个保证唯一性的高质量库。

答案 1 :(得分:1)

首先,请确保您可以使用Cassandra了解如何订购和查询数据。范围查询仅基于某个分区键工作,例如PRIMARY KEY(sensor_id, time)。在大多数情况下,通过分区键进行区分足以确保时间戳是唯一的。

如果您仍然需要生成全局唯一的基于时间的UUID,那么这也应该是可能的,因为您要导入历史数据并且可以实现共享UUID生成器,该生成器将通过跟踪上次创建的内容来创建唯一的UUID时间戳只是递增一定量的纳秒,以便在重叠的情况下创建一个新的唯一时间戳,因此值将始终单调增加。