Cassandra 考虑消息传递应用程序需要 IN 子句

Cassandra need for IN clause in consideration of a messaging application

对于一个消息传递应用程序,我有一个数据库结构相对于:

CREATE TABLE users(
    userid text,
    name text, 
    rooms list<text>
    ...
    PRIMARY KEY (userid)
);

CREATE TABLE rooms(
    roomid text,
    members list<text>,
    createdat bigint,
    lastmessage bigint,
    ...
    PRIMARY KEY (roomid, createdat)
);

CREATE TABLE messages(
    roomid text,
    bucket int,
    messageid bigint,
    authorid text,
    ...
    PRIMARY KEY ((hash, roomid), messageid)
);

启动时,客户端请求给定用户的所有房间。首先,我查询给定用户的所有 roomids:

SELECT rooms FROM users WHERE userId = 1234

然后我使用 IN 子句收集所有房间

SELECT * FROM rooms WHERE roomid IN ('room_1', 'room_2', ......);

和return客户端的实体。

我研究过,IN 子句可能导致一个节点承受很大压力。我希望用户最多有一百个房间。

我必须将请求拆分为单个查询还是他们的另一种方式,比如更改数据模型?

为什么IN子句会导致单节点压力?

提前致谢!

您是正确的,您应该限制 IN() 运算符中的键数。我通常建议非常低的个位数键,例如 2 或 3,不要太多,否则协调器将承受很大压力,因为它必须触发尽可能多的单独请求。

你说得对,你应该以不同的方式对数据建模以获得最佳性能。

我强烈建议创建一个按用户 ID 分区的新 table:

CREATE TABLE rooms_by_userid (
  ...
  PRIMARY KEY (userid, roomid)
)

当您查询 table 时:

SELECT ... FROM rooms_by_userid WHERE userid = 1234

您将获得按房间 ID 聚类的数据行。这是对数据建模的最佳方式,因为它是根据应用要求组织的。

您当前的模型必须查询 2 table 才能有效地执行笨拙的 JOIN。我提议的方式意味着您只需要从一个 table 中检索数据,因此它非常高效。干杯!