确保在 10 分钟后删除以前版本的单元格

Ensure previous version of a cell is removed after 10 minutes

在 Cassandra 中,我想更新一行以在处理完该行后删除一些敏感数据。 一行有以下过程。

  1. 插入记录
  2. 处理记录(更新它)
  3. 设置要处理的行并从该行的一列中删除敏感数据

我知道更新实际上并不是按照 Cassandra 的设计更新磁盘上的数据。但是,我想确保在不太长的时间后数据实际上从磁盘中删除。 table 没有明确地(使用 CQL 语句)仅插入和更新语句删除任何行。

据我了解,我必须使用相对较短的 gc_grace_period,例如 10 分钟。

你能告诉我这个配置是否可行吗?这样的策略有什么影响?

我正在使用 Cassandra 3.11.1,table 的 TTL 为一天。 table.

每天插入大约 100k 到 1M 条记录

让我回答这个由两部分组成的问题:-

gc_grace_seconds 是 Cassandra 在清理具有墓碑数据的 SSTables 之前必须等待的时间(由 TTL/Deletes 引起)。因此,在您的情况下,table 的 TTL 为 1 天,默认情况下 gc_grace_seconds 为 864000(秒)= 10 天。这意味着一天内过期的数据会再等待 10 天(默认情况下)才能被清理。

默认 gc_grace_seconds 高的原因是为了确保在显式删除期间,如果集群中的任何节点关闭,删除(逻辑删除)会在节点恢复时传播。换句话说就是避免僵尸数据。

在你的情况下,因为没有任何明确的删除,只有墓碑,所以为 gc_grace_seconds 设置一个较小的值是安全的,比如 90000(25 小时)。

另一个风险更高的选项是将 gc_grace_seconds 设置为零,前提是保证应用程序永远不会进行显式删除并仅依赖 TTL。将其设置为零具有系统中没有墓碑的优点。数据在其 TTLed

后立即被清除

问题的第二部分:

为了在处理后 10 分钟内使列过期,我们可以按如下方式设置列级 TTL。下面我建议使用更短的 gc_grace_seconds 和 TWCS,这将有助于在 10 + 1 分钟内驱逐这一行并且不会造成墓碑压力。

更新 CQL 以设置列级 TTL

UPDATE test USING TTL 600 
  SET status = 'PROCESSED' 
  WHERE primary_key = ? ;

此外,关于table压缩策略:-

我假设这些行是按顺序处理的(或者换句话说,这个 table 被视为一个队列)。处理这种情况的更简洁的方法是使用 "Time Window Compaction Strategy"。一般建议TimeWindow slice的个数不要超过50个。

命令是

CREATE TABLE test (
........
) WITH 
    AND gc_grace_seconds = 60
    AND default_time_to_live = 86400
    AND compaction = {'compaction_window_size': '30', 
                      'compaction_window_unit': 'MINUTES', 
                      'class': 'org.apache.cassandra.db.compaction.TimeWindowCompactionStrategy'}

此设置将为我们提供以下保证:

  • 超过 30 分钟的数据将停止压缩,从而降低 I/O 消耗。以 30 分钟时间范围内的行为目标的查询将主要命中有限数量的 SSTable,以防压缩是最新的
  • 使用 TTL 插入,逻辑删除通过文件删除被清除(在这种情况下,在原始写入后 1 天 1 分钟后不久)
  • 通过提示或修复从原始时间 window 发送的数据仅使用当前 window 的 SSTables 进行压缩,防止写入放大
  • 磁盘上的最大压缩开销是最后创建的存储桶的 50%
  • 磁盘 space 使用增长很容易预测table

关于 TWCS 的精彩阅读。