IIoT平台中的数据库:Mail.ru云解决方案如何处理来自多个设备的PB级数据


嗨,我是Mail.ru Cloud Solutions物联网解决方案开发小组负责人Andrey Sergeev 众所周知不存在通用数据库。尤其是当您需要构建一个物联网平台时,该平台能够以接近实时的方式每秒处理来自传感器的数百万个事件。

我们的产品Mail.ru IoT平台始于基于Tarantool的原型。我将告诉您我们走的路,遇到的问题以及如何解决它们。并且还展示了工业物联网现代平台的当前架构。在本文中,我们将讨论:

  • 关于我们的数据库要求,通用解决方案和CAP定理;
  • 一种方法中的数据库+应用程序服务器是否是灵丹妙药;
  • 关于平台及其中使用的数据库的发展;
  • , Tarantool’ .

, @Databases Meetup by Mail.ru Cloud Solutions. , :



Mail.ru IoT Platform


我们的产品Mail.ru IoT Platform是一个可扩展且独立于硬件的平台,用于为工业物联网构建解决方案。它允许您同时从成千上万个设备中收集数据并以接近实时的模式(即准实时)处理此流,包括使用自定义规则-Python或Lua中的脚本。

该平台可以存储来自源的无限数量的原始数据,提供了一组现成的用于可视化和分析数据的组件,用于预测分析的内置工具以及基于该平台创建应用程序。


这就是Mail.ru IoT平台设备的外观。

目前,该平台可根据客户设施上的内部部署模型进行安装,今年计划在公共云中发布该平台即服务。

Tarantool原型:这一切是如何开始的


我们的平台最初是一个试点项目,它是一个具有单一实例Tarantool的原型,其主要功能是从OPC服务器接收数据流,使用Lua脚本实时处理接收到的事件,基于它们监视关键指标,并在其中生成事件和警报。上级系统。


Tarantool原型方案

该原型甚至在战斗条件下在一个群集地点工作了几个月,它是伊拉克公海,波斯湾的石油生产平台。他监控了关键指标,并为可视化系统和事件日志提供了数据。飞行员被认为是成功的,但是原型通常是这样-它并没有超出飞行员的范围,并且原型被搁置了很长时间,直到它落入我们的手中。

我们开发物联网平台的目标


与原型一起,我们获得了任务-制作功能完善,可扩展且具有容错能力的IoT平台,然后可以将其作为服务在公共云中启动。

我们需要构建一个具有以下介绍的平台:

  1. 同时连接数十万个设备。
  2. 每秒接收数百万个事件。
  3. 流处理接近实时。
  4. 原始数据存储了几年。
  5. 流分析和历史分析工具。
  6. 多个数据中心的部署支持可最大程度地恢复灾难。

平台原型的优缺点


在开始积极开发时,原型如下所示:

  • Tarantool,用作数据库+应用程序服务器(Application Server);
  • 所有数据都存储在Tarantool存储器中;
  • 同一Tarantool中Lua上的一个应用程序,它执行接收数据,处理数据以及对传入数据调用用户脚本的功能。

这种构建应用程序的方法具有以下优点

  1. 代码和数据在一个地方,这使您可以直接在应用程序的内存中对数据进行操作,并消除了传统应用程序典型的网络访问开销。
  2. Tarantool使用Lua的JIT(Just in Time Compiler),在编译时将Lua代码编译为机器代码,从而允许简单的Lua脚本以与C代码相当的速度运行(来自一个内核的40,000 RPS-这不是限制) !)。
  3. Tarantool基于协作多任务处理,也就是说,对存储过程的每次调用都是在其自己的光纤中启动的,这是协程的类似物,这在具有I / O操作(例如网络访问)的任务中提供了更大的性能提升。
  4. 有效利用资源-很少有工具可以从单个CPU内核每秒处理40,000个请求。

但是有明显的缺点

  1. 我们需要将设备中的原始数据存储数年,但是Tarantool没有数百PB的内存。
  2. 第一个优点的直接结果是:平台的整个代码都是数据库中的存储过程,这意味着对平台代码库的任何更新都是数据库的更新,这是非常痛苦的。
  3. , . , Tarantool 24-32 (Tarantool ) . — Tarantool, .
  4. . - , Tarantool Lua , - , LuaJIT .

结论: Tarantool是创建MVP的不错选择,但是对于功能齐全,可扩展,易于支持且具有容错能力的IoT平台,该平台可以接收,处理和存储来自成千上万个设备的数据,则不适合。

我们想要摆脱的原型的主要痛苦


首先,我们希望解决原型的两个难题:

  1. 摆脱数据库+应用程序服务的概念。我们想要更新应用程序代码,而不管数据存储区如何。
  2. 简化负载下的动态缩放。我想获得尽可能简单的独立的水平缩放功能。

为了解决这些问题,我们选择了一种尚未经过测试的创新方法:微服务体系结构以及将服务分为无状态(应用程序)和有状态(数据库)数据库。

为了进一步促进无状态服务的运营和水平扩展,我们将它们进行了容器化并采用了Kubernetes。


我们确定了无状态服务,剩下的就是决定如何处理数据。

物联网平台的基本数据库要求


最初,我们不想围墙花园,而是希望将所有平台数据存储在一个通用数据库中。在分析了目标之后,我们得出了通用数据库的以下需求列表:

  1. ACID- — , .
  2. — .
  3. — , near real-time.
  4. — - .
  5. — , .
  6. — ( !), .
  7. — , ( !).
  8. SQL — .

CAP-


在开始对市场上的所有数据库进行排序以符合我们的要求之前,我们决定使用一个众所周知的工具CAP定理来验证我们对健康的要求。

CAP定理说,分布式系统最多可以具有以下三个属性中的两个:

  1. 一致性(数据一致性) -在某个时间点的所有计算节点中,数据不会相互矛盾。
  2. 可用性 -对分布式系统的任何请求都以正确的响应结尾,但不能保证系统中所有节点的答案都匹配。
  3. 分区容限 -即使节点之间没有连接,它们也继续彼此独立地工作。


例如,经典的CA系统是具有同步复制的PostgreSQL主从群集,经典的AP系统是Cassandra。

让我们回到我们的需求并使用CAP定理对它们进行分类:

  1. ACID交易和严格一致性(或至少不是最终一致性)是C。
  2. 用于读写的水平缩放以及高可用性是A(多主机)。
  3. 容错能力为P,当一个数据中心发生故障时,平台不应死亡。


结论:我们需要的通用数据库必须具有CAP定理的所有三个属性,这意味着没有满足所有需求的通用数据库。

为物联网平台使用的数据选择数据库


如果您无法选择通用数据库,我们决定选择平台将使用的数据类型,并为每种类型选择一个数据库。

首先,我们将数据分为两种类型:

  1. - 信息是世界,设备,设置,规则,几乎所有数据(传输终端设备的数据除外)的模型。
  2. 来自设备的原始数据-来自设备的传感器读数,遥测和服务信息。实际上,这些是时间序列,其中每个单独的消息都包含一个值和一个时间戳。

选择元数据数据库


元数据的数据库要求。元数据本质上是关系的。它们的特点是数量很少,很少修改,但是它们是重要的数据,不会丢失,因此即使在异步复制以及ACID事务和水平读取扩展的框架内,一致性也很重要。

此类数据相对较少,并且它们的更改相对较少,因此您可以牺牲水平缩放比例来记录,以及在发生事故时可能无法访问记录数据库。也就是说,根据CAP定理,我们需要一个CA系统。

通常情况下这是合适的。有了这样的问题说明,任何支持异步复制群集的经典关系数据库(如PostgreSQL或MySQL)都将非常适合我们。

我们平台的功能。我们还需要对具有特定要求的树木的支持。作为原型的一部分,BDVV类系统(实时数据库)具有一项功能-使用标签树对世界进行建模。它们使您可以将所有客户端设备组合为一个树形结构,这有助于管理大量设备及其显示。


这就是树状结构显示设备的样子。

这样一棵树使您可以将终端设备与环境链接起来,例如,您可以将物理上位于一间屋子中的设备放在一个子树中,这极大地简化了以后的工作。此外,这是一项方便的功能,此外,我们还想在机载雷管系统的利基市场中工作,而这种功能的存在实际上是行业标准。

为了完全实现标签树,潜在的数据库必须满足以下要求:

  1. 支持任意宽度和深度的树木。
  2. 修改ACID事务中的树元素。
  3. 遍历树时的高性能。

经典的关系数据库可以很好地处理小树,但对于任意树则不能很好地处理。

可能的解决方案。使用两个数据库-用于存储树的图形数据库和用于存储其余元信息的关系数据库。

这种方法同时具有多个重大缺点:

  1. 为了确保两个数据库之间的一致性,您需要添加一个外部事务协调器。
  2. 这种设计很难维护,也不是很可靠。
  3. 在输出中,我们得到两个数据库,而不是一个,而图形数据库仅用于支持有限的功能。


两个数据库可能但不是很好的解决方案


我们用于存储元数据的解决方案我们还想到并记得,最初在基于Tarantool的原型中实现了此功能,结果非常好。

在继续之前,我想给出一个非标准的Tarantool定义:Tarantool不是数据库,而是用于为您的特定情况构建数据库的一组原语。

开箱即用的可用原语:

  • 空间-数据库中用于存储数据的表的类似物。
  • 全面的ACID交易。
  • 使用WAL日志进行复制是异步的。
  • 支持自动重新分片的分片工具。
  • 用于存储过程的超快LuaJIT。
  • 大型标准库。
  • LuaRocks软件包管理器,提供更多软件包。

我们的CA解决方案是基于Tarantool的关系图数据库。我们已经基于Tarantool原语收集了梦想元信息存储库:

  • 数据存储空间。
  • ACID交易-可用。
  • 异步复制-可用。
  • 关系-在存储过程中完成。
  • 树-也基于存储过程。

对于这样的系统,我们拥有的集群安装是经典的-一个Master用于编写,几个Slive具有异步复制用于扩展以进行读取。

结果:关系数据库和图形数据库的快速,可扩展混合。一个Tarantool实例能够处理数千个读取请求,包括具有活动树遍历的读取请求。

选择数据库以存储设备中的数据


设备数据的数据库要求。这些数据的特征在于频繁记录和大量数据:数百万个设备,数年的存储,传入消息和已存储数据的PB级信息。它们的高可用性很重要,因为传感器读数主要取决于用户规则和我们的内部服务。

对于数据库,用于读写的水平缩放,可用性和容错性以及用于处理此数据数组(最好基于SQL)的现成分析工具的可用性非常重要。同时,我们可以牺牲一致性和ACID事务。

也就是说,在CAP定理的框架中,我们需要一个AP系统。

其他要求在确定将要存储的大量数据的位置时,我们还有一些其他要求:

  1. 时间序列-来自传感器的数据是时间序列,我想获得专门的基础。
  2. 开源-开源代码的优点不需要注释。
  3. 自由群集是新型数据库中的常见祸害。
  4. 良好的压缩-考虑到数据量以及总体上的一致性,我想有效地压缩存储的数据。
  5. 成功的操作-我们希望从一个已经有人在接近我们的负载进行积极利用的数据库开始,以最大程度地降低风险。

我们的决定ClickHouse专门满足了我们的要求-具有复制,多主数据库,分片,SQL支持和免费集群的基于时间的基于列的数据库。此外,Mail.ru在操作存储量最大的ClickHouse群集之一方面具有多年的成功经验。

但是,无论ClickHouse多么出色,我们都会遇到问题。

这些设备的数据库问题及其解决方案


写性能问题。大型数据流的写入性能立即出现问题。需要将它们尽快带入分析数据库,以便实时分析事件流的规则可以查看特定设备的历史记录,并决定是否发出警报。

解决问题。 ClickHouse不能容忍多个单个插入(插入),但可以处理大批量(批次)数据-轻松应对数百万行的记录批次。我们决定缓冲传入的数据流,然后分批粘贴此数据。


因此,我们解决了录制性能差的

问题,解决了录制问题,但是这花费了我们大量时间,使数据进入系统与​​数据出现在数据库之间的时间延迟了几秒钟。

这对于实时响应传感器数据的各种算法至关重要。

阅读性能问题。用于实时数据处理的流分析不断需要来自数据库的信息-这些是成千上万的小查询。平均而言,一个ClickHouse节点可同时容纳约一百个分析查询;该节点是为处理大量数据而很少进行的繁重分析查询而创建的。当然,这不适用于计算来自成千上万个传感器的数据流的趋势。


随着大量请求ClickHouse不能很好地工作。

解决这个问题。我们决定在ClickHouse前面放置一个缓存,其中将包含最近24小时内请求最多的热点数据。

最近24小时的数据不是一年的数据,而是相当可观的数据,因此,我们还需要一个具有水平缩放功能的AP系统,用于读写,但同时注重记录单个事件和多个事件的性能。阅读。它还需要高可用性,时间序列分析,持久性和内置TTL。

最后,我们需要一个快速的ClickHouse,它甚至可以将所有内容存储在内存中以提高速度。我们在市场上找不到任何合适的解决方案,因此我们决定在Tarantool原语的基础上构建它:

  1. 持久性-是(WAL日志+快照)。
  2. 性能-内存中有所有数据。
  3. 扩展-有复制+分片。
  4. 高可用性-有。
  5. 时间序列分析工具(分组,聚合等)-在存储过程中制作。
  6. TTL-在存储过程中使用一根背景纤维(协程)制成。

事实证明,这是一种方便且高效的解决方案-一个实例拥有10,000个RPC用于读取,其中包括多达数万个查询的分析查询。

这是生成的体系结构:


最终架构:ClickHouse作为分析数据库和Tarantool缓存,可在24小时内存储数据

新数据类型-状态及其存储


我们为所有数据选择了专门的数据库,但是开发了平台并且出现了新的数据类型-状态。状态包含设备和传感器的当前状态,以及流分析规则的各种全局变量。

例如,房间里有一个灯泡。它可以关闭也可以打开,并且您必须始终可以访问其当前状态,包括规则中的状态。另一个示例是流规则中的变量,例如某种计数器。这类数据的特点是需要频繁记录和快速访问,但与此同时,数据本身只占相对较小的数量。

元数据存储不适合这些类型的数据,因为状态可能经常更改,在我们的情况下,记录上限仅限于一个Master。自从我们的状态在三年前更改以来,长期和可操作的存储也不适合使用,因此对我们而言,快速读取访问权限很重要。

也就是说,对于存储状态的数据库而言,用于读取和写入的水平缩放,高可用性和容错性很重要,而在值/文档级别则需要一致性。您可以利用总体一致性和ACID事务。

合适的解决方案可以是任何键值或文档数据库:带阴影的Redis群集,MongoDB或Tarantool。

Tarantool的优点:

  1. 这是使用Tarantool的最流行的方法。
  2. 水平缩放-异步复制+分片。
  3. 文档级别的一致性-是。

结果,我们现在有了三个Tarantools,用于完全不同的情况:存储元信息,用于从设备快速读取数据和存储状态数据的缓存。

如何为物联网平台选择数据库


  1. 通用数据库不存在。
  2. 每种类型的数据都有自己的最适合的数据库。
  3. 有时,您所需的数据库可能在市场上不可用。
  4. Tarantool适合作为专门数据库的基础。

最初由Mail.ru Cloud Solutions @Databases Meetup上进行此演讲观看其他表演视频,在Mail.ru Group上注册Kubernetes附近的电报活动公告


还有什么要读的

  1. 为项目选择什么数据库,以免再次选择
  2. 不仅限于Ceph:还可以阻止MCS云中的存储


All Articles