ScyllaDb/Cassandra 中具有级别的时间序列日志数据

问题描述 投票:0回答:1

我需要一种按级别(例如日志、调试、错误)和时间戳查询日志数据的方法。这样我就可以在给定一个级别、一组级别或所有级别的指定时间后检索信息。

建议的解决方案:

CREATE KEYSPACE my_keyspace
WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}
AND durable_writes = true
AND partitioner = 'org.apache.cassandra.dht.ByteOrderedPartitioner';

CREATE TABLE my_keyspace.logs (
    timestamp TIMESTAMP,     // Partition key
    level TEXT,              // Clustering key
    source_node_id TEXT,     // Clustering key to handle collisions
    message TEXT,            // Log message content
    PRIMARY KEY ((timestamp), level, source_node_id) 
) WITH CLUSTERING ORDER BY (level ASC, source_node_id ASC);

SELECT * FROM logs 
WHERE TOKEN(timestamp) > TOKEN('2024-10-01T00:00:00Z') 
AND level IN ('error', 'warn');

这里我依靠 ByteOrderedPartitioning 来确保数据按时间戳良好排序,以便我可以按有序方式接收数据。我对级别使用聚集键,以便可以使用 IN 子句。尽管我不完全确定可以在 TOKEN 大于之后使用 IN 子句。我使用“source_node_id”来确保如果日志数据同时发生在不同的节点上,我不会覆盖日志数据,每个日志记录实体将有一个唯一的标识符。

发现的潜在问题:由于字节排序,如果日志记录量随着时间的推移非常不均匀,那么这将影响数据在节点上分布的均匀程度,尽管我认为我可以忍受这一点。只要在很长一段时间内,除了偶尔的热点之外,数据在令牌范围内基本上均匀地积累。我们可以假设在正常操作中,日志记录量将呈正态分布。

我将使用最新版本的 Cassandra 或 ScyllaDB 来实现此日志记录服务,并且不关心旧版本的行为。

我想知道A这是否是一个有效的解决方案,B可以在TOKEN大于子句之后使用IN子句,C可以更好地使用索引来帮助解决这样的问题并提供更好的解决方案吗?

cassandra scylla
1个回答
0
投票
ScyllaDB不支持

ByteOrderedPartitioner

,不支持它的原因正是您所问的:它会导致数据分布非常倾斜。因此,您不应该在该分区程序上构建解决方案。
针对大小时间序列的更好的数据建模是使用聚类键

,而不是分区键,按时间排序。但是,您不希望将所有数据保存在单个分区中,因此您经常将分区拆分为各个日期的存储桶(即,天数是分区键),并且在每个分区内数据按聚类键(准确时间)排序。在这种方法中,数据在磁盘上保持了良好的平衡,但是“写入”活动仍然仅针对单个分区,因此一整天仅使用集群的 RF(例如 3 个)CPU,因此添加到另一个组件的分区键,以便新活动将分布在例如 10 个分区而不是一个分区(当然,需要从这 10 个分区进行读取)。您可以根据需要将“级别”作为集群键或分区键的一部分 - 例如,如果常见需求是扫描,例如仅扫描错误级别事件,则将其作为分区键的一部分会更有效- 这使您可以有效地仅扫描一天的错误级别事件,而无需过滤掉其他类型的事件。

使用 ScyllaDB 或 Cassandra 进行时间序列建模非常流行,因此您可以在 Google 搜索中轻松找到有关如何有效地进行建模的各种文档和演示文稿 - 如何对数据进行建模、使用哪种压缩策略(时间窗口压缩策略) ),等等。

© www.soinside.com 2019 - 2024. All rights reserved.