我需要针对以下用例的最佳方法,
我有'设备'表(只有一个分区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台设备触发此查询。
这有更好的设计吗?
答案 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被认为是很多),或做几个查询,但它们会很快... :)
最好成绩,
阿兰