共计 4272 个字符,预计需要花费 11 分钟才能阅读完成。
车联网属于物联网的一个分支,通过车载终端采集数据,利用无线网络传输到云服务平台进行持久化存储,最终提供基于实时 / 历史数据的个性化服务。
目前初创型的车辆网企业,接入的车辆通常低于 10 万,数据采集频率远远大于 1 秒。这个级别的数据规模,如果采用 HBase 系的技术方案,需要至少 6 台 8 核 32G 配置的机器,而采用 TDengine 作为数据存储引擎,一台 2 核 8G 的机器就可以完成。
技术架构
TDengine 作为时序处理引擎,可以完全不用 Kafka、HDFS/HBase/Spark、Redis 等软件,大幅简化大数据平台的设计,降低研发成本和运营成本。因为需要集成的开源组件少,因而系统可以更加健壮,也更容易保证数据的一致性。
- 基于 HBase 的解决方案,架构图如下
- 而基于 TDengine 的解决方案,架构图如下
数据模型
车载终端采集的数据字段非常多,很多企业按照国标 ISO 22901 建立数据模型,也有公司按照业务需要使用自定义的数据模型。但通常,采集数据都包含如下字段,本文也采用这种方法构造数据模型。
- 采集时间(时间戳)
- 车辆标志(字符串)
- 经度(双精度浮点)
- 维度(双精度浮点)
- 海拔(浮点)
- 方向(浮点)
- 速度(浮点)
- 车牌号(字符串)
- 车辆型号(字符串)
- 车辆 vid(字符串)
不同于其他时序数据引擎,TDengine 为每辆车单独创建一张数据表,数据字段为采集时间、车辆标志、经度、纬度、海拔、方向、速度等与时间序列相关的采集数据;标签字段为车牌号、车辆型号等车辆本身固定的描述信息。这里面有一个小技巧,浮点数据压缩比相对整型数据压缩比很差,经度纬度通常精确到小数点后 7 位,因此将经度纬度增大 1E7 倍转为长整型存储,将海拔、方向、速度增大 1E2 倍转为整型存储。
创建数据库的语句为
create database db cache 8192 ablocks 2 tblocks 1000 tables 10000;
创建超级表的 SQL 语句为
create 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),那么创建数据表的语句为
create table v1 using tags(25746,‘bmw’);
数据写入
仍然以车辆 v1 为例,写入一条记录到表 v1 的 SQL 语句为
insert into v1 values(1562150939000,1,2,3,4,5);
测试数据的生成,可以采用批量数据写入方法,类似
insert 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 条数据)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "time.h"
#include "taos.h"
int main(int argc, char *argv[]) {taos_init();
TAOS *taos = taos_connect("127.0.0.1", "root", "taosdata", NULL, 0);
if (taos == NULL) {printf("failed to connect to server, reason:%s\n", taos_errstr(taos));
exit(1);
}
if (taos_query(taos, "create database db cache 8192 ablocks 2 tblocks 1000 tables 10000") != 0) {printf("failed to create database, reason:%s\n", taos_errstr(taos));
exit(1);
}
taos_query(taos, "use db");
char sql[65000] = "create table vehicles(ts timestamp, longitude bigint, latitude bigint, altitude int, direction int, velocity int) tags(card int, model binary(10))";
if (taos_query(taos, sql) != 0) {printf("failed to create stable, reason:%s\n", taos_errstr(taos));
exit(1);
}
int begin = time(NULL);
for (int table = 0; table < 100000; ++table) {sprintf(sql, "create table v%d using vehicles tags(%d,'t%d')", table, table, table);
if (taos_query(taos, sql) != 0) {printf("failed to create table t%d, reason:%s\n", table, taos_errstr(taos));
exit(1);
}
for (int loop = 0; loop < 44; loop++) {int len = sprintf(sql, "insert into v%d values", table);
for (int row = 0; row < 1000; row++) {len += sprintf(sql + len, "(%ld,%d,%d,%d,%d,%d)", 1561910400000L + 60000L * (row + loop * 1000L), row, row, row, row, row);
}
if (taos_query(taos, sql) != 0) {printf("failed to insert table t%d, reason:%s\n", table, taos_errstr(taos));
}
}
}
int end = time(NULL);
printf("insert finished, time spend %d seconds", end - begin);
}
}
将改 C 文件命名为 test.c,在相同目录下创建 makefile 文件
ROOT = ./
TARGET = exe
LFLAGS = -Wl,-rpath,/usr/lib/ -ltaos -lpthread -lm -lrt
CFLAGS = -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/
all: $(TARGET)
exe:
gcc $(CFLAGS) ./test.c -o $(ROOT)/test $(LFLAGS)
clean:
rm $(ROOT)test
编译之后,将测试程序和数据库在同一台 2 核 8G 的台式机上运行,写入时间共计为 3946 秒,相当于 4400000000 条 /3946 秒 =111.5 万条 / 秒,折算成点数为 111.5*5=557 万点 / 秒。
insert finished, time spend 3946 seconds
该程序是单线程运行的,如将其修改成多线程,速度还会有更大提升,但是仅就目前的性能来看,对于车辆网的场景也已经足够。
数据查询
TDengine 在数据查询方面做了很多针对时序数据的优化。基于上面生成的测试数据集进行查询,这是一些常见 SQL 语句的运行结果,性能还是有点吓人的。
- 查询总数
- 单辆车的明细数据
查询类型 | 查询时间 |
---|---|
1 车当前值查询 | 2.3ms |
1 车 1 小时明细查询 | 2.1ms |
1 车 1 日明细查询 | 6.3ms |
1 车 10 日明细查询 | 15.4ms |
1 车 31 日明细查询 | 31.6ms |
- 单辆车的聚合查询
查询类型 | 查询时间 |
---|---|
1 车 1 小时聚合查询 | 1.9ms |
1 车 1 日聚合查询 | 1.7ms |
1 车 10 日聚合查询 | 2.3ms |
1 车 31 日聚合查询 | 2.2ms |
- 多辆车的单日聚合查询
查询类型 | 查询时间 |
---|---|
1 车单日聚合查询 | 3.2ms |
10 车单日聚合查询 | 5.1ms |
100 车单日聚合查询 | 10.4ms |
1000 车单日聚合查询 | 51.4ms |
10000 车单日聚合查询 | 455.9ms |
100000 车单日聚合查询 | 2074.8ms |
- 多辆车单月聚合查询
查询类型 | 查询时间 |
---|---|
1 车单月聚合查询 | 3.1ms |
10 车单月聚合查询 | 4.1ms |
100 车单月聚合查询 | 7.7ms |
1000 车单月聚合查询 | 33.7ms |
10000 车单月聚合查询 | 289.5ms |
100000 车单月聚合查询 | 1197.ms |
- 多辆车单月曲线查询
查询类型 | 查询时间 |
---|---|
1 车单月曲线查询 | 6.9ms |
10 车单月曲线查询 | 13.2ms |
100 车单月曲线查询 | 75.6ms |
1000 车单月曲线查询 | 710.9ms |
10000 车单月曲线查询 | 7137.6ms |
100000 车单月曲线查询 | 32130.8ms |
- 资源消耗
数据库服务进程只消耗了约 2.7GB 的内存,CPU 占用可以忽略不计。
结果分析
TDengine 提供的时序数据解决方案,单机情况下的平均写入速度在百万条 / 秒级别,单辆车的所有查询均能做到实时,多辆车的查询速度也非常快,是车联网乃至物联网的必备利器。
关于 TDengine
TDengine 是涛思数据拥有自主知识产权的高性能、可伸缩、高可靠、零管理的物联网大数据平台软件,可以将数据库、缓存、消息队列、流式计算等功能完全融合在一起。由于针对物联网大数据特点做了各种优化,TDengine 的数据插入、查询的性能比通用的大数据平台好 10 倍以上,存储空间也大为节省,采用 SQL 接口,与第三方软件能无缝集成,大幅简化了物联网平台的系统架构,大幅减少了研发和运维的复杂度与成本。TDengine 可广泛运用于物联网、车联网、工业大数据等领域。2019 年 7 月 12 日,TDengine 开源,在 GitHub 全球趋势排行榜上连续几天排名第一。
目前在 GitHub 上,TDengine 的 Star 数已超 10,000,GitHub 地址:https://github.com/taosdata/T…,欢迎来 GitHub 上 Star 我们!