【问题标题】:Managing table which is frequently updated and queried管理频繁更新和查询的表
【发布时间】:2017-10-19 00:26:14
【问题描述】:

到目前为止,我和我的朋友已经制作了一个小型系统,用于从我们区域周围的传感器收集天气数据。 这是我们数据库中的一张表:

CREATE TABLE `Measurement` (
  `Id` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `SensorId` varchar(16) COLLATE utf8_unicode_ci NOT NULL,
  `Time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  `Battery` double DEFAULT NULL,
  `Rain` double DEFAULT NULL,
  `Humidity` double DEFAULT NULL,
  PRIMARY KEY (`Id`,`Time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

环境:

  • ASP.Net 框架 4.6。
  • Web API 2.
  • MySQL 社区版。

部署:

  • 有一个用于存储用户信息、天气测量和传感器信息的数据库部署在单个服务器上。
  • 有一个 WEB API 可以帮助客户端应用连接和获取数据。

我们的情况是:

此表用于存储每 10 秒来自 60 个传感器的气候要素测量值。 目前,我们面临一个数据急剧增加的问题,只需简单计算一下:

1(每 10 秒记录一次)* 6(一小时内记录)* 24(一天几小时)* 365(一年的天数)=52 560(一年的记录)

52 560(每年记录)* 60(传感器)= 3 153 000(记录)

因此,在从 60 个传感器收集数据一年后,我们拥有 3 153 000 条记录。太多的记录无法存储到一张表中(在我看来)。 这就是为什么我正在考虑一个解决方案: - 将传感器的测量数据分成多个数据库并部署到多个服务器上。每个传感器将有一台小型 PC 来存储其信息(通过使用 API) - 当用户想要查询数据库以搜索他们需要的信息时,Web服务器会根据他们提供的传感器信息,调用不同的API端点来获取数据并汇总信息,然后将它们显示到UI。

我的问题是:

  • 不包括我们用于部署我们的数据库和微服务的PC成本是否衡量。这种部署是一种有效的做法吗?
  • 有没有办法管理这种测量表? (数据每10秒增加一次,可以多次查询)?
  • 如果有办法优化我的表,请告诉我?
  • 是否应该将传感器测量收集功能部署为微服务以提高性能和可扩展性?

谢谢,

【问题讨论】:

    标签: mysql sql scalability microservices bigdata


    【解决方案1】:

    您的问题总体而言过于宽泛。然而:

    我们有 3 153 000 条记录。这是太多的记录,无法存储到一个 表(在我看来)

    你的意见完全是错误的。存储数百万(或数千万甚至数亿或数十亿行)的数据库表没有问题。您确实需要开始更加关注数据的结构。

    有两种关键技术可以提供帮助:

    • 分区(你可以了解它here
    • 索引

    更新速率为 10 次更新/秒,插入数据应该没有任何问题。

    【讨论】:

    • 那么,关于索引。您能否检查在我们的情况下使用复合键是否良好?我创建了一个 api,它可以帮助用户按时间、电池、雨量、湿度来排序记录
    • @Redplane 。 . .最佳索引取决于您要优化的查询。用数据布局和查询描述提出另一个问题。这个问题太笼统了。
    • 我同意这个问题很广泛......就像霰弹枪爆炸的弹丸图案。如果目标足够大,一些弹丸可能会击中目标。 Gordon 是正确的...这里真正 重要的是如何查询数据...从表/分区中需要什么结果。数据库需要支持哪些查询模式?设计数据库以满足查询模式是至关重要的。如果我们不需要支持查询,我们可以将数据填充到数据库中。将数据填充到数据库中不是问题。
    【解决方案2】:

    关于每年的读数数量的“简单计算”似乎有些不对劲。

    24 小时有 86,400 秒。即每天 8,640 个“十秒间隔”。

    乘以每年 365 天,即每年 3,153,600 个“十秒间隔”。

    乘以 60 个传感器(每个传感器每十秒一个读数),即每年 1.89 亿 (189,216,000) 个读数。


    要管理具有大量行的表,请考虑对Time 列进行范围分区。例如,按周或按月。

    我们实际上需要多少VARCHAR(255) 来识别读数/传感器?如果我们可以改用INT 数据类型,那将只有四个字节。 DATETIME 数据类型将花费我们 8 个字节,而 TIMESTAMP 数据类型将只需要 4 个字节。

    如果我沿着将表分割成更小的表的路线,我会考虑 60 个表,每个读取一个。并将Id/SensorId 值(列)移出表,并将其移到表的标识符中。这样一来,我们就只剩下 Time 作为主键了,并保存了大量重复的数据。

    我们仍然可以在每个表上实现分区。

    但到目前为止,我们只讨论插入行。讨论中缺少的以及真正重要的是我们将如何查询数据;我们需要支持哪些查询模式。

    在使用微服务之前,我会先了解数据结构。如果每个读数都在一个单独的表中,那么这有助于将这些表分片到多个服务器上。但它对应用程序不是透明的。应用层需要意识到这一点,并使用多个数据库连接,为每个表使用正确的连接。

    【讨论】:

      【解决方案3】:

      由于您的目标是“巨大”表,因此您需要尽可能地缩小数据类型。 1.89 亿/年的行与您当前的架构可能是 40GB/年

        `Id` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
        `SensorId` varchar(16) COLLATE utf8_unicode_ci NOT NULL,
      

      他们需要是 utf8 吗?无论您是否需要 utf8,对 IdSensorId 中的每一个进行规范化,或者对这对进行规范化。可能MEDIUMINT UNSIGNED(3 个字节,16M 限制)就足够了。

        `Battery` double DEFAULT NULL,
        `Rain` double DEFAULT NULL,
        `Humidity` double DEFAULT NULL,
      

      DOUBLE 占用 8 个字节并为您提供 16 个有效数字。我怀疑您是否可以将湿度读取到超过 3 个有效数字。 FLOAT 只占用 4 个字节并为您提供 7 个有效数字。 DECIMAL(4,2) 可能值得考虑——值高达 99.99,只占用 2 个字节。 (等等)

        PRIMARY KEY (`Id`,`Time`)
      

      不知道SELECTs,我们无法判断它有多大用处。

      上述更改可能会使您降至 10GB/年。

      完成这些工作,然后我们来谈谈汇总表——您确实想要扫描 189M 行以查找任何内容!

      您还没有说过任何会触发使用分区的内容。

      “帮助用户对记录进行排序”——过滤呢?你真的在帮助用户获取 189M 行吗?

      【讨论】:

        【解决方案4】:

        可能是一个完整的不同的解决方案,可以查看您长期实际想要存储的内容。当然,您希望通过数据收集的结果来回答很多问题。

        解决方案是否可以定期运行以生成一些将长期存储的关键见解,然后修剪表以创建更多空间 - 或归档“旧”数据?

        只是一个 - 拉斯

        【讨论】:

          【解决方案5】:

          简而言之:您可能希望查看更专门用于时间序列数据的解决方案。例如influxdb。为了使您的系统更加健壮,您可能还需要包含一个快速流处理器,例如 Apache Kafka

          这里是您问题的答案:

          不包括我们用于部署数据库和微服务的 PC 成本 是否测量。这种部署是一种有效的做法吗?

          这个问题不太清楚您要问什么,但我假设您问的是使用无服务器云部署进行数据库/服务设置是否有效。如果是这样,那么答案可能是:是的,因为作为一个所谓的小团队,您不必处理硬件的设置和维护(避免成本)。

          有没有办法管理这种测量表? (数据是 每10秒增加一次,可以多次查询)?

          再次,将influxdb 视为一种更专业的解决方案,它将帮助您解决有关时间序列数据管理的许多典型问题。

          如果有办法优化我的表格,请告诉我?

          查看所有数据库专家的其他精彩答案。

          我是否应该将传感器测量收集功能部署为微型 服务以提高性能和可扩展性?

          您的收集函数实际上是一个数据流端点,因此您可能需要为此目的使用流处理器,例如 Kafka。现在,当您的流保存在一个大队列中(在 kafka 中称为主题)时,您就有时间使用任何大数据技术(例如使用spark/hadoop)处理它并将其存储在任何地方需要格式/分析(这很可能是传统 rdb 或 nosql db 发挥作用的地方)。

          微服务是一种架构风格,旨在帮助具有复杂解决方案的大型组织应对组织挑战。取决于您的应用程序设置有多大,但如果您的开发/devops 团队中有超过 10 人,您可能需要考虑将您的实现拆分为多个微服务。更多信息请阅读this awesome article

          【讨论】:

            猜你喜欢
            • 2020-03-29
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-19
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多