应用程序日志的Cassandra数据模型(数十亿次操作!)

时间:2014-08-14 16:23:46

标签: cassandra data-modeling

说,我想从一个巨大的应用集群中收集日志,每秒产生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集群上运行?
  • 是否存在阻止它从数百个聚合器每秒扩展到100000个插入行并存储一PB或两个可查询数据的任何内容,前提是并发查询者的数量永远不会超过10个?

1 个答案:

答案 0 :(得分:4)

这个数据模型关闭到一个理智的模型,有几个重要的修改/警告:

  • 使用ByteOrderedPartitioner,特别是不要将时间作为键。执行此操作将导致群集中出现严重的热点,因为您将执行大部分读取操作,并且所有写入操作仅限于部分数据范围(因此也是群集的一小部分)。 使用Murmur3Partitioner

  • 要启用范围查询,您需要一个哨兵密钥 - 您可以提前知道的密钥。对于日志数据,这可能是一个时间段+一些其他已知值,这些值不是基于时间的(因此您的写入均匀分布)。

  • 您的索引可能没问题,但在不知道您的数据的情况下很难判断。 确保您的基数值,或者指数不会很好地扩展。

  • 确保所有潜在的过滤列都符合低基数规则。更好的是,如果您不需要实时查询,使用Spark进行分析。您应该根据需要创建新列,因为这不是什么大问题。卡桑德拉稀疏地存放它们。更好的是,如果您使用Spark,可以将这些值存储在地图中

  • 如果您遵循这些指南,则可以根据需要进行扩展。如果没有,您将获得非常差的性能,并且可能会获得与单个节点相当的性能。