Cassandra的滑动窗TTL

时间:2017-03-10 18:34:12

标签: cassandra cql3

我正在调查Cassandra的潜在即将到来的项目,我认为它可能非常适合。它让我感到困惑的一个潜在地方是数据保留的要求。基本上我们有这样的架构:

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)
)

在关系数据库术语中,我会说Thing属于一个用户,而Thing有很多Subthings。

Thing有各种与之相关的子事件,它们会在以后出现,它会依次更新相应的静态字段。我们需要在最后一次为该事物插入子物品后存储每件物品30天。例如,插入Thing A和Thing B.一周之后插入了物品B的子物品。在初次插入后30天删除事物A.事物B(以及所有相关的子事件)将在7天后删除。

据我所知,我不能只使用TTL插入,因为我需要更新共享相同user_id和thing_id的其他Thing行的TTL。我也不完全确定如何在这里运行DELETE命令,因为我没有删除任何键。我认为主键在这里是正确的,因为所有查询都将基于user_id(除了由updated_at确定的删除)。

我的另一个问题是墓碑的想法。我只读过它们,但这里的问题是我每天都会删除数以百万计的这些东西。在每日删除后,是否需要每日压缩?

更新 我想到的另一种选择,因为原始帖子有一个第二个表,每次添加一个子项时都会插入该表。它看起来像是:

CREATE TABLE  Expirations (
  expiry date
  user_id int
  thing_id int
  PRIMARY KEY (expiry, user_id, thing_id)
)

其中,expiry是要删除的给定user_id和thing_id的日期。这个表必须根据需要进行更新,因为事物被插入到Things表中,然后我必须每天运行一些东西来查询今天到期的值并迭代它们以从Things表中删除东西。我不确定这是否被认为是" Cassandra方式"但它似乎可以奏效。

1 个答案:

答案 0 :(得分:1)

这是一项有趣的挑战。我会使用map data type将每个thing_id映射到其所有subthing_id。我会去寻找类似的东西:

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)

在这里,我插入了一个新字段insertion_date,它应该完全包含插入日期,以及一个新字段partition_date,它将成为新的唯一PARTITION KEY,应该存储{{1}的截断}字段,只是为了避免一些热点(我假设可以根据你的TTL要求简单地根据日期字段进行查询,如果你需要查询insertion_date字段,那么事情会有所不同)。我最近回答了有关此建模问题herehere的类似问题,因此请查看这些问题以获取有关所用技术的更多信息(它称为 bucketing )。

然后是user_id,这是您问题的核心。在地图中推送新对象应该完全重置该地图的TTL,这样可以准确地提供所需的行为。请注意,TTL将仅删除字段,而不是整行,您只需要测试它是否为空。

最后,墓碑行为是你不得不面对的问题。如果您能够负担得起完整的行重写,那么您不必仅更新thing_map字段,而是立即在所有行中进行删除,并在分区级别获得删除,以及&#34;反向时间序列& #34;我使用群集密钥进行建模时应该注意这一点,而不会出现太多问题。