【问题标题】:Cassandra: how to model time series of sensor data?Cassandra:如何对传感器数据的时间序列进行建模?
【发布时间】:2016-09-28 04:17:47
【问题描述】:

我需要将传感器读数存储在 cassandra(版本 2!)中。 有 n 个传感器,每个传感器最多可以发送 m 个不同类型的值(例如 Float、Bool、String)。这些值必须存储在 cassandra 中。稍后,将主要按时间范围查询值。因此,查询可能是“给我从 2016-05-01 09:00 到 2016-05-15 13:00 的所有读数”。可能有传感器 ID/类型的过滤器,但主要查询始终是时间。 (因此查询可能是“给我 2016 年 5 月 5 日传感器 1 和 5 的所有数据”,但很可能不是“给我传感器 1 和 5 的所有数据”)。

对于更详细的查询,如果必须扫描所有数据(受时间和可能的传感器 ID 限制)是可以的。因此,对于查询“给我 2016 年 5 月 5 日传感器 5 的所有传感器数据,其中读数的浮点值大于 1000”,如果 cassandra 必须从 2016 年 5 月 5 日扫描传感器 5 的所有值,则可以!

我阅读了很多关于数据建模的博客文章/问题,(例如[1][2][3][4][5][6])但有些东西已经存在多年了,我不确定,如果这仍然是正确的方法。

我的主要问题是:

  • 时间戳我使用什么数据类型(需要毫秒分辨率)
  • 如何定义键? (例如,我是否需要像某些示例那样使用每小时一次的主键?如果需要,我可以在 cassandra 中合并超过一小时的结果,还是需要手动执行?)
  • 如何添加 sensorID 以便高效查询

传感器数据将始终按顺序插入,因此不会更改以前的数据,也不会添加时间戳低于当前最大值的数据。

【问题讨论】:

    标签: database-design cassandra cql


    【解决方案1】:

    时间戳我使用什么数据类型(需要毫秒分辨率)

    timeuuid绝对是

    如何定义键? (例如,我是否需要像某些示例那样使用每小时一次的主键?如果是,我可以在 cassandra 中合并超过一小时的结果还是需要手动执行?)

    使用 Cassandra 进行数据建模的最大秘密是将物理分区的大小限制在可管理的范围内(~100Mb / 1000 万个单元)

    在您的情况下,每个传感器的子分区取决于插入率

    如果某些传感器以每秒数千个数据点的速度插入数据,则每小时分区是适当的粒度。当然,每小时 1 个分区 (PRIMARY KEY ((sensor_id, hour), insertion_time_in_timeuuid)) 会限制您的查询能力,例如如果您想在下午 4 点到 10 点之间获取某个传感器的数据,则需要发出 6 个查询或使用 IN 子句 (SELECT * FROM ... WHERE sensor_id=xxx AND hour IN (16, 17, 18, 19, 20, 21, 22))

    如果插入率适中,您可以按天/周/月进行子分区。这里没有规则,因为这完全取决于数据量。

    要记住的关键是在易于查询与分区大小之间保持平衡。

    如何添加 sensorID 以便高效查询

    将它作为分区键的一个组成部分与子分区时间范围一起放置,例如PRIMARY KEY( (sensor_id, hour), insertion_time_in_timeuuid)

    传感器数据将始终按顺序插入,因此不会更改以前的数据,也不会添加时间戳低于当前最大值的数据。

    CREATE TABLE sensor_data (
      sensor_id timeuuid,
      partitioning_time_range bigint,
      insertion_time_in_timeuuid timeuuid,
      float_value float
      int_value int,
      bool_value bool,
      text_value text,
      PRIMARY KEY( (sensor_id, hour), insertion_time_in_timeuuid)
    ) WITH CLUSTERING ORDER BY (insertion_time_in_timeuuid DESC);
    

    要适应不同类型的数据,只需为数据类型(float_valuebool_value、...)创建一个列。在运行时,如果您只使用 4/5 中的 1 列,Cassandra 只会在磁盘上插入 1 个物理单元(与关系数据库保留未使用列的空间)

    【讨论】:

    • 非常感谢您的回答。插入率是每分钟几百个值,所以也许我从每周分区开始。为跨越多个分区的所有传感器选择数据的正确(高性能)方法是什么?
    • 如果您需要获取所有传感器的数据,则必须并行发送异步 SELECT 语句,每个 sensor_id 一个,并从应用程序端手动合并结果。使用异步将加速并在集群中分配工作。如果您需要一个 sensor_id 列表,可以创建一个仅存储 sensor_id 的表并对其进行迭代
    • sensor_id 类型实际上是 timeuuid 吗?
    • sensor_id 可以是任何类型,只要您确保每个 sensor_id 的唯一性
    猜你喜欢
    • 2015-01-15
    • 2014-11-18
    • 2015-12-30
    • 1970-01-01
    • 2016-08-29
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    相关资源
    最近更新 更多