Cassandra 卡桑德拉滑动窗TTL
我正在寻找一个潜在的即将到来的项目,我认为它可能是一个很好的适合卡桑德拉。让我感到困惑的一个潜在地方是数据保留需求。基本上我们有这样一个模式:Cassandra 卡桑德拉滑动窗TTL,cassandra,cql3,Cassandra,Cql3,我正在寻找一个潜在的即将到来的项目,我认为它可能是一个很好的适合卡桑德拉。让我感到困惑的一个潜在地方是数据保留需求。基本上我们有这样一个模式: CREATE TABLE Things ( user_id int thing_id int a text static b text static .... more static fields updated_at timestamp static type text subthing_id int PRIM
CREATE TABLE Things (
user_id int
thing_id int
a text static
b text static
.... more static fields
updated_at timestamp static
type text
subthing_id int
PRIMARY KEY (user_id, thing_id, subthing_id)
)
在关系数据库术语中,我会说一个东西属于一个用户,一个东西有很多子东西
一个对象有各种与之相关联的子对象,这些子对象将在以后执行新的插入操作,从而更新相应的静态字段。我们需要在最后一次插入子项后,将每个内容存储30天。举个例子,物体A和物体B被插入。一周后,将插入B的子项。首次插入后30天内删除内容A。事物B(以及所有相关的子事物)在7天后被删除
据我所知,我不能只使用TTL插入,因为我需要更新共享相同用户id和对象id的其他对象行的TTL。我也不完全确定如何在这里运行DELETE命令,因为我没有使用任何键进行删除。我相信这里的主键是正确的,因为所有查询都将基于用户id(除了由更新的用户id确定的删除)
我的另一个担忧是墓碑的概念。我只读过关于它们的文章,但这里的担忧是,我每天可能会删除数百万个这样的东西。在执行每日删除后,是否需要每日压缩
更新:
从最初的帖子开始,我就想到了另一种选择,即在每次添加子项时插入第二个表。它看起来像:
CREATE TABLE Expirations (
expiry date
user_id int
thing_id int
PRIMARY KEY (expiry, user_id, thing_id)
)
其中expiry是要删除的给定用户id和对象id的日期。当东西被插入到东西表中时,这个表必须根据需要进行更新,然后我必须每天运行一些东西来查询今天到期的值,并对它们进行迭代以从东西表中删除东西。我不确定这是否被认为是“卡桑德拉方式”,但它似乎可以奏效。这是一个有趣的挑战。我将使用a将每个
对象id
映射到其所有子项id
s。我喜欢这样的东西:
CREATE TABLE Things (
partition_date timestamp,
insertion_date timestamp,
user_id int,
thing_map map<int,int>
a text static
b text static
.... more static fields
updated_at timestamp static
type text
PRIMARY KEY (partition_date, insertion_date, user_id)
) WITH CLUSTERING ORDER BY (insertion_date DESC)
创建表格内容(
分区日期时间戳,
插入日期时间戳,
用户id int,
地图
静态文本
b文本静态
……更多的静态场
时间戳静态时更新的_
键入文本
主键(分区日期、插入日期、用户id)
)使用聚类顺序(插入日期描述)
在这里,我插入了一个新字段insertion\u date
,该字段应准确保存插入日期,以及一个新字段partition\u date
,该字段将成为新的仅新建分区键,该字段应存储insertion\u date
字段的截断,以避免出现一些热点(我假设,由于您的TTL要求,如果您需要查询user\u id
字段,您可以简单地基于一个day字段进行查询,但情况有点不同)。我最近回答了有关此建模问题的类似问题,因此请查看这些问题,以获得有关所用技术的更多信息(称为bucketing)
然后,问题的核心是thing\u map
。在映射中推送一个新对象应该完全重置该映射的TTL,这样可以为您提供准确的所需行为。请注意,TTL将仅删除字段,而不是整行,您只需测试它是否为null
最后,墓碑行为是您必须面对的一个问题。如果您能够承受完整的行重写,那么您可以在分区级别删除所有行,而不是只更新
map
字段我已经用集群键建模了,应该不会有太多问题。谢谢你的回答!不过我有几个问题要问。所以我很确定如果每个查询都基于用户id,那么用户id必须是分区键。日期可以作为这些查询的一部分,但是可选的。唯一的时间是在查询中使用e date而不使用user_id来删除过期的内容。我想归根结底,最好是让delete命令或SELECT查询命中尽可能少的分区。我正在用另一个我认为也可行的选项更新原始问题…让我知道你的想法。@ShaneAndrade:你可以将日期
与用户id
放在一起,以便更好地划分数据。正如前面所说的,你可以在我发布的链接中找到如何做到这一点。另外请注意,如果你使用TTL
,那么数据将自动消失,因此你根本不需要执行任何选择/删除
es是另一个可行的选择,但您有TTL
。。。