Cassandra数据库的旧数据清理策略

4

我们根据类别将事件存储在多个表中。 每个事件都有一个ID,但包含多个子元素。 我们有一个查找表格,可以使用子元素ID查找事件。 每个子元素最多可以参与7个事件。 因此,分区最多将保存7行。 在5年的时间内,我们将拥有300-500亿行事件查找数据。

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”。一年一次不需要,直接删除即可。(问题是每次读取都可能要查询所有表)
还有其他方法可以考虑吗?
现在是否有设计决策(我们还没有投入生产)可以缓解未来的问题?

嗨@Mumi,你如何设置“X年的TTL”? - Yogesh Jilhawar
3个回答

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

0
AND default_time_to_live = 157,680,000 // 5年的秒数

0

根据您的表结构,为了获取单行数据,您需要知道所有数据的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';

请注意,此删除操作将创建墓碑,这些墓碑将被您的读取跳过,但它们将在压缩期间被读取,所以请记住这一点。

或者,如果您不需要回收存储空间,可以简单地跳过删除部分,因为系统始终会高效检索数据,因此系统将始终平稳运行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接