Cassandra物化视图和IN查询有哪些陷阱?
What are the pitfalls of Cassandra materialised views and IN queries?
假设我有一个 table
CREATE TABLE events (
stream_id text,
type text,
data text,
timestamp timestamp,
PRIMARY KEY (stream_id, timestamp)
);
请求模式是我需要通过stream_id
获取所有事件。
例如SELECT * FROM events WHERE stream_id = 'A-1';
然后我需要在给定一组 type
的情况下获取所有事件。所以我制作了一个MV:
CREATE MATERIALIZED VIEW events_by_type AS
SELECT * FROM events
WHERE type IS NOT NULL AND
timestamp IS NOT NULL
PRIMARY KEY (type, stream_id, timestamp)
WITH CLUSTERING ORDER BY (timestamp DESC);
请求像
SELECT * FROM events_by_type WHERE type IN ('T1', 'T2);
这种查询模式和数据模型有哪些缺陷?
如果有,是否可以改进?
我能想到的唯一一个你可能遇到的陷阱是与视图的一致性没有反映在写入基础的一致性级别上table。因此,如果您需要更强的一致性(读写法定人数),您可能会 运行 遇到问题。
一个问题是您的分区是无限的。在当前版本中,如果您的建筑物的分区大于 100 MB 左右,您可能会开始遇到其他性能问题(有效,但有时需要 GC 调整以保持运行)。这最近有所改善,但你应该打破你的分区一些。即
CREATE TABLE events (
stream_id text,
time_bucket text,
type text,
data text,
timestamp timestamp,
PRIMARY KEY ((stream_id, time_bucket), timestamp)
);
CREATE MATERIALIZED VIEW events_by_type AS
SELECT * FROM events WHERE
type IS NOT NULL AND
time_bucket IS NOT NULL AND
timestamp IS NOT NULL
PRIMARY KEY ((type, time_bucket), stream_id, timestamp)
WITH CLUSTERING ORDER BY (timestamp DESC);
它增加了您 time_bucket
需要了解的复杂性。您可以将存储桶预定义为每天(即 2016-10-10 00:00:00
)或创建一个新的 table 来映射可能的 time_buckets 类型或 stream_id.
这也可能是老式二级索引是合理选择的情况。假设有合理限制但数量不多的类型,二级索引就可以正常工作。 (如果只有很少数量的不同类型,那么您也可能 运行 遇到物化视图中大分区的问题。)
假设我有一个 table
CREATE TABLE events (
stream_id text,
type text,
data text,
timestamp timestamp,
PRIMARY KEY (stream_id, timestamp)
);
请求模式是我需要通过stream_id
获取所有事件。
例如SELECT * FROM events WHERE stream_id = 'A-1';
然后我需要在给定一组 type
的情况下获取所有事件。所以我制作了一个MV:
CREATE MATERIALIZED VIEW events_by_type AS
SELECT * FROM events
WHERE type IS NOT NULL AND
timestamp IS NOT NULL
PRIMARY KEY (type, stream_id, timestamp)
WITH CLUSTERING ORDER BY (timestamp DESC);
请求像
SELECT * FROM events_by_type WHERE type IN ('T1', 'T2);
这种查询模式和数据模型有哪些缺陷? 如果有,是否可以改进?
我能想到的唯一一个你可能遇到的陷阱是与视图的一致性没有反映在写入基础的一致性级别上table。因此,如果您需要更强的一致性(读写法定人数),您可能会 运行 遇到问题。
一个问题是您的分区是无限的。在当前版本中,如果您的建筑物的分区大于 100 MB 左右,您可能会开始遇到其他性能问题(有效,但有时需要 GC 调整以保持运行)。这最近有所改善,但你应该打破你的分区一些。即
CREATE TABLE events (
stream_id text,
time_bucket text,
type text,
data text,
timestamp timestamp,
PRIMARY KEY ((stream_id, time_bucket), timestamp)
);
CREATE MATERIALIZED VIEW events_by_type AS
SELECT * FROM events WHERE
type IS NOT NULL AND
time_bucket IS NOT NULL AND
timestamp IS NOT NULL
PRIMARY KEY ((type, time_bucket), stream_id, timestamp)
WITH CLUSTERING ORDER BY (timestamp DESC);
它增加了您 time_bucket
需要了解的复杂性。您可以将存储桶预定义为每天(即 2016-10-10 00:00:00
)或创建一个新的 table 来映射可能的 time_buckets 类型或 stream_id.
这也可能是老式二级索引是合理选择的情况。假设有合理限制但数量不多的类型,二级索引就可以正常工作。 (如果只有很少数量的不同类型,那么您也可能 运行 遇到物化视图中大分区的问题。)