TDengine在星诺好管车的应用实践

作者 | 焦海波,星诺信息研发总监

小 T 导读:江苏星诺信息是一家基于智能车载定位终端提供车辆定位、车队管理服务的物联网科技公司,在行业中有着十多年的服务和运营经验,软硬件开发经验丰富。好管车,是星诺信息最新研发的一套基于大数据人工智能 + 云服务的车队管理SaaS工具。好管车致力于打造一个智能化管车工具,基于独有的精准硬件设备+智能大数据算法平台,提供给政企车队及物流企业客户一套综合管理与服务解决方案,覆盖车辆精准里程、定位回放、能耗管理、行程合并、账单结算、安全监控、智能装备和统计分析等车队运营全流程,赋能车队及物流企业、提升行业整体效率。

选择TDengine Database的几个考虑

2018年12月份在InfoQ举办的全球架构师峰会上有幸结识了TDengine的创始人陶建辉先生,当时陶建辉先生演讲的主题是《快速搭建一超高性能的时序空间大数据处理平台》,作为正处于初期研发阶段的好管车系统来说,TDengine Database里很多先进的概念和设计思路都非常符合一个车联网项目的需求,不论是从业务场景还是从车联网相关数据特点出发,当时就感觉和我们的好管车项目非常的契合,并且还有一个很重要的原因,在新项目研发初期TDengine对于系统开发成本和运维成本都能做到一部分的降低,毕竟对于一个初创项目来说,验证和实验产品是最主要的目标,能快则快,在数据库和未来后期的大数据处理平台这块能有一个比较坚实的基础肯定是最好的选择。

之后便开始与涛思数据深入沟通合作,在1个月内开始了私有部署版本测试,经过初期本地部署版本的调试和对接之后,在2019年3月初我们开始了云服务版本的打通与测试。

摒弃繁杂,拥抱致简

在这个阶段我们当然也尝试过其他类型的数据库解决方案,因为研发团队精力人力有限我们几乎没有去考虑自己搭建一套大数据处理平台,毕竟要充分整合Kafka、HBase、Hadoop、Spark这一系列开源框架不仅意味要花费大量人力,还需要更多的时间去调试开源框架本身的问题,融合及联调不同框架,还存在着很多数据一致性的问题,同时也意味着后期运维成本的大幅度增加,稳定性也是个不小的未知数。

之后我们也尝试了云服务,比如阿里云的几个解决方案,表格存储、时序时空数据库TSDB版和InfluxDB版,但因为当时本身阿里云所提供的时序数据库方面的服务也是一个初期版本和方案,在很多方面其实还不是很成熟,甚至很多服务都是处于一个内测和公测的阶段,加上在接入和实际使用上的一些问题,比如没有刚开始没有类SQL的操作及查询语言,数据聚合函数方面的欠缺,最终都不是最合适的选择。还有一点,类似的云服务器在整体产品不是那么成熟的情况下,云服务厂商能提供的实际相关支持也不那么方便,毕竟通过工单打字沟通交流还是存在一定障碍的。

最终我们还是坚持了一开始的选择,选择了TDengine的云服务版本,利用阿里云的高速通道服务,打通了TDengine和我们阿里云ECS的连接,利用其高速、高效的存储和便捷的查询支持接入好管车平台。

场景契合,数据增值

在对TDengine进行一定的研究后,我们意识到TDengine是一个专门面对时序结构化数据存储分析的大数据处理软件。对于车联网的数据,绝大部分是TBox定位终端上报的数据。这些数据包括GPS坐标、油耗、里程数、加速度、起停信息等,是完全结构化的时序数据流,非常适合写入TDengine。星诺好管车的系统搭建思路如下:

TDengine 时序数据库 - TDengine在星诺好管车的应用实践 image
图 1 星诺好管车的系统搭建思路

星诺好管车SaaS服务平台基于终端上报的车辆运行状态数据,进行一系列实时及离线数据分析,针对每个TBox上报的数据,经过负载均衡平均分配到后端实时解析服务器,数据经过初步解析后直接通过TDengine提供的接口写入数据库,TDengine中我们建立了一个超级表来存储基础GPS数据,并为每辆车建立一个子表,超级表gpsinfo的tag用来存放车辆子表的静态信息,比如车辆编号、车牌号、所属用户、所属分组,这些不常变更的信息,子表则用于存放车辆的即时状态信息,包括行驶和停驶信息,例如速度、方向、经纬度、报警状态码、信号强度等十几种。

关于数据的实时分析,除了针对上报数据的即时分析,另外对于车辆异常状态的报警数据,考虑到核心解析应用的稳定性,我们利用了TDengine的消息订阅服务功能,将数据库收到并插入的新记录以消息队列的形式发出通知,由后端的几台报警信息解析服务器专门负责订阅接收通知进行进一步的业务报警分析处理。针对后期的历史数据分析,则定期执行计划任务,按时间或车辆行程规律进行日常的数据统计分析。

使用体验

TDengine Database使用标准的 SQL 语法,与MySQL相似。在项目上手成本几乎为零。针对其特点,我们对每个数据采集点单独建表,通过超级表维护公共数据字段,及其提供的聚合选择等多种查询函数,使得在多维度数据整合查询方面非常便利。根据TDengine和我公司业务,主要实现车辆信息的采集处理。

1、创建车辆信息超级表 gpsinfo, 通过超级表提取车辆信息公共字段[gps_time 、lngitude 。。] ,及车辆对应标签,车辆编号 vid 等信息,区分子表信息

--- 车辆信息表
 create table gpsinfo (
   gps_time TIMESTAMP,
   lngitude DOUBLE,
   latitude DOUBLE,
   altitude INT,
   ...
 )
 tags
(
  vid BINARY(9),
  pno_64 BINARY(40)
);

-- 根据其对表的数量没有限制,对所有车辆进行单独建表
create table  db_gps_info.vid(..) tags(...)

2、业务使用,通过超级表的查询来,聚合数据实现相应业务。

// 查询一段时间内, 终端状态信息
select first(gps_time) from gpsinfo
where tbname in (vid) and gps_time >= "xxxx-xx-xx xx:xx:xx" and  gps_time <= "xxxx-xx-xx xx:xx:xx"
group by vid

遇到的问题及解决方案

补发数据的乱序写入

在实际场景中,由于TBox使用4G网络发送采集的数据,经常出现车辆进入信号差的区域,TBox没有信号而无法实时上报数据,只能先缓存在终端本地缓存中。等到网络信号恢复后,TBox终端会先上报最新状态,然后补发缓存的数据。最开始我们发现补发的历史数据很多无法直接insert到TDengine,这是由于补发的数据时间戳往往已经不是表中最大的时间戳,此时TDengine不允许insert这些记录。改用import后,解决了补发历史数据的写入问题。

未来的展望

未来针对数据库中存储的数据我们将更多的尝试利用TDengine Database的实时流式计算特性,针对单辆车或同一客户下的多辆车的数据流进行实时聚合、统计等计算,并将计算出的衍生数据作为新的分析结果保存进TDengine,以便后期进一步的操作、统计和展示。