说,我想从一个巨大的应用集群中收集日志,每秒产生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
的方式去这里?答案 0 :(得分:4)
这个数据模型关闭到一个理智的模型,有几个重要的修改/警告:
不使用ByteOrderedPartitioner,特别是不要将时间作为键。执行此操作将导致群集中出现严重的热点,因为您将执行大部分读取操作,并且所有写入操作仅限于部分数据范围(因此也是群集的一小部分)。 使用Murmur3Partitioner 。
要启用范围查询,您需要一个哨兵密钥 - 您可以提前知道的密钥。对于日志数据,这可能是一个时间段+一些其他已知值,这些值不是基于时间的(因此您的写入均匀分布)。
您的索引可能没问题,但在不知道您的数据的情况下很难判断。 确保您的基数值,或者指数不会很好地扩展。
确保所有潜在的过滤列都符合低基数规则。更好的是,如果您不需要实时查询,使用Spark进行分析。您应该根据需要创建新列,因为这不是什么大问题。卡桑德拉稀疏地存放它们。更好的是,如果您使用Spark,可以将这些值存储在地图中。
如果您遵循这些指南,则可以根据需要进行扩展。如果没有,您将获得非常差的性能,并且可能会获得与单个节点相当的性能。