小 T 导读:在中移物联网的智慧出行场景中,须要存储车联网设施的轨迹点,还要反对对车辆轨迹进行查问。为了更好地进行数据处理,他们在 2021 年上线了 TDengine 2.0 版本的 5 节点 3 正本集群。3.0 公布后,它的泛滥个性吸引着中移物联网进行了大版本升级。本文具体分享了中移物联网在 3.0 我的项目的业务实际和全新体验,以此给大家作参考。
对于中移物联网:
中移物联网有限公司是中国移动通信集团有限公司出资成立的全资子公司。公司依照中国移动整体策略布局,围绕“物联网业务服务的撑持者、专用模组和芯片的提供者、物联网专用产品的推动者”的策略定位,专业化经营物联网专用网络,设计生产物联网专用模组和芯片,打造智慧出行、智能家居、智能穿戴等特色产品,开发经营物联网连贯治理平台 OneLink 和物联网开放平台 OneNET,推广物联网解决方案,造成了五大方向业务布局和物联网“云 - 网 - 边 - 端”全方位的体系架构。
业务背景:
智慧出行是中移物联网的一个十分典型的场景,咱们须要存储车联网设施的轨迹点,还要反对对轨迹进行查问。最后咱们应用的是 Oracle 小型机单表分区存储数据,运维简单不便治理。2017 年,响应团体去 IOE 的要求,该我的项目开始应用 MySQL 集群。2019 年,产品提出了更高的数据存储需要,咱们又开始调研国产数据库 TiDB,但因为其存储老本过高,不适宜轨迹存储这种低价值的数据,而且不能解决行业客户轨迹数据存储周期定制化的须要,因而咱们开始持续调研新的存储计划——国产开源时序数据库(Time Series Database)TDengine 就是这个时候进入了咱们的视线。
在调研中咱们发现,智慧出行轨迹数据的特点人造适宜 TDengine:高频写入,每天写入约两亿条轨迹数据;低频查问,通常是由用户触发,查问最近几天的轨迹;企业用户有定制轨迹存储周期的需要;不针对 OLAP 需要,数据价值密度低。
因而,在经验了谨严的选型测试后,咱们最终确定抉择 TDengine 作为新的数据存储引擎。具体选型过程和我的项目历史背景能够参考 2.x 版本的案例《存储空间降为原来的 1 /7,TDengine 在中移物联网轨迹数据存储中的利用》。
革新后零碎的整体架构如下图所示:
咱们在 2021 年上线 TDengine 的 2.4.0.18 的 5 节点 3 正本集群稳固运行至今。往年 3.0 公布后,它的泛滥个性非常吸引咱们,其中最典型的几个包含:Raft 协定的引入使 TDengine 领有了更规范的一致性算法存储引擎的重构优化了 2.x 版本的设计查问灵便度大幅晋升,可实现的需要变得多元化反对更弱小的流式计算
因而,只管 2 – 3 版本底层数据文件并不兼容,咱们还是本人写了程序把数据迁徙到了 3.0.2.5 版本,以至于前面官网正式公布了企业版迁徙工具 taosX 的时候,咱们早就先走一步了。
3.0 应用体验:
TDengine 3.0 的装置部署上保留了和 2.0 一样的简略易用模式,降级操作只须要备份数据文件目录,笼罩装置即可,而且写入速度极高,靠近硬盘的间断写入性能。TDengine 的高效压缩算法,能够节俭大量存储空间,SQL 应用也非常简单。在此前对 MySQL 计划的替换中,咱们的存储空间降为原来的 1/7,能够看到,在节俭存储空间方面,TDengine 的劣势极为显著。
目前咱们共有 102 万张子表,曾经累积的总数据量曾经达到了 2000 亿行,3 正本,磁盘占用 3.1TB。在迁徙到 TDengine 3.0 之后,各方面的体现仍然十分不错:业务的写入峰值达到了 1.2-1.3w 行 /s,数据迁徙的过程中能够达到 20w 行 /s,这些状况下 TDengine 都能够轻松解决;存储大概只有 MySQL 的 1/7;读取数据性能也很突出,咱们最罕用的单设施单日查问,能够在 0.1s 内返回后果。
咱们以后应用的是 3.0.2.5 版本,然而因为业务自身不容许停机,所以没方法做离线降级。因而,后续会由 TDengine 企业版团队帮助咱们在线降级至最新版本(以后最新版本为 3.0.5.1)。
建模设计:
在库表设计上,咱们使用了主动建表来写入数据,每个终端设备产生的轨迹点位数据在第一次入库的时候主动创立子表,这样只须要建一个 database 和业务需要的超级表就能够了,省掉了数据入库时的校验和建表操作。
值得一提的是,在 2.x 时代,元数据是在治理节点上集中存储的,因而在过后的版本中,主动建表的速度会受到单线程工作能力的制约,过后大略最高每秒只能创立 6000 个子表左右,不过过后咱们也没有这么高的建表频率所以也没有受到太大影响。通过重构之后,3.0 的元数据曾经齐全做到了分布式存储,所有 vnode 都会独立存储本人表的元数据并解决写入操作,所以主动建表的写入效率曾经大幅减少。
咱们的超级表建表语句如下,能够给大家参考:
1. 车辆历史状态、地位:
create stable device_statushis (pos_time TIMESTAMP, sample_time TIMESTAMP, record_time TIMESTAMP, online_status SMALLINT, alarm_status SMALLINT, pos_method SMALLINT, pos_precision SMALLINT, pos_longitude DOUBLE, pos_latitude DOUBLE, pos_altitude DOUBLE, pos_speed FLOAT, pos_direction FLOAT, acc_forward FLOAT, acc_side FLOAT, acc_verticle FLOAT, rollover_level SMALLINT, power_voltage FLOAT, acc_status SMALLINT, satellite_num SMALLINT) tags(device_id BINARY(32) ) ;
2. 车辆事件:四急 (急减速 急加速 急刹车 急转弯)
CREATE STABLE `emg_info` (`pos_time` TIMESTAMP, `sample_time` TIMESTAMP, `record_time` TIMESTAMP, `duration` SMALLINT, `mid_interval` SMALLINT, `mid_number` SMALLINT, `pre_number` SMALLINT, `pre_interval` SMALLINT, `start_time` TIMESTAMP, `end_time` TIMESTAMP, `start_lat` DOUBLE, `end_lat` DOUBLE, `start_lng` DOUBLE, `end_lng` DOUBLE, `event_type` SMALLINT, `sample_info` NCHAR(2048), `parameter_type` NCHAR(10)) TAGS (`device_id` VARCHAR(32), `app_code` NCHAR(32));
3.GPS 信息:
CREATE STABLE `gps_info` (`pos_time` TIMESTAMP, `sample_time` TIMESTAMP, `record_time` TIMESTAMP, `online_status` SMALLINT, `alarm_status` SMALLINT, `pos_method` SMALLINT, `pos_precision` SMALLINT, `pos_longitude` DOUBLE, `pos_latitude` DOUBLE, `pos_altitude` DOUBLE, `pos_speed` FLOAT, `pos_direction` FLOAT, `acc_forward` FLOAT, `acc_side` FLOAT, `acc_verticle` FLOAT, `rollover_level` SMALLINT, `power_voltage` FLOAT, `acc_status` SMALLINT, `satellite_num` SMALLINT) TAGS (`device_id` VARCHAR(32), `app_code` NCHAR(32), `device_hash` INT);
4. 汽车总线数据:
CREATE STABLE `can_info` (`pos_time` TIMESTAMP, `sample_time` TIMESTAMP, `record_time` TIMESTAMP, `gas_pedal_position` FLOAT, `spark_angle` FLOAT, `total_fuel_consumption` INT, `storage_battery_voltage` FLOAT, `latest_engine_runtime` INT, `fuel_pressure` INT, `distance_after_mil` INT, `long_term_fuel_trim` FLOAT, `engine_rpm` INT, `intake_manifold_pressure` SMALLINT, `distance_total` INT, `engine_inlet_port_temp` SMALLINT, `calcu_load` TINYINT, `vehicle_speed` SMALLINT, `fuel_type` NCHAR(30), `area_code` INT) TAGS (`device_id` VARCHAR(32), `app_code` NCHAR(32));
在应用层,因为咱们存储的数据是车辆轨迹数据,因而会做很多对于车辆轨迹数据的剖析,比方:热点路线、轨迹段数据、停留点、行驶事件(急转弯、急减速、急加速、车辆其它信息),但因为 TDengine 始终以来都是时序数据库,并没有地理信息相干的计算函数,所以在这块咱们本人写了很多函数,通过 Spark 的 RDD 来进行了计算剖析,最初再把剖析后的数据返回给客户端。
将来瞻望:
目前 TDengine 可能很好地解决咱们的需要,尤其是弱小的存取能力是咱们最称心的中央。但近期我从官网人员处得悉,从行将于 7 月份公布的 3.0.6.0 版本开始,TDengine 将提供全新的数据类型 geometry 用于点线面等几何类型的存储,并且会逐渐提供一套合乎 OGC(Open Geospatial Consortium) 规范的 SQL 函数,包含几何输入输出、空间关系、几何测量、汇合操作和几何解决等等。
其实通过咱们察看,还是有很多车联网用户对于轨迹剖析有应用需要,如果 TDengine 能够残缺反对到空间数据的解决,这样咱们的零碎架构将会进一步简化,连 Spark 都能够不必了,这就能够说是齐全意义上地应用了 All in one 的时序数据处理引擎。
惋惜的是,目前因为咱们历史数据的经纬度都是通过独自列来存储的,对于 Geometry 带来的全新数据类型,咱们宏大的历史数据量和应用层是很难疾速调整的,所以只能在测试环境利用,先逐步试用起来。
最初,祝 TDengine 越来越好,最终成为时序数据库的事实标准。
作者介绍:薛超,中移物联网数据库运维高级工程师,10 年数据库运维经验,2017 年退出中移物联网,负责智能硬件产品部数据库相干工作,专一于数据库优化和推动架构演进;近年来次要钻研国产新型数据库,目前所在部门全副业务曾经去“O”,在此过程中,积攒了大量新型数据库的运维教训。