减少cassandra墓碑



我有一个表来存储处理失败的消息,我每5分钟通过调度程序重新处理一次消息。

当消息被成功处理时,表中相应的行被删除,因此相同的消息不应该再次被处理。

从表查询中获取行是SELECT * FROM <table_name>,因此如果大量的行被删除,我们将面临墓碑问题。表使用时间戳作为分区键,message_name(TEXT)作为集群键,TTL为7天,gc_grace_second为2天

根据我的要求,我需要删除记录,否则重复的记录将被处理。有什么办法可以避免墓碑问题吗?

我看到了两个问题。

  1. Cassandra被用作排队机制,这是一种已建立的反模式。
  2. 所有分区都用SELECT * FROM <table_name>查询,因为没有WHERE子句

所以在Cassandra中,一些数据模型和用例生成墓碑。此时,除了设计数据模型使不查询它们之外,没有太多要做的事情。

所以我的想法是用不同的方式划分表。

CREATE TABLE messages (
day TEXT,
message_time TIMESTAMP,
message_text TEXT,
PRIMARY KEY ((day),message_time))
WITH CLUSTERING ORDER BY (message_time DESC);

使用此模型,您可以查询特定day的所有消息。还可以在daymessage_time上运行范围查询。例:

SELECT * FROM messages
WHERE day='20210827'
AND message_time > '2021-08-27 04:00';

这将构建自2021-08-27 04:00以来所有消息的结果集。在请求的时间范围之外(在本例中为04:00之前)生成的任何墓碑都不会被查询。

注意(基于删除模式)在给定的时间范围内仍然可以有墓碑。但这里的想法是,WHERE条款限制了"爆炸半径",因此,查询较少数量的墓碑应该不是问题。

不幸的是,没有快速解决您的问题的方法。

你面临的挑战是,你正在使用Cassandra作为队列,这不是一个好主意,因为你正好进入了墓碑地狱。我相信你现在已经看到了这篇关于队列和类队列数据集是Cassandra的反模式的博客文章。

如果您在桶中对数据进行不同的建模,每个桶映射到一个表,则可以避免生成大量的墓碑。当您处理完bucket中的所有项后,TRUNCATE表。这个想法来自Ryan Svihla在他的博客文章"理解删除"中,他在其中介绍了"分区表"的概念。干杯!

相关内容

  • 没有找到相关文章

最新更新