使用Cassandra获得最新的独特结果
我有一个服务可以处理不同服务上的用户状态。 多个DCs上的流量可能非常高,因此我认为Cassandra适合存储这些数据。使用Cassandra获得最新的独特结果,cassandra,Cassandra,我有一个服务可以处理不同服务上的用户状态。 多个DCs上的流量可能非常高,因此我认为Cassandra适合存储这些数据。 我只需要保留每个服务和用户的最新更新。 我想创建这个表: CREATE TABLE db.state ( service uuid, user uuid, updated_at timestamp, data varchar, PRIMARY KEY (service, user, updated_at) ) WITH CLUSTERING O
我只需要保留每个服务和用户的最新更新。
我想创建这个表:
CREATE TABLE db.state (
service uuid,
user uuid,
updated_at timestamp,
data varchar,
PRIMARY KEY (service, user, updated_at)
) WITH CLUSTERING ORDER BY (updated_at DESC);
问题是如何查询最新的100个唯一用户状态。使用此查询:
选择服务、用户、数据,在FROM db.state处更新,其中服务=:服务限制100
如果某个用户有很多更新,我不会得到最新的100个用户,而是更少。
我不想合并客户端中的唯一用户,因为为了获得100个用户,有时需要获得10000行
我想到了两个都有问题的解决方案:
主键(服务,用户)
和
使用主键(服务、用户、,
更新地址)
。但这会影响性能主键(服务,用户)
创建表并读取
在写入之前具有完全一致性,以检查是否未写入较旧的更新。但这就放弃了可用性和一种反模式
卡桑德拉编辑 写入不一定按顺序进行,因此时间戳是在外部提供的。
我不需要保存历史记录,只需保存最后一次更新(通过外部时间戳)。供您选择:
IF存在或IF子句
如果您需要历史记录(不仅仅是最新的),并且不需要第二张表,您可以使用group by:
CREATE TABLE state ( // simplified a little
service int,
user int,
updated_at timeuuid,
data text,
PRIMARY KEY (service, user, updated_at)
) WITH CLUSTERING ORDER BY (user ASC, updated_at DESC);
INSERT INTO state (service, user, updated_at, data) VALUES ( 1, 1, now(), '1');
INSERT INTO state (service, user, updated_at, data) VALUES ( 1, 1, now(), '2');
INSERT INTO state (service, user, updated_at, data) VALUES ( 1, 1, now(), '3');
INSERT INTO state (service, user, updated_at, data) VALUES ( 1, 2, now(), '1');
INSERT INTO state (service, user, updated_at, data) VALUES ( 1, 2, now(), '2');
INSERT INTO state (service, user, updated_at, data) VALUES ( 2, 1, now(), '1');
INSERT INTO state (service, user, updated_at, data) VALUES ( 1, 3, now(), '2');
INSERT INTO state (service, user, updated_at, data) VALUES ( 1, 3, now(), '3');
INSERT INTO state (service, user, updated_at, data) VALUES ( 1, 3, now(), '1');
INSERT INTO state (service, user, updated_at, data) VALUES ( 1, 3, now(), '2');
SELECT * FROM state WHERE service = 1 GROUP BY service, user;
service | user | updated_at | data
---------+------+--------------------------------------+------
1 | 1 | 7c2bd900-981e-11e9-a27a-7b01c564a3f0 | 3
1 | 2 | 7c2d1180-981e-11e9-a27a-7b01c564a3f0 | 2
1 | 3 | 7c88c610-981e-11e9-a27a-7b01c564a3f0 | 2
它的效率并不惊人,但只要您不让单个服务分区变得太大,它就可以工作。实际上,我强烈建议在其中添加一个日期组件/桶,如:
CREATE TABLE state (
bucket text
service int,
user int,
updated_at timeuuid,
data text,
PRIMARY KEY ((bucket, service), user, updated_at)
) WITH CLUSTERING ORDER BY (user ASC, updated_at DESC);
其中bucket是YYYY-MM-DD字符串(或YYYY-WEEKOFYEAR或其他内容)。然后大约在边界时间查询当前和最后一个bucket。否则,分区将不断增长,直到出现问题。谢谢您的回答。我补充了解释:“写入不一定是按顺序进行的,所以时间戳是外部提供的。”对于你的问题,我不需要历史记录