所以我知道由于设计原因,TTL 不适用于计数器,并且我已阅读 https://issues.apache.org/jira/browse/CASSANDRA-2103以及其他一些与此相关的问题,但似乎没有明确的答案(除非我遗漏了一些完全合理的东西):
我们如何优雅地处理 Cassandra 中计数器的过期问题?
示例用例:特定日期的页面浏览量。
为此,我们可能有一个表格,例如
创建表页面浏览量(页面 varchar、日期 varchar、浏览次数计数器、主键(页面、日期));
一年后,我们在某一特定日期有多少浏览量的信息并不是很相关(相反,我们可能会将其聚合到 View /月表或类似表中),并且我们不希望不必要的数据徘徊在我们的数据库无缘无故。通常我们会在上面设置一个 TTL,然后让 Cassandra 为我们处理——优雅!但由于我们不允许对计数器表使用 TTL,因此这不是一个选项。
您也不能只从 pageviews where date > 'xxxx' 运行删除,因为两个键都必须在 where 子句中定义。 您首先需要先查询所有页面,然后发出单独的删除,这是不可扩展的。 有没有适当的方法来实现这一目标?
最佳答案
它的明显速度较慢,但如果您不想自己管理过期时间,这就是代价 - 您可以使用 LWT 并实际插入 TTL 列而不是更新一个柜台。即:
CREATE TABLE pageviews (
page varchar,
date timestamp,
views int,
PRIMARY KEY(page, date))
WITH compaction = {'class': 'LeveledCompactionStrategy'};
要更新页面 View :
UPDATE pageviews USING TTL 604800
SET views = *12*
WHERE page = '/home' AND date = YYYY-MM-DD
IF views = *11*
如果失败,请重新阅读并重试。如果竞争激烈,这可能会非常慢,但在这种情况下,您可以对每个应用程序进行一些批处理,例如每 10 秒或某事只刷新一次更新,并一次增加超过 1
要查看日期范围内的总计:
SELECT sum(views) FROM pageviews WHERE page='/home' and date >= '2017-01-01 00:00:00+0200' AND date <= '2017-01-13 23:59:00+0200'
最快的方法是使用计数器,并在不太忙的时间做一份工作,删除 X 天之前的内容。
另一个想法,如果你可以接受一些%错误,你可以在每页使用一个计数器并使用 forward decay为了“过期”(使旧 View 增量无关紧要),仍然需要一项工作来定期调整地标。不过,这对于查看范围没有那么有用,并且只会为您提供“到目前为止总计”的估计值。
关于select - Cassandra 和使用计数器类型清理旧数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47705289/