减少计算、简化架构——TDengine在灌区信息化平台中的应用
公司简介
成都禹为科技有限责任公司是一家基于多年水利行业经验成功孵化而出的高科技企业,专注于物联网、大数据和数字孪生技术在水利行业中的应用,致力于通过自身行业经验和研发能力为水利行业管理者与建设者提供全方位的数字化解决方案和价值服务。
灌区信息化平台是以灌区内建设物理网系统、无人机系统结合卫星遥感等感知系统为基础,对灌区内的水雨情、土壤墒情、工程信息、气象信息及作物分布等信息进行监视,通过大数据分析,结合 GIS、数字孪生等技术为灌区提供量测水服务、供需水预报、水资源综合调度、水旱灾害防御、供用水管理、重点区域视频监视、远程设备控制等功能。
相较于以往的水利信息化系统,现代灌区信息化平台呈现以下特点:
- 设备厂家多,数据没有统一规范,数据质量无法保障
- 数据多且存储周期长,一个中型灌区一年数据量约为 300~500 亿条,数据要求至少保存 10 年及以上,关键数据甚至要求保存 20 年及以上
- 数据类型较为集中,主要集中在水位、流量、闸门开度、环境温湿度、土壤温湿度、雨量等
- 需要实时展示的指标较多,一般有各关键节点上的实时水位、小时平均水位、5 分钟水量、日水量等
- 个性化的数据 OLAP 需求较多,且对数据准确性要求较高
为了解耦系统中的数据接入和数据分析,我们将数据的接入和计算分析拆分为独立的通用物联网平台及大数据平台,在整个系统的技术选型方案中,我们经历了数据库&定时任务的架构、以流式计算为核心的架构和以 TDengine 为核心的架构三个阶段。
一、技术方案
1. 数据库&定时任务的架构
在系统设计之初,我们考虑直接使用 MySQL+MongoDB+定时任务的方式来支撑我们的系统:MySQL 存储所有的业务数据及维度信息;MongoDB 存储设备实时数据以及水量等业务数据;为了解决分钟水量、日水量等数据的计算,我们使用定时任务在计算时从 MongoDB 中获取实时数据,从MySQL中获取维度数据,将处理好的数据再写回 MongoDB 中,通过提前预计算的方式为前端提供数据。
但这种方式有以下几个问题:
- 无法对设备数据进行灵活的治理分析,设备数据乱序后需要通过人工干预或程序预处理的方式纠偏;
- 需要提前考虑多种维度的数据处理,以便满足实时数据展示和 OLAP 查询的需求;
- 5 分钟水量、日水量等数据使用定时任务计算会导致数据库负载过重;
- 在数据较多的情况下,MongoDB 必须使用更多的硬件资源搭建数据库集群,才能满足存储和数据查询的要求。
2. 以流式计算为核心的架构
鉴于在数据库&定时任务的架构方案中出现的数据处理较慢的问题,结合笔者在过往工作中所积累的经验,我们设计了流式计算数据架构方案。
数据通过物联网系统进入系统,经过处理后会根据设备类型被标准化为统一格式的数据,然后数据被写入 OpenTSDB 和 Kafka 中,供 Flink 消费。Flink 按照 Job 定义消费 Kafka 数据,并按照 MySQL 中的维表信息进行加工处理,然后写入 MongoDB 中;同时还将数据处理为分钟水量、日数量等业务实时所需的数据。
相较于上一版方案,数据乱序问题以及数据实时计算的问题得到了良好的解决,同时也能很好地满足 OLAP 等业务对数据的查询要求。但该方案增加了 Flink、Kafka 以及 OpenTSDB 三个较为大型的工具,无形中增加了项目的建设成本及运维成本。是否有一种平台可以集数据存储、消息队列、大数据计算及分析于一身,且不会过多的增加硬件成本?TDengine 终走进了我们的视线。
3. 以 TDengine 为核心的架构
由于以上两个方案都各自有自己的缺陷,我们试着调研寻求一个更适合我们的平台方案,偶然间笔者从一位从事工业物联网多年的朋友那里了解到 TDengine 这个产品,于是我们迅速从查询效率、写入效率、稳定性、容错率以及功能完整性等方面对多个数据库进行了调研,终我们认为 TDengine 是当下适合我们的。原因如下:
- 查询和写入速度极快,亿级数据瞬间查询
- 丰富的查询方案,能够很好地满足业务需求
- 使用和部署简单,官方文档齐全,类 SQL 语法可以降低学习成本
- 支持消息队列、消息订阅、缓存、流式计算等功能,优势明显
- 集群等功能均开源免费,集群扩容容易
- 数据库资源需求较少,能够显著地减少系统的建设成本
系统架构如下图所示。
相较于上两版方案,整个架构在数据存储和数据查询分析环节更加简洁,使用 TDengine 替代了 Flink、Kafka、OpenTSDB 三个重量级工具。
4. 设备数据
原本我们的系统中就有设备模型的概念,用以隔离设备厂商之间设备数据标准不统一所带来的问题,而 TDengine 提供的超级表概念与我们的设备模型概念不谋而合!
create stable model_${设备类型编号}
(ts timestamp,${设备标准数据属性})
tags
(devicesn binary(50));
相关文章