使用 TDengine 快速搭建车联网平台

原创
2019/10/10 19:07
阅读数 182
车联网属于物联网的一个分支,通过车载终端采集数据,利用无线网络传输到云服务平台进行持久化存储,最终提供基于实时/历史数据的个性化服务。
目前初创型的车辆网企业,接入的车辆通常低于10万,数据采集频率远远大于1秒。这个级别的数据规模,如果采用HBase系的技术方案,需要至少6台8核32G配置的机器,而采用TDengine作为数据存储引擎,一台2核8G的机器就可以完成。

技术架构

TDengine作为时序处理引擎,可以完全不用Kafka、HDFS/HBase/Spark、Redis等软件,大幅简化大数据平台的设计,降低研发成本和运营成本。因为需要集成的开源组件少,因而系统可以更加健壮,也更容易保证数据的一致性。

  • 基于HBase的解决方案,架构图如下

图 1 基于HBase的技术架构图

  • 而基于TDengine的解决方案,架构图如下

图 2 基于TDengine的技术架构图


数据模型

车载终端采集的数据字段非常多,很多企业按照国标ISO 22901建立数据模型,也有公司按照业务需要使用自定义的数据模型。但通常,采集数据都包含如下字段,本文也采用这种方法构造数据模型。

  • 采集时间(时间戳)

  • 车辆标志(字符串)

  • 经度(双精度浮点)

  • 维度(双精度浮点)

  • 海拔(浮点)

  • 方向(浮点)

  • 速度(浮点)

  • 车牌号(字符串)

  • 车辆型号(字符串)

  • 车辆vid(字符串)

不同于其他时序数据引擎,TDengine为每辆车单独创建一张数据表,数据字段为采集时间、车辆标志、经度、纬度、海拔、方向、速度等与时间序列相关的采集数据;标签字段为车牌号、车辆型号等车辆本身固定的描述信息。这里面有一个小技巧,浮点数据压缩比相对整型数据压缩比很差,经度纬度通常精确到小数点后7位,因此将经度纬度增大1E7倍转为长整型存储,将海拔、方向、速度增大1E2倍转为整型存储。

创建数据库的语句为

1create database db cache 8192 ablocks 2 tblocks 1000 tables 10000;

创建超级表的SQL语句为

1create table vehicle(ts timestamp, longitude bigint, latitude bigint, altitude int, direction int, velocity int) tags(card int, model binary(10));

以车辆vid作为表名(例如vid为1,车牌号为25746,类型为bmw),那么创建数据表的语句为

1create table v1 using tags(25746, ‘bmw’);

数据写入

仍然以车辆v1为例,写入一条记录到表v1的SQL语句为

1insert into v1 values(1562150939000,1,2,3,4,5);

测试数据的生成,可以采用批量数据写入方法,类似

1insert into v1 values(1562150939000,1,1,1,1,1) (1562150969000,2,2,2,2,2) (1562150999000,3,3,3,3,3) (……)(……);

本文采用C语言编写了一个车辆模拟数据生成程序,该程序首先10万张数据表,然后每张数据表写入1个月的数据(数据间隔1分钟,计44000条数据)

 1#include <stdio.h> 
2#include <stdlib.h>
3#include <string.h> 
4#include <unistd.h> 
5#include "time.h"
6#include "taos.h"
7int main(int argc, char *argv[]) {
8   taos_init();
9
10   TAOS *taos = taos_connect("127.0.0.1", "root", "taosdata", NULL, 0);
11   if (taos == NULL) {
12     printf("failed to connect to server, reason:%s\n", taos_errstr(taos));
13     exit(1);
14   }
15
16   if (taos_query(taos, "create database db cache 8192 ablocks 2 tblocks 1000 tables 10000") != 0) {
17     printf("failed to create database, reason:%s\n", taos_errstr(taos));
18     exit(1);
19   }
20
21   taos_query(taos, "use db");
22
23   char sql[65000] = "create table vehicles(ts timestamp, longitude bigint, latitude bigint, altitude int, direction int, velocity int) tags(card int, model binary(10))";
24   if (taos_query(taos, sql) != 0) {
25     printf("failed to create stable, reason:%s\n", taos_errstr(taos));
26     exit(1);
27   }
28
29   int begin = time(NULL);
30   for (int table = 0; table < 100000; ++table) {
31     sprintf(sql, "create table v%d using vehicles tags(%d, 't%d')", table, table, table);
32     if (taos_query(taos, sql) != 0) {
33       printf("failed to create table t%d, reason:%s\n", table, taos_errstr(taos));
34       exit(1);
35     }
36
37     for (int loop = 0; loop < 44; loop++) {   
38       int len = sprintf(sql, "insert into v%d values", table);   
39       for (int row = 0; row < 1000; row++) {     
40         len += sprintf(sql + len, "(%ld,%d,%d,%d,%d,%d)", 1561910400000L + 60000L * (row + loop * 1000L), row, row, row, row, row);   
41       }   
42       if (taos_query(taos, sql) != 0) {     
43         printf("failed to insert table t%d, reason:%s\n", table, taos_errstr(taos));   
44       } 
45     }
46   }
47   int end = time(NULL);
48     printf("insert finished, time spend %d seconds", end - begin);
49   }
50}

将改C文件命名为test.c,在相同目录下创建makefile文件

 1ROOT = ./
2TARGET = exe
3LFLAGS = -Wl,-rpath,/usr/lib/ -ltaos -lpthread -lm -lrt 
4CFLAGS = -O3 -g -Wall -Wno-deprecated -fPIC -Wno-unused-result -Wconversion -Wno-char-subscripts -D_REENTRANT -Wno-format -D_REENTRANT -DLINUX -msse4.2 -Wno-unused-function -D_M_X64 -std=gnu99 -I/usr/local/include/taos/
5
6all: $(TARGET)
7
8exe:
9   gcc $(CFLAGS) ./test.c -o $(ROOT)/test $(LFLAGS)
10
11clean:
12   rm $(ROOT)test 

编译之后,将测试程序和数据库在同一台2核8G的台式机上运行,写入时间共计为3946秒,相当于4400000000条/3946秒=111.5万条/秒,折算成点数为111.5*5=557万点/秒。

1insert finished, time spend 3946 seconds

该程序是单线程运行的,如将其修改成多线程,速度还会有更大提升,但是仅就目前的性能来看,对于车辆网的场景也已经足够。

数据查询

TDengine在数据查询方面做了很多针对时序数据的优化。基于上面生成的测试数据集进行查询,这是一些常见SQL语句的运行结果,性能还是有点吓人的。

TDengine在数据查询方面做了很多针对时序数据的优化。基于上面生成的测试数据集进行查询,这是一些常见SQL语句的运行结果,性能还是有点吓人的。

  • 查询总数

    图 3 查询总数

  • 单辆车的明细数据

查询类型
查询时间
1车当前值查询
2.3ms
1车1小时明细查询
2.1ms
1车1日明细查询
6.3ms
1车10日明细查询
15.4ms
1车31日明细查询
31.6ms


图 4 单辆车的明细数据查询


  • 单辆车的聚合查询

查询类型
查询时间
1车1小时聚合查询
1.9ms
1车1日聚合查询 1.7ms
1车10日聚合查询 2.3ms
1车31日聚合查询
2.2ms

图 5 单辆车的聚合查询


  • 多辆车的单日聚合查询

查询类型 查询时间
1车单日聚合查询
3.2ms
10车单日聚合查询
5.1ms
100车单日聚合查询
10.4ms
1000车单日聚合查询
51.4ms
10000车单日聚合查询

455.9ms

100000车单日聚合查询 2074.8ms

图 6 多辆车的单日聚合查询


  • 多辆车单月聚合查询

查询类型 查询时间
1车单月聚合查询
3.1ms
10车单月聚合查询
4.1ms
100车单月聚合查询
7.7ms
1000车单月聚合查询
33.7ms
10000车单月聚合查询

289.5ms

100000车单月聚合查询 1197.ms

图 7 多辆车单月聚合查询


  • 多辆车单月曲线查询

查询类型 查询时间
1车单月曲线查询
6.9ms
10车单月曲线查询
13.2ms
100车单月曲线查询
75.6ms
1000车单月曲线查询
710.9ms
10000车单月曲线查询

7137.6ms

100000车单月曲线查询 2130.8ms

图 8 多辆车单月曲线查询


  • 资源消耗

图 9 Top截图


数据库服务进程只消耗了约2.7GB的内存,CPU占用可以忽略不计。

图 10 内存占用


结果分析

TDengine提供的时序数据解决方案,单机情况下的平均写入速度在百万条/秒级别,单辆车的所有查询均能做到实时,多辆车的查询速度也非常快,是车联网乃至物联网的必备利器。

关于 TDengine

TDengine是涛思数据拥有自主知识产权的高性能、可伸缩、高可靠、零管理的物联网大数据平台软件,可以将数据库、缓存、消息队列、流式计算等功能完全融合在一起。由于针对物联网大数据特点做了各种优化,TDengine的数据插入、查询的性能比通用的大数据平台好10倍以上,存储空间也大为节省,采用SQL接口,与第三方软件能无缝集成,大幅简化了物联网平台的系统架构,大幅减少了研发和运维的复杂度与成本。TDengine可广泛运用于物联网、车联网、工业大数据等领域。2019年7月12日,TDengine开源,在GitHub全球趋势排行榜上连续几天排名第一。

目前在GitHub上,TDengine的Star数已超10,000,点击「阅读原文」,欢迎来GitHub上Star我们!


本文分享自微信公众号 - TDengine(taosdata_news)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部