在 Cassandra 中使用 TTL 和 Delete 哪个更好?

Which one is better to use TTL or Delete in Cassandra?

我想在特定时间后从 Cassandra 集群中删除记录。 那么我应该使用TTL还是手动删除呢?

让记录根据 TTL 过期更好。使用基于 TTL 的删除,您可以将 gc_grace_seconds 设置为更低的值(1 天或两天),并且您不必担心逻辑删除会持续更长时间。

使用手动删除,您需要确保墓碑不会增加到超过警告和错误阈值,因为它会影响查询。

答案是"it depends"。在 cassandra 中删除数据从来都不是免费的。

如果您必须 "DELETE",您需要始终发出这些查询,使用 TTL,它从您写入数据的那一刻起就完成了。但是通过使用 DELETE,您可以更好地控制数据删除。

在操作方面,你应该尝试让你的墓碑在同一个 sstable 中,所以一旦 gc_grace 过期,完整的 sstable 就可以被删除。因为只有当 sstables 被压缩时数据才会被真正删除,即使 gc_grace 已经过去,并且 sstable 持有墓碑时没有发生压缩,墓碑将不会从硬盘中删除。这也为您的 table.

选择压缩策略。

如果您还使用了很多墓碑,则应始终启用:"unchecked_tombstone_compaction" 在 table 级别。您可以在此处阅读更多相关信息:https://docs.datastax.com/en/cql/3.1/cql/cql_reference/compactSubprop.html

这取决于您的数据模型。幸运的答案是,由于它们的预测table 性质,您可以 构建您的数据模型以适应 TTL。

例如,

假设我构建了以下 table 来跟踪用户对 REST 服务的请求。假设我真的只关心上周的数据价值,那么我将 TTL 设置为 604800 秒(7 天)。所以我需要支持的查询基本上是这样的(查询用户 'Bob' 前 7 天的交易):

SELECT * FROM rest_transactions_by_user 
  WHERE username='Bob' AND transaction_time > '2018-05-28 13:41';

为了支持该查询,我将构建此 table:

CREATE TABLE rest_transactions_by_user (
  username TEXT,
  transaction_time TIMESTAMP,
  service_name TEXT,
  HTTP_result BIGINT,
  PRIMARY KEY (username,transaction_time))
  WITH CLUSTERING ORDER BY (transaction_time DESC)
  AND gc_grace_seconds = 864000      
  AND default_time_to_live = 604800;

注意几点:

  • 我将 gc_grace_seconds 设为默认值 864000(十天)。这将确保 TTL 墓碑将有足够的时间在整个集群中传播。
  • 行将在 7 天后 TTL(如上所述)。之后,他们将成为额外的 10 天的墓碑。
  • 我按 transaction_time 降序排列。这将我关心的行(没有 TTL 的行)放在我的分区的 "top" 中(顺序)。
  • 通过查询前 7 天的 transaction_time,我忽略了比这更早的任何内容。由于我的 TTL 墓碑将在之后存在 10 天,因此它们将位于我分区的 "bottom"。

这样,将我的查询限制在过去 7 天可确保 Cassandra 永远不会 必须处理墓碑,as我的查询永远找不到它们。所以在这种情况下,我 已经 构建了一个数据模型,其中 TTL "better" 而不是随机删除。