【问题标题】:Cassandra : TTL vs dynamic tables vs large amount of deletesCassandra:TTL vs 动态表 vs 大量删除
【发布时间】:2021-10-07 17:09:46
【问题描述】:

我基本上有一个像这样的data 表(一个分区id,以及一个序列化值serialized_value):

CREATE TABLE keyspace.data (
    id bigint,
    serialized_value blob,
    PRIMARY KEY (id)
) WITH caching = {'keys': 'ALL', 'rows_per_partition': 'NONE'}
  AND compaction = {'class': 'org.apache.cassandra.db.compaction.LeveledCompactionStrategy', 'enabled': 'true'}
    AND compression = { 'class' : 'LZ4Compressor'};

用例涉及维护数据的多个版本(serialized_value 用于给定的id)。

每天,我都必须向 Cassandra 发送一个新版本的数据。每次涉及 1 亿行/分区。

当然,我不需要维护所有版本的数据,只需要最近 4 天(所以最近的四个version_id)。

我确定了三种解决方案:

解决方案 1:TTL

这个想法是在插入时设置一个 TTL。这样,最旧版本的数据会被自动删除,而不会出现与 thombstone 相关的问题。

优点:

  • 没有读取性能损失 (?)
  • 没有与墓碑相关的问题

缺点:

  • 如果几天摄取失败,我可能会因为 TTL 自动删除而丢失 Cassandra 集群中的所有数据

解决方案 2:动态表格

表创建变为:

CREATE TABLE keyspace.data_{version_id} (
    id bigint,
    serialized_value blob,
    PRIMARY KEY (id)
) ...;

表名包含version_id

优点:

  • 表格(对应一个版本)很容易删除
  • 没有读取性能损失
  • 没有与墓碑相关的问题

缺点:

  • 向集群动态添加表可能需要每次都启动所有节点。
  • 有点难处理客户端(查询特定的表名,而不是同一个)

解决方案 3:大量删除

在这种情况下,所有数据都保留在一个表中,并且将version_id 添加到主键中。

CREATE TABLE keyspace.data (
    version_id int,
    id bigint,
    serialized_value blob,
    PRIMARY KEY ((version_id,id))
) ...;

优点:

  • 在整个应用程序生命周期中只需创建和维护一个表

缺点:

  • 可能会因大量 thombstone 而导致读取性能下降
  • thombstones相关问题,因为需要删除大量数据,以清除所有与旧version_id相关的数据。

删除将只匹配确切的分区键,因此它将生成partition thombstones 而不是cell thombstones。但因此,我害怕这样做的表现..

实现这一目标的最佳方法是什么? :-)

【问题讨论】:

    标签: cassandra datastax datastax-enterprise


    【解决方案1】:

    最好根据日期或时间戳对数据进行聚类,以相反的顺序排序,并且仍然设置 TTL。例如:

    CREATE TABLE ks.blobs_by_id (
        id bigint,
        version timestamp,
        serialized_value blob,
        PRIMARY KEY (id, version)
    ) WITH CLUSTERING ORDER BY (version DESC)
    

    如果您在表上有默认 TTL,旧版本将自动过期,因此当您检索行时:

    SELECT ... FROM blobs_by_id WHERE id = ? LIMIT 4
    

    只会返回最近的 4 行(按降序排列),您不会遍历已删除的行。干杯!

    【讨论】:

    • 嗨,埃里克。谢谢。但是,我不确定是否理解。在您的示例中,version 是一个集群键。但是,在我的用例中,数据将始终由特定版本和特定 id 访问(根本没有迭代/范围)。所以最好有 PRIMARY KEY ((id, version)) 而不是 PRIMARY KEY (id, version) 这涉及集群,不是吗?
    • 无论如何,您都可以根据 TTL 选择解决方案 1。但是,它会涉及很多 thombstone,因为与特定 version 相关的所有数据都会立即过期。在此 SO 帖子 (stackoverflow.com/a/42862816/10098090) 中,作者明确表示:因此使用 TTL 删除太多条目被视为反模式。你同意吗 ? 因为我的情况完全一样..
    • 之前引用的作者还补充说:建议使用临时表,这样就不需要删除个别行。只需删除整个表格。。这对我来说似乎是个好主意(最终选择解决方案2)。但是,我看到其他帖子 (stackoverflow.com/a/60510145/10098090) 说 在 Cassandra 中不断创建和删除表的数量不是一个好习惯,并且不推荐
    猜你喜欢
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    • 1970-01-01
    • 2018-01-22
    • 2015-02-12
    • 1970-01-01
    • 2018-03-31
    • 2018-03-16
    相关资源
    最近更新 更多