scylla - 从scylla中选择时如何保证timeuuid单调递增
问题描述
我有一个以 timeuuid 作为集群键的表。
CREATE TABLE event (
domain TEXT,
createdAt TIMEUUID,
kind TEXT,
PRIMARY KEY (domain, createdAt)
);
我希望按此集群键的顺序选择数据,并提供以下保证 - 如果我选择了某些内容,将来这些记录之前将不会有任何插入(因此我可以遍历记录检查发生的新情况,而不会有跳过任何内容的风险事件)
SELECT kind FROM event WHERE domain = ? AND createdAt > lastCreatedAtWeAreAwareOf
如果我在客户端上生成 timeuuid 并使用并行插入到 scylla,那么从技术上讲,最近的 timeuuid 可能会在几个较旧的之前被首先插入(比如由于说一些网络问题),我可能会在我的选择中错过这些记录。
有什么可能的方法来解决这个问题?
我尝试使用currentTimeUUID
函数,它似乎可以工作(在同一个分区键内单调增加)但会创建很多重复项(每个分区键有 20-40 个重复项),即我最终得到了很多完全相同的记录currentTimeUUID
(我真的想要一种避免重复的方法,它会使选择过程复杂化并消耗不必要的资源)
我也很好奇使用currentTimeUUID
函数时是否存在向后时钟跳跃的威胁?
解决方案
已编辑
似乎 Scylla 中存在一个错误,即 currentTimeUUID 总是为使用相同的协调器同时完成的写入生成重复项。我在这里创建了一个问题。感谢您提出这个问题。
下面是以前的答案
如果我在客户端上生成 timeuuid 并使用并行插入到 scylla,那么从技术上讲,最近的 timeuuid 可能会在几个较旧的之前被首先插入(比如由于说一些网络问题),我可能会在我的选择中错过这些记录。
澄清一下,所有写入都将以正确的顺序存储。在某个时间点,您将能够以正确的顺序读取足够旧的写入。这意味着一种可能的解决方案是确保 select 不会查询最近的数据。因此,为“迟到”的写入留出一个窗口,让它们到达并排好队。例如,您可以使用这样的选择:
SELECT kind FROM event WHERE domain = ? AND createdAt > lastCreatedAtWeAreAwareOf AND createdAt < now() - 30s
不过,我不知道您是否可以施加这种延迟。这个策略不会给你一个完全的确定性,因为所有延迟超过 30 秒的写入都将被遗漏。
我尝试使用 currentTimeUUID 函数,它似乎可以工作(在同一个分区键内单调增加)但会创建很多重复项(每个分区键有 20-40 个重复项),即我最终得到了很多具有完全相同 currentTimeUUID 的记录(我真的很想要一种避免重复的方法,它会使选择过程复杂化并消耗不必要的资源)
您可以通过引入额外的集群键列来减少集群键重复的机会,例如:
CREATE TABLE event (
domain TEXT,
createdAt TIMEUUID,
randomBit UUID/int,
kind TEXT,
PRIMARY KEY (domain, createdAt, randomBit)
);
并以某种好的随机方式在客户端上为其生成价值。也许您知道记录的某些方面保证是唯一的并且可以用作集群键列。它会比随机场更好。
推荐阅读
- c# - 在 .NET 5 中排除新的 System.Range
- python - Python条件语句逻辑
- flutter - 这种图像布局样式指的是什么?用flutter可以轻松实现吗?
- c# - MSIX WPF - 等效的 Package.InstalledLocation
- linux - 在 Linux 中使用 cmakelists 文件链接 mongocxx
- eclipse - Eclipse:不兼容的JVM:1.8.0_281 版的JVM 不适合这个产品。版本:需要 11 或更高版本
- excel - 如何使用元素周期表对化合物求和(化学课)
- python - 后台多线程 Python 应用程序
- python - 访问假定字典中的嵌套数据
- amazon-web-services - 使用 BatchWriteItemEnhancedRequest Dynamodb JAVA SDK 2 写入超过 25 个项目