Cassandra - 使用 TimeUUID 重复时间戳?
Cassandra - duplicate timestamps with TimeUUID?
我的传感器经常将数据写入日志文件。我想将这些日志存储到 Cassandra 中,并与 Spark 一起处理它们。
我考虑过使用 TimeUUID 列来存储我的时间戳以自动保留顺序。我的查询将大量使用范围查询,因此我认为这可能是理想的。但是,由于日志记录的频率,我的日志 可以 包含重复的时间戳。日志不会流式传输到 cassandra;我只处理历史数据。时间戳将成为我的复合主键的一部分。我想不出一个可行的列,我可以将其拉入行键以使具有重复时间戳的行唯一。
documentation 说:"The values returned by minTimeuuid and maxTimeuuid functions are not true UUIDs in that the values do not conform to the Time-Based UUID generation process specified by the RFC 4122. The results of these functions are deterministic, unlike the now function."
当强制使用 TimeUUID 的日期而不是使用 now
时,这可能最终会覆盖以前的数据。
我将使用 Java/Scala 将我的历史数据从 .json 批量插入到 Cassandra。 (Cassandra 3.0.8 | CQL 规范 3.4.0 | 本机协议 v4)
如何在我的数据中包含重复的时间戳?
- 我是否使用 TimeUUID(now) 作为我的主键并将实际的 date/time 存储在不同的列中?这会让我失去已经订购实际 date/time 的好处。
- 我是否必须确保我的 Java/Scala 应用程序将生成有效、唯一的 TimeUUID?如果是这样,我可以使用任何通用库吗?
或者还有其他(更好的)选择吗?
谢谢
首先,请确保您对如何订购和查询数据的想法确实可以使用 Cassandra 实现。范围查询将仅基于特定的分区键工作,例如PRIMARY KEY(sensor_id, time)
。在大多数情况下,通过分区键进行区分足以确保时间戳是唯一的。
如果您仍然需要生成全球唯一的基于时间的 UUID,那也应该可行,因为您将要导入历史数据并且可以只实现一个共享的 UUID 生成器,该生成器将通过跟踪最后创建的时间戳,并仅增加一定的纳秒数以在重叠的情况下创建新的唯一时间戳,因此值将始终单调增加。
您使用 timeuuid 作为唯一标识符的想法是正确的方法。正确完成后,您将不会有重复项。 timeuuid 是一个 type 1 uuid,它不仅包含 时间戳,还包含一些熵以保证即使在同一时间点也是唯一的。
那么,现在问题仍然存在——您应该如何为您的历史数据生成 timeuuid?如您所述,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。一定要选择保证唯一性的优质库。
我的传感器经常将数据写入日志文件。我想将这些日志存储到 Cassandra 中,并与 Spark 一起处理它们。
我考虑过使用 TimeUUID 列来存储我的时间戳以自动保留顺序。我的查询将大量使用范围查询,因此我认为这可能是理想的。但是,由于日志记录的频率,我的日志 可以 包含重复的时间戳。日志不会流式传输到 cassandra;我只处理历史数据。时间戳将成为我的复合主键的一部分。我想不出一个可行的列,我可以将其拉入行键以使具有重复时间戳的行唯一。
documentation 说:"The values returned by minTimeuuid and maxTimeuuid functions are not true UUIDs in that the values do not conform to the Time-Based UUID generation process specified by the RFC 4122. The results of these functions are deterministic, unlike the now function."
当强制使用 TimeUUID 的日期而不是使用 now
时,这可能最终会覆盖以前的数据。
我将使用 Java/Scala 将我的历史数据从 .json 批量插入到 Cassandra。 (Cassandra 3.0.8 | CQL 规范 3.4.0 | 本机协议 v4)
如何在我的数据中包含重复的时间戳?
- 我是否使用 TimeUUID(now) 作为我的主键并将实际的 date/time 存储在不同的列中?这会让我失去已经订购实际 date/time 的好处。
- 我是否必须确保我的 Java/Scala 应用程序将生成有效、唯一的 TimeUUID?如果是这样,我可以使用任何通用库吗?
或者还有其他(更好的)选择吗?
谢谢
首先,请确保您对如何订购和查询数据的想法确实可以使用 Cassandra 实现。范围查询将仅基于特定的分区键工作,例如PRIMARY KEY(sensor_id, time)
。在大多数情况下,通过分区键进行区分足以确保时间戳是唯一的。
如果您仍然需要生成全球唯一的基于时间的 UUID,那也应该可行,因为您将要导入历史数据并且可以只实现一个共享的 UUID 生成器,该生成器将通过跟踪最后创建的时间戳,并仅增加一定的纳秒数以在重叠的情况下创建新的唯一时间戳,因此值将始终单调增加。
您使用 timeuuid 作为唯一标识符的想法是正确的方法。正确完成后,您将不会有重复项。 timeuuid 是一个 type 1 uuid,它不仅包含 时间戳,还包含一些熵以保证即使在同一时间点也是唯一的。
那么,现在问题仍然存在——您应该如何为您的历史数据生成 timeuuid?如您所述,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。一定要选择保证唯一性的优质库。