Cassandra 中一个用例的数据模型设计方法

Data Model design approach for one use case in Cassandra

我需要以下用例的最佳方法,

我有 'Device' table(只有一个分区 ID:'Device')我还有另一个 table 'DeviceStatistics'(分区 ID:'deviceId' 这样 table 将拥有与设备数量一样多的分区)这意味着对于每台设备,每分钟都会收集一次统计数据。

CREATE TABLE device(
   "partitionId" text,"name" text,"deviceId" text, ..., primary key ("partitionId","name","deviceId"));

其中 partitionId - 它是一个常量 ('device')

CREATE TABLE deviceStatistics (    
"deviceId" text,     
"timestamp" timestamp, ...,
primary key ("deviceId","timestamp")) with clustering order by ("timestamp" DESC);

其中 'deviceId' - 它是分区键,每个分区下都有时间戳条目列表

到此为止,因为我只需要以下查询,

1) select * from device where partitionId = 'device'
   - which list all the devices available. 
2) select * from deviceStatistics where deviceId = 'deviceId_1'
   - which list all the device statistics for a deviceId
3) select * from deviceStatistics where deviceId = 'deviceId_1' LIMIT 1
   - which gets the most recent statistics for a deviceId 

现在我需要以下用例的解决方案,

我需要收集集群级别的统计信息,这意味着我需要收集时间戳的所有设备统计信息,

(即)如果 4 个设备的 deviceStatistics 可用于时间戳,那么我需要收集时间戳的所有四个统计信息并添加到设备组级别。

这意味着我的 DeviceGroupstatistics 是时间戳的所有设备统计信息的聚合。

现在的问题是,由于我有 'deviceId' 作为 deviceStatistics table 的 partitionId,我需要执行此查询(select * from deviceStatistics where deviceId = 'deviceId' LIMIT 1) 对于所有设备 ID。 所以假设我有 1000 台设备,那么我需要每分钟为所有 1000 台设备触发此查询。

有没有更好的设计?

我建议使用单独的 table,其中时间戳将是分区键,设备 ID 是集群键。时间戳的粒度可能取决于您的应用程序 - 例如,减少秒数并舍入到分钟数,或类似的东西。

您可以实现存储应用程序中的数据(首选),或者您可以使用物化视图(但它们是实验性的,并不总是推荐使用)。

Alex Ott 的建议是一个很好的做法:将您的数据复制到另一个 table 中,使用带时间戳的存储桶(天、小时、分钟、秒,取决于输入速度)作为分区键,并将 deviceid 作为第一个聚类列(取决于您的查询)。

类似于

PRIMARY KEY (bucket, device_id, timestamp ... etc)

选择合适的存储桶大小很重要:根据几篇帖子,cassandra 中的分区不应超过 100MB 左右。

如果您每分钟收集一次统计数据,则 1000 台设备和 100 字节数据记录的一天桶将导致 1440 (24x60) x 设备数量 (1000) x 记录大小 (100) 分区大小 => 每个分区 144,000,000 字节 听起来不错,但是你必须用你的数据做估计和测量,这是一个粗略的计算。

如果你要连续查询几天,你必须在查询中添加一个 IN 子句,限制字数(10 个被认为是很多),或者进行多次查询,但它们会很快。 ..:)

最佳,

阿兰