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

时间:2018-02-18 07:59:25

标签: apache cassandra cassandra-3.0

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

我有'设备'表(只有一个分区ID:'设备')我还有另一个表' DeviceStatistics' (分区ID:' deviceId'这样该表将具有与设备数量一样多的分区),这意味着每个设备都会收集每分钟的统计信息。

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

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

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表的partitionId,我需要为所有deviceId执行此查询(select device from deviceStatistics,其中deviceId =' deviceId' LIMIT 1)。 所以假设我有1000台设备,那么我需要每分钟为所有1000台设备触发此查询。

这有更好的设计吗?

2 个答案:

答案 0 :(得分:1)

我建议使用单独的表,其中timestamp将是分区键,设备ID是群集键。时间戳的粒度可能取决于您的应用程序 - 例如,drop seconds&几分钟,或类似的东西。

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

答案 1 :(得分:1)

Alex Ott的建议是一个好习惯:将带有时间戳的存储桶(日,小时,分钟,秒,取决于输入速度)的另一个表中的数据复制为分区键,将deviceid复制为第一个集群列(取决于您的查询)

类似

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

选择合适的桶大小非常重要:根据几篇文章,cassandra中的分区不应超过100MB左右。

如果您每分钟收集统计信息,则会产生1000个设备和100个字节数据记录的日期存储桶  一个1440(24x60)x nbr的设备(1000)x大小的记录(100)分区大小 =>每个分区144,000,000个字节 听起来不错,但是你必须对你的数据进行估算和测量,这是一个粗略的计算。

如果你需要查询sevaral天,你必须在你的查询中添加一个IN子句,使用有限数量的术语(10被认为是很多),或做几个查询,但它们会很快... :)

最好成绩,

阿兰

相关问题