【发布时间】:2014-08-15 04:17:28
【问题描述】:
假设,我想从一个每秒产生 1000-5000 条记录的大型应用程序集群中收集日志。将来,这个数字可能会达到每秒 100000 条记录,从 10000 个强大的数据中心聚合而成。
CREATE TABLE operation_log (
-- Seconds will be used as row keys, thus each row will
-- contain 1000-5000 log messages.
time_s bigint,
time_ms int, -- Microseconds (to sort data within one row).
uuid uuid, -- Monotonous UUID (NOT time-based UUID1)
host text,
username text,
accountno bigint,
remoteaddr inet,
op_type text,
-- For future filters — renaming a column must be faster
-- than adding a column?
reserved1 text,
reserved2 text,
reserved3 text,
reserved4 text,
reserved5 text,
-- 16*n bytes of UUIDs of connected messages, usually 0,
-- sometimes up to 100.
submessages blob,
request text,
PRIMARY KEY ((time_s), time_ms, uuid)) -- Partition on time_s
-- Because queries will be "from current time into the past"
WITH CLUSTERING ORDER BY (time_ms DESC)
CREATE INDEX oplog_remoteaddr ON operation_log (remoteaddr);
...
(secondary indices on host, username, accountno, op_type);
...
CREATE TABLE uuid_lookup (
uuid uuid,
time_s bigint,
time_ms int,
PRIMARY KEY (uuid));
我想使用 OrderedPartitioner,它将通过其time_s(秒)将数据分布在整个集群中。随着更多应用程序日志聚合器添加到应用程序集群,它还必须扩展到数十个并发数据写入器(唯一性和一致性由 PK 的uuid 部分保证)。
分析师必须通过执行这些类型的查询来查看这些数据:
- 范围查询
time_s,过滤任何数据字段 (SELECT * FROM operation_log WHERE time_s < $time1 AND time_s > $time2 AND $filters), - 从上一个结果中分页查询(
SELECT * FROM operation_log WHERE time_s < $time1 AND time_s > $time2 AND token(uuid) < token($uuid) AND $filters), - 计数在一个时间范围内由任何数据字段过滤的消息 (
SELECT COUNT(*) FROM operation_log WHERE time_s < $time1 AND time_s > $time2 AND $filters), - 按某个范围内的任何数据字段对所有数据进行分组(将由应用程序代码执行),
- 通过
uuid(数百条SELECT * FROM uuid_lookup WHERE uuid IN [00000005-3ecd-0c92-fae3-1f48, ...])请求数十或数百条日志消息。
我的问题是:
- 这是一个健全的数据模型吗?
- 是使用
OrderedPartitioner去这里的方式吗? - 为潜在过滤器配置几列是否有意义?或者每隔一段时间添加一个列是否足够便宜,可以在具有一些预留空间的 Cassandra 集群上运行?
- 如果并发查询器的数量永远不会超过 10,是否有任何东西阻止它从数百个聚合器扩展到每秒 100000 个插入行并存储 PB 或 2 个可查询数据?
【问题讨论】: