清除Cassandra DB

时间:2018-02-07 09:49:36

标签: cassandra cassandra-3.0

我们根据类别将事件存储在多个表中。 每个事件都有一个id,但包含多个子元素。 我们有一个查找表来使用subelement_id查找事件。 每个子元素最多可参加7个活动。 因此分区最多可容纳7行。 在5年的时间里,我们将在eventlookup中拥有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 eventlookup YYYY ”。不需要一年一次,只需放下它。 (问题是每次读取都应该查询所有表)

我们可以考虑其他方法吗?

我们现在可以制定一项设计决策(我们尚未投入生产),这将减轻未来的问题吗?

2 个答案:

答案 0 :(得分:1)

如果值得花费额外的空间,请在单独的表/列中查找recordtimes subelement_id date的范围。

如果您不想先设置ttl,那么您可以轻松地删除具有特定年龄的记录的ID。

但请记住,要使此跟踪分发得很好,只需一个(date,chunk)就可以在群集和非常宽的行中生成热点,所以请考虑一些分区键,例如chunk我随机使用的subelement_id过去0-10的数字。您也可以查看TimeWindowCompactionStrategy - 这是一篇关于它的博客文章:http://thelastpickle.com/blog/2016/12/08/TWCS-part1.html

您的分区键仅设置为table 2 4 6 ,因此所有记录时间的7个事件的所有元组都将位于一个分区中。

答案 1 :(得分: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 *将检索您的数据,并将停止扫描您想要的分区:5年前。最重要的是,如果你在那之后有了墓碑,那么它们根本不会影响你的阅读。这意味着你可以安全地"通过发布删除

安全地修剪该点
WHERE subelement_id = 'mysub_id' AND recordtime < '2013-01-01';

请注意,此删除将创建将被您的读取跳过的逻辑删除,但是它们将在压缩期间被读取,因此请记住。

或者,如果您不需要回收存储空间,则可以跳过删除部分,系统将始终流畅运行,因为您始终可以有效地检索数据。