我的传感器频繁地将数据写入日志文件。我想将这些日志存储到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)
如何在数据中包含重复的时间戳?
还是有其他(更好)的选择吗?
由于
答案 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时间戳只是递增一定量的纳秒,以便在重叠的情况下创建一个新的唯一时间戳,因此值将始终单调增加。