我们根据类别将事件存储在多个表中。每个事件都有一个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"。一年一次是不需要的,简单地放弃它。(问题是每次读取都可能查询所有表)
有没有其他方法可以考虑?
我们现在(还没有投入生产)是否可以做出一个设计决策来缓解未来的问题?
3条答案
按热度按时间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 分区中。liwlm1x92#
给定你的表结构,你需要知道所有数据的
subelement_id
,才能获取一行。因此,根据这个假设,可以通过按recordtime DESC
对数据进行排序来改进表结构:字符串
现在你所有的数据都是降序排列的,这将给予你一个很大的优势。
假设你有多年的数据(例如2000年到2018年)。假设您只需要保留过去5年的数据,则需要通过以下方式获取数据:
型
此查询非常有效,因为C* 将检索您的数据,并将停止扫描您想要的分区:五年前。最大的好处是,如果你在那之后有墓碑,那么,它们根本不会影响你的阅读。这意味着您可以在该点之后“安全地”修剪安全地发出删除命令
型
请注意,此删除将创建墓碑,将跳过您的阅读,但他们将阅读压缩,所以请记住。
或者,如果您不需要回收存储空间,您可以简单地跳过删除部分,您的系统将始终平稳运行,因为您将始终有效地检索您的数据。
ahy6op9u3#
AND default_time_to_live = 157,680,000// 5年(秒)