清除Cassandra DB的旧数据策略

vsnjm48y  于 2023-08-04  发布在  Cassandra
关注(0)|答案(3)|浏览(180)

我们根据类别将事件存储在多个表中。每个事件都有一个id,但包含多个子元素。我们有一个查找表来使用subelement_id查找事件。每个子元素最多可以参与7个事件。因此,分区将最多容纳7行。在5年的时间里,我们将有30-50亿行的事件查找。

CREATE TABLE eventlookup (
    subelement_id text,
    recordtime timeuuid,
    event_id text,
    PRIMARY KEY ((subelement_id), recordtime)
)

字符串
问题:一旦达到5年(或其他数字)标记,我们如何删除旧数据。我们希望在某些特定的时间间隔清除“尾巴”,比如每周或每月。
迄今为止研究的方法:

  • X年的TTL(性能良好,但TTL需要事先知道,每列8个额外字节)
  • 不删除-简单地忽略问题(其他人的问题:0)
  • 速率受限的单行删除(执行完整的表扫描和可能的数十亿条删除语句)
  • 将表拆分为多个表->“CREATE TABLE eventlookupYYYY"。一年一次是不需要的,简单地放弃它。(问题是每次读取都可能查询所有表)

有没有其他方法可以考虑?
我们现在(还没有投入生产)是否可以做出一个设计决策来缓解未来的问题?

wgx48brx

wgx48brx1#

如果需要额外的空间,可以在单独的表/列家族中跟踪recordtimes的范围。
然后,如果您不想先验地设置ttl,则可以轻松地获得要删除的具有特定年龄的记录的id。
但是请记住,要使这种跟踪分布良好,只有一个date会在集群中生成热点和非常宽的行,所以考虑一些分区键,如(date,chunk),我在过去为chunk使用0-10的随机数。你也可以看看TimeWindowCompactionStrategy -这里有一篇关于它的博客文章:http://thelastpickle.com/blog/2016/12/08/TWCS-part1.html
您的分区键仅设置为subelement_id,因此所有记录时间的7个事件的所有元组将位于 one 分区中。

liwlm1x9

liwlm1x92#

给定你的表结构,你需要知道所有数据的subelement_id,才能获取一行。因此,根据这个假设,可以通过按recordtime DESC对数据进行排序来改进表结构:

CREATE TABLE eventlookup (
    subelement_id text,
    recordtime timeuuid,
    eventtype int,
    parentid text,
    partition bigint,
    event_id text,
    PRIMARY KEY ((subelement_id), recordtime)
)
WITH CLUSTERING ORDER BY (recordtime DESC);

字符串
现在你所有的数据都是降序排列的,这将给予你一个很大的优势。
假设你有多年的数据(例如2000年到2018年)。假设您只需要保留过去5年的数据,则需要通过以下方式获取数据:

SELECT * FROM eventlookup WHERE subelement_id = 'mysub_id' AND recordtime >= '2013-01-01';


此查询非常有效,因为C* 将检索您的数据,并将停止扫描您想要的分区:五年前。最大的好处是,如果你在那之后有墓碑,那么,它们根本不会影响你的阅读。这意味着您可以在该点之后“安全地”修剪安全地发出删除命令

WHERE subelement_id = 'mysub_id' AND recordtime < '2013-01-01';


请注意,此删除将创建墓碑,将跳过您的阅读,但他们将阅读压缩,所以请记住。
或者,如果您不需要回收存储空间,您可以简单地跳过删除部分,您的系统将始终平稳运行,因为您将始终有效地检索您的数据。

ahy6op9u

ahy6op9u3#

AND default_time_to_live = 157,680,000// 5年(秒)

相关问题