【问题标题】:Storing sensor data efficiently有效存储传感器数据
【发布时间】:2013-09-02 10:36:07
【问题描述】:

我正在考虑重新开发一个存储和可视化传感器数据的应用程序。该应用程序可供多个用户访问,他们可以添加无限的传感器。我们现在有 10 个用户,我们有大约 1000 个传感器。用户数量可能不会改变。如果有足够的电力(太阳能电池板),传感器每 5 秒发送一次数据。

目前数据存储在 4 个表中。

  • 用户 [ID、电子邮件、密码等]
  • 设备 [id, name, user_id] user_id: 外键
  • 传感器 [id, device_id, type] device_id: 外键
  • 数据 [id, sensor_id, time, data] sensor_id: 外键

问题是数据表变得非常大。目标是将数据保留近一年。我使用 MySQL,我对它的性能非常失望。现在我正在使用带有 Gunicorn 的烧瓶,并且正在使用 RabbitMQ 来排队存储过程。我有什么可以改变的来提高现有系统的性能吗?如果你从头开始做这件事,你会做出什么改变? NoSQL 会在这种情况下产生重大影响吗?我要求太多了,但这是我第一次遇到这种问题。

【问题讨论】:

  • 性能不能接受的原因是什么?你可以说得更详细点吗?在不知道您正在执行的操作执行得太慢的情况下,我不明白这是如何回答的。
  • 一段时间内尝试选择数据时出现问题。用户只是坐在那里等待查询执行。我说的是30秒。有时它会达到设置为 45 秒的超时。
  • 您是否索引了您的time 列?
  • 不,我没有。我会试试看。希望它会改善这种情况。
  • 您应该会看到显着的改善。

标签: mysql scalability


【解决方案1】:
  1. 由于您有 1k 个传感器,每个传感器每 5 秒生成一次数据,在我看来,这是一个很好的例子,可以使用像 Akka 这样的框架来处理许多请求并避免 许多线程 问题

  2. 一旦你的处理阶段看起来已经优化,你就正确地写了关于 NoSQL 的文章。 cmets 中的人提到缺少索引,但由于您只有一个表,这可能导致表中的每个insert 都会触发所有数据的索引重新计算。这可能会影响您应用的吞吐量。

    您有很多选择来解决这个问题。将表划分到最后一个包含最新数据或使用两个表,一个用于读取和查询,第二个用于写入以及从第二个到第一个的批量插入 - 这绝对是使用截止索引的速度。众所周知的问题是,您可以针对大量读取或大量写入优化存储,而不是同时针对两者进行优化。

    或者你可以看看NoSQL,特别是我想到的Redis,看看他们的数据类型http://redis.io/topics/data-types-intro

    Redis 天生就支持长列表。由于它不支持SELECT ... FROM ... WHERE ... 的任何查询,因此您必须提供自己的 indexescaches 才能提供所需的查询。如果您对如何使用 key:value 存储感兴趣,请查看他们的 twitter 演示。 Twitter 必须像你一样解决同样的问题。

这就引出了我的最后一点。如果您想提供更好的可扩展性,但您不知道如何做,请查看 facebook、twitter 或 netflix 架构。

【讨论】:

  • 1.这还不是问题。它只是工作。 2.mongodb呢?好像没那么可怕。我已经遇到了用 mongodb 构建数据的问题,而 redis 对我来说似乎是一个很大的飞跃。
  • Mongo 旨在处理像 json 这样的文档。它不支持查询,但您可以在某些 JSON 属性之上定义索引。我对 mongo 不熟悉,因为我没有在真正的产品中使用过它。使用哪个数据库的重要一点是您要对数据做什么。您是否需要使用查询来查询它们,或者您想使用大型数组(数百万个项目)或大型哈希集。这就是为什么它建议你阅读 redis 数据类型主题的原因,也许你会发现那些结构是你的权利。
  • 谢谢你指点我redis。我找到了这个[strataconf.com/strata2013/public/schedule/detail/27350],我认为我应该这样做。
【解决方案2】:

作为 Martin Podval,您应该查看 NoSql,但您可以再次尝试一些技巧。首先,开始将数据分区到多个表中。根据最常用的时间范围,您可以为一个表分区一周或一个月。然后对于时间范围,您将不得不查询多个表并组合结果(一个小的 map&reduce 作业),但是在较小的表上的多个查询将被证明比在大表上的单个查询更快。

第二个技巧是优化表的索引,不惜一切代价避免 JOIN 操作。

最后你可以添加缓存,这是一个非常古老的技巧,并且有很多争论,但是 10 个用户在 1000 个传感器上一年,我认为他们很有可能会多次查看相同的数据.

我认为最好的解决方案不是仅仅使用 NoSQL 解决方案,而是更接近分布式的解决方案,即使使用廉价服务器,您也会获得更好的性能。算一算,您一年应该有大约 63 亿条记录。无论计算机有多快,使用什么系统(存储系统),即使从内存中读取数据也需要很长时间。

【讨论】:

    【解决方案3】:

    如果不讨论已经在行业中得到验证的解决方案,任何关于遥测数据的讨论都是不完整的。

    HDF5 就是这样一种解决方案。 HDF5 是一种用于存储和管理遥测数据的数据模型、库和文件格式。它支持无限多种数据类型,专为灵活高效的 I/O 以及大容量和复杂数据而设计。

    SQL Server 有一个FILESTREAM 数据类型,它特别适合处理大型遥测数据集。 McClaren Systems 使用它来收集一级方程式赛车的遥测数据。

    进一步阅读
    Programming with FileStream
    McClaren Case Study

    【讨论】:

      【解决方案4】:

      自您提出问题以来,数据库格局发生了很大变化,但这个问题今天仍然有效,甚至更多。总而言之,您的需求似乎如下:

      1. 存储大量传感器数据/时间序列数据。
      2. 能够快速查询数据
      3. 在给定时间段后轻松/自动删除数据:数据保留政策

      您似乎需要针对传感器/物联网/时间序列数据进行优化的数据库。根据DB-Engines 在过去 2 年中的说法,时间序列数据库获得了最大的关注。我认为值得尝试这些数据库,因为它们针对此类数据进行了优化。一些值得注意的:

      1. InfluxDB 用于传感器和系统的开源时间序列数据库。
      2. GridDB 开源 NoSQL 时间序列数据库,用于物联网和大数据。
      3. CrateDB 用于工业物联网的分布式 SQL

      这些数据库都是为了存储时间序列/物联网数据而设计的,可以快速摄取和查询,并具有数据保留功能。

      例如,使用GridDB,您的数据模型将是这样的:

      • 用户的容器字段 user_id、email、密码等
      • 每个设备的设备容器,带有键“DEVICES_$userID”和字段 deviceId 和 sensorIDs 数组
      • 每个设备的传感器容器,带有键“SENSOR_$sensorID”,字段时间和数据。

      容器的工作方式类似于表,但无需任何技巧即可对数据进行分区,您可以在其中快速查询单个或一组传感器的数据。由于每个传感器数据都存储在每个容器中,因此您不会得到一个臃肿的表。

      【讨论】:

        猜你喜欢
        • 2011-02-28
        • 1970-01-01
        • 2016-04-15
        • 1970-01-01
        • 1970-01-01
        • 2019-10-22
        • 1970-01-01
        • 2015-09-23
        • 2012-09-11
        相关资源
        最近更新 更多