近百万条数据、3 秒查询,TDengine 助力北微云平台的搭建
作者:朱永杰
小 T 导读:作为一家聚焦惯性传感技术领域的企业,北微传感致力于让物联世界更美好,其研发的数百种型号的倾角传感器、电子罗盘、航姿参考系统、惯性测量单元、光纤陀螺仪、组合导航等产品,在交通运输、工程机械、航空航天、能源电力、医疗器械等领域发挥着重要的作用。随着业务的不断发展,北微传感对传感器数据的重视程度也在逐渐提高。
为了实现传感器的智能监控以及智能管理,北微传感旗下的北微云团队打造了物联网接入平台,实现传感器数据的解析、处理、可视化、状态监控、数据监测、月度数据下载、告警推送、上传日志记录等诸多功能。
这套系统在终端设备对接连接管理平台后,可通过 TCP/UDP 等形式采集终端数据,并在连接结束后将当前传输的数据集通过消息队列的形式,推送到设备管理及数据解析平台,实现对传输数据的解析以及上传日志的留档。在应用开发层,从物联网平台的基础业务场景出发,结合数据实现业务封装,提供大屏数据接口、数据状态监测等诸多功能。后续计划提供对应的 SDK,将平台数据及能力下放,方便用户在自身系统上拓展出平台提供的能力。
由于传感器设备数量众多且数据不一,连接管理平台所接收的数据传输量巨大。为了保证数据接收日志的连贯以及上传间隔的直观可视化,无论是 TCP 还是 UDP 的接收都采用了批量插入的操作,每次终端上传的突发数据量都很大,因此要求搭载的数据库要具备极高的数据吞吐率和存储低延时。
基于此,我们决定进行数据库选型,以匹配北微云平台的搭建。
一、为什么选择 TDengine?
在整套系统的构建中,用户出于对后续产品的迭代等考量,在研发初期就对数据动态化、接入设备多元化、系统性能、查询速度以及数据展现形式设定了相关的要求。
初期系统采用的是简单的单设备类型及单协议设计,数据库搭建上选用的是 MySQL+索引的方式,弊端是当数据写入过多以及查询深度过大时,时常出现数据库宕机等各种问题。此外,当接入终端的数量增加时会产生大量的时序数据,在实现存储、压缩、查询等基本需求外,还需要平衡学习及运维成本。
从以上问题和需求出发,数据库需要具备以下几点能力:
- 可以准确地记录插入时间,具有较高的查询速度、强大的数据读写及压缩能力
- 从报表的查询场景出发要具备优秀的时间检索能力,以提高月度报表的请求速度
- 提供毫秒级别的数据查询、时间轴的滑动窗口聚合以及多种针对物联网场景的函数
- 提供可以快速集成的告警组件,减少开发成本
幸运的是,我在 2020 年 3 月参与过一个空调控制系统的研发,当时采取的是 InfluxDB、TDengine 双数据库存储的形式,但在后续的迭代中已经全面转向 TDengine。在这个研发任务中,我负责的业务就是基于 TDengine 实现监测数据的可视化以及大屏展示,对于其类 SQL 的操作方式以及优秀的查询性能印象深刻。
基于以上原因,为了保证项目的快速交付以及系统的稳定运行,我们选择了 TDengine 作为北微云平台接入设备的时序数据库。
二、TDengine 的具体实践
具体到我们的场景中,使用 TDengine 建库建表的思路如下所示:
TDengine 超级表的结构十分简单,采集字段就是时间戳 ts 和采集值 data_value。但此处定义了三个标签,分别是用于描述设备的地址编码、企业分组编码以及参数编码。
从下面子表的设计中可以看到,针对大数据量以及多数据参数的查询情况,我们采取了一个数据参数、一个地址编码为一张表的存储方式,在查询时直接对设备地址编码_参数编码的表进行查询,大大降低了数据查询时间。在可视化服务通过一定算法优化的前提下,单核 2G 轻量服务器的配置,近百万条数据的分析查询时间仅在 3 秒以内。
在实际使用中,我们还发现采用 TDengine 提供的连续查询功能,可以高效处理类似于时间窗口下传感器的电量及温度场景。举个例子,以每小时为时间窗口、每半小时为前进量来统计传感器所在地点的温度:
可以通过 select * from avg_temp_100000015 order by ts desc;的形式快速获取已经存储好的数据,对于类似的按照时间周期进行折线统计的场景相当有效。反映到实际业务场景中,如下所示:
下图为 TDengine 的查询效果展示,几乎达到了所查即所得的效果。
三、北微云架构搭载 TDengine 的效果与优势
北微云采用了工业互联网平台典型的端边云系统架构,通过设备管理平台、连接管理平台、应用开发平台等几大模块的运作保障应用层业务功能的稳定,更好地服务于终端型号及解析策略配置、设备连接与管理、数据分析及监控、月度数据查询与下载等场景,同时可支持多类型终端及为其他项目提供接入的需求。下图为具体的架构示意图:
本项目中,通过各种协议以及 SDK、API 等获取的传感器数据是主要的数据来源。物联网终端设备按照固定的上传周期进行上传,随着时间的推移,传感器积累的数据量在不断增多,由此所带来的查询成本以及数据导出压力也变得相当巨大。同时,用户对于数据安全也具有较高的要求。
在咨询涛思数据的小伙伴后,我们在线上环境搭建时采用了 TDengine 双主节点部署的形式,降低了单机遇到全量查询时的数据压力,提高吞吐的同时也提升了查询响应的速度。
该项目中的应用开发平台以及设备管理平台采取了多机部署,通过设置对应的 Nginx 负载均衡策略提升系统的流畅程度。相较于北微传感之前使用的三方平台——进入设备列表至少要等待 3 秒、海量数据查询 1 分钟以上,目前情况已经有了相当大的改善:全量查询基本控制在了秒级,大屏的实时场景也可以提供毫秒级别的数据响应。
在传感器监测的场景下,系统需要根据传感器数据对不同的数据项进行监控,若超过预设阈值则进行对应的告警推送。从技术的角度讲,报警是指从最近一段时间产生的数据中筛选出符合一定条件的数据,根据定义好的计算方法得出一个结果,当结果符合某个条件且持续一定时间后,触发警告并以某种形式通知用户。在 TDengine 告警模块的帮助下,组件的开发尤其迅速,我们短短两天就完成了相关编码。
在告警组件的开发中,我们通过封装参数内置公式解析算法对请求 JSON 中的 expr(表达式以及部分函数)进行封装,为复杂的逻辑运算提供了解析与支持,并基于 Alert 组件的 RESTful 接口扩展出报警监测规则、报警监测组件以及报警监测模板的能力。
在收到规则及模板添加请求后,通过领域模型封装能力,可以快速构建符合请求规范的 JSON 形式的报警规则。在推送完成后还可以实现告警规则的本地化存储,使前端可以通过调用后端接口的方式,对已经推送的报警规则进行管理。
在对应的数据行为以及业务封装完成后,只需要通过 SpringBoot 整合 AlertManager,以实现数据的接收,再走消息总线发送到解析平台进行解析与记录,并根据扩展点和预先制定的推送方式完成告警信息的推送即成功(目前站内提供了网站弹窗以及邮箱推送的功能)。
四、写在最后
在第一期的设计中,我们针对 TDengine 提供的告警模块实现了一些内部的封装以及功能的拓展,该项目在 12 月初已经交付使用且在年后将转入第二阶段的开发。
二期中对于系统的拆分有着比较清晰的要求,在完善对外 SDK 的同时,需要将一些非核心领域的相关能力做一定的剥离,可能会将封装的告警组件通过 Java SDK 的版本暴露出去。后续平台使用稳定后会通过 GitHub、Gitee 将其进行开源,希望可以帮助有同样需求的同仁,快速扩展并设计出基于平台特色的告警组件。
✨TDengine官网首页点击查看‘源代码’,了解更多具体细节。✨