【问题标题】:Data Model design approach for one use case in CassandraCassandra 中一个用例的数据模型设计方法
【发布时间】:2018-07-28 17:04:04
【问题描述】:

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

我有“设备”表(只有一个分区 ID:“设备”),还有另一个表“设备统计”(分区 ID:“设备 ID”,因此该表的分区数与设备数一样多),这意味着对于每台设备,每分钟都会收集一次统计信息。

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

有没有更好的设计呢?

【问题讨论】:

    标签: cassandra cassandra-3.0


    【解决方案1】:

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

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

    【讨论】:

    • 感谢您的建议,但问题是“我根据查询设计了表”如果我将时间戳保留为分区键,那么分区将会太多,并且此查询也会受到影响: select * from deviceStatistics where deviceId = 'deviceId_1' AND timestamp from somevalue to timestamp to somevalue
    • 目前我正在寻找框架 devicegroupstatistics 的查询,当设备数量增加时,这对我来说变得越来越复杂。我需要在最后一分钟收集每个 deviceId 的统计信息,它增加了查询,但当前表设计满足此查询:select * from deviceStatistics where deviceId = 'deviceId_1' AND timestamp from somevalue to timestamp to somevalue
    • 我相信上面的解决方案是构建第三张表,时间戳作为分区键,deviceId 作为集群列。写入两个表 deviceStatistics_by_timestamp 和 deviceStatistics_by_deviceId。根据分区键是什么读取对应的表。
    • @dilsingi - 是的,你是对的 - 这是我的建议 - 要么明确地写出来,要么创建物化视图
    • @AlexOtt 感谢您的解决方案。这真的很正常。 :)
    【解决方案2】:

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

    类似

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

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

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

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

    最好的,

    阿兰

    【讨论】:

    • 感谢您的解释。 :)
    猜你喜欢
    • 2017-01-24
    • 1970-01-01
    • 2021-03-20
    • 2012-11-18
    • 1970-01-01
    • 2012-07-09
    • 1970-01-01
    • 2016-08-30
    • 1970-01-01
    相关资源
    最近更新 更多