维护每个用户有界列表的最佳cassandra数据模型

omjgkv6w  于 2021-06-10  发布在  Cassandra
关注(0)|答案(2)|浏览(347)

我有kafka流包含用户与网站的交互,所以每个事件都有一个时间戳和关于事件的信息。对于每个用户,我希望在cassandra中存储最后k个事件(例如100个事件)。
我们的网站经常遇到机器人/大量用户,这就是为什么我们要限制事件,只是为了考虑“正常”用户。
我目前在Cassandra有当前的数据模型:

user_id, event_type, timestamp, event_blob

哪里

<user_id, event_type> = partition key,   timestamp = clustering key

目前,我们在一个新事件发生时立即在cassandra中写一个新记录,然后我们去清理“较重”的分区(即事件计数>100)。这不是实时发生的,除非我们不清理沉重的分区,否则有时在读取时会出现不好的延迟。
对于这种情况,你有什么更好的table设计建议吗?有没有办法告诉cassandra最多只存储k个元素作为分区,并以fifo方式终止旧的元素?还是有更好的table设计我可以选择?

gab6jxml

gab6jxml1#

对于这种情况,你有什么更好的table设计建议吗?
在为这样的场景进行数据建模时,我建议使用一种模式,该模式使用以下三个方面:
表上的默认ttl设置。
按降序对时间分量进行聚类。
调整查询以使用时间戳上的范围,从不查询超过ttl的数据。
ttl公司:
稍后我们去清理“较重”的分区
清理工作(平均)还要多久?我要做的一件事是,在你的团队通常需要清理它们之前,将表上的ttl设置为最长时间。
聚类键,降序:
所以您的主键定义如下所示:

PRIMARY KEY ((user_id,event_type),timestamp)

确保在时间戳上按降序进行聚类。

WITH CLUSTERING ORDER BY (timestamp DESC)

这一点与ttl结合使用很重要。在这里,您的墓碑位于分区的“底部”(排序时) timestamp 最近的数据(您关心的数据)位于分区的“顶部”。
范围查询:
最后,确保您的查询在 timestamp .
例如:如果今天是11号,我的ttl是5天,那么我可以查询最后4天的数据,而不必回拉墓碑:

SELECT * FROM events
WHERE user_id = 11111 AND event_type = 'B'
AND timestamp > '2020-03-07 00:00:00';
rfbsl7qr

rfbsl7qr2#

现有实现的问题是删除会创建逻辑删除,这最终会导致读取延迟。不建议创建太多的墓碑。
基于计数(每个分区的行数)的fifo实现是不可能的。对于您的用例,更好的方法是不要删除同一个表中的记录。使用spark将表迁移到新的temp表中,并删除迁移过程中的额外记录。比如:
1) 创建新表
2) 使用spark,从原始表中读取,迁移所有必需的记录(过滤额外的记录)并写入新的temp表。
3) 截断原始表。请注意,truncate操作不会创建逻辑删除。
4) 使用spark将temp表中的所有内容迁移回原始表。
5) 截断临时表。
您可以在应用程序的维护窗口中执行此操作(大约一个月一次),直到您可以使用每个分区限制100次的读取。

相关问题