随着汽车智能化发展,adas数据分析变得越来越重要,此处根据个人认知对adas数据平台进行分析。
- 概述
adas数据一般来自于汽车厂商发布新车的前的 实际道路测试(路试),相对于其他数据,具有如下特征:
1.数据全面,有准备的录制数据,分析数据要求多方面,如宏观、微观、问题分析、场景分析,及基于数据的模型训练
2.数据量大,通常一轮路试周期在 2周-1个月左右
3.数据格式多样化,大部分会基于autosar协议,但可演变出多种数据格式,且如有现场融合或特斯拉类,不遵守该协议的情况。
4.全为数字格式
5.具有时序性
6.可进行切割
基于以上分析,首先要对数据进行统一格式化,制定数据分析的输入标准。其次因具有不同维度的分析,采取的分析方案或知识域也不一样,所以尽量采用跨知识域存储及数据处理方案。最后,对分析结果能进行快速回溯验证。
- 统一输入标准
将不同的原始文件(路试数据)通过自有规则,转换为统一格式,该部分可以在数据分析前完成,从而和汽车路试领域解耦,该部分我们叫做"预解析"。那预解析完以怎样的格式存储呢,这是数据平台最重要的点。
举一个业务用例图:
用户 ---- 上传路试数据 ---- 转换为标准数据 ---- 标准数据再处理(运行各种模型)---- 切片(筛选出关键事件、场景,统计宏观数据)---- 对场景、关键事件进行回溯验证 ---- 出具报告。该流程是数据分析人员的基本作业流程,包含"3进3出"
|---|----------|-------------------|
| | 进 | 出 |
| 1 | 原始文件录入 | 原始文件转标准格式前 获取原始数据 |
| 2 | 标准格式存储 | 运行模型前 获取标准格式数据 |
| 3 | 回写标准数据格式 | 切片场景前 获取标准格式数据 |
可以看到 第1个进出 是没有选择的,本身就是统一输入标准。第2、3个进出就比较有讲究,相当于数据的回写,这不就是我们日常使用的数据库吗?初期我也是这么认为的,并且找了一个iotdb(时序库)作为存储,运行时从中存取数据,但很快发现问题:运行模型会将几乎所有数据运行一次,且有的模型还是"数据顺序"要求。不仅如此,切片逻辑也需全量扫描,比如定位一个场景,总不能让路试工程师哪个小本本记录,xx秒开始泊车,xx秒开始上坡,xx秒开始S弯吧。。。除此之外,还会通过数据进行相关预测,甚至做模型回灌和训练,可以看到这其中已经不仅仅是传统的数据分析,还有大量的 "数据挖掘"概念。由此得出一个结论,我们的数据是用于多方面应用的,应当具有很好的开放性。
综合以上得出两点:1.数据运行过程会进行近全量处理 2.数据访问应具有很好的开放性。
- 存储及数据处理方案
基于以上总结,处理全量数据,采用"存取一体"的lambda架构是最合适的。数据开放性上主要在于 支持不用语言高效访问,访问包含访问 时序数据、结果数据、以及中间数据。
实际应用中,我们最终基于3种方案进行了对比与选择,在此分享。分别是:基于arrow文件+spark(或等价的)、基于iotdb时序库、基于TDengine时序库。以下对三种方案做对比,分别是:全量处理方案、开放性、潜在风险
基于arrow文件+spark(或等价的)方案:
全量处理。采用 lambda架构。批处理层:数据参数,将arrow从云存储下载到本地;加速层:从本地load数据,进行自定义处理,回写arrow,回传云存储;服务层:按需下载云存储arrow文件,读取展示
开放性。原始文件访问---云端下载;过程文件---加速层程序控制;结果文件---下载访问。由于arrow支持多语言快速存取,访问速度会很快。
潜在风险。该方案采取使用时下载文件,非常依赖云存储,对云存储和宽带稳定性有较高要求。其次由于未像传统spark使用方式,将实际原始数据传输,增加了一层映射,代码难度增加。
基于iotdb时序库的方案:
全量处理。由数据库架构完成存入操作,但由于提供了TSfile挂载,可在外部写完TSfile后,挂载到数据库。相对数据库直接入库,省略了wal缓冲及记录,索引文件构建等操作,极大增加了插入速度。数据取出:java或C等只能将数据按一列一列取出,但python可直接传输numpy数据结构,传输量大大减少。非外部模型(simulink模型等)下可以采用数据库内置引擎。
开放性:原始文件访问---通过sql查询访问,除python外,速度较慢;过程文件---如取出操作则程序可控,采用内置引擎则无法提供;结果文件---通过sql访问,除python外,速度较慢。
潜在风险:全量处理时,需要控制数据总量,毕竟机器的空间是有限的,可以通过卸载存储组(类似mysql 的某个db)的方式,达到基于存储组的 "无限量"的云数据库,但恢复时需要等待较长时间(实际1-5分钟)。当需要大批量数据查询时,查询时长会增加,比如某个路试一天数据360亿个数据点,200多G,要传输多久??
基于TDengine时序库方案:
全量处理。和iotdb一样,由数据库架构完成存入操作。主要采取批量写入增加吞吐量,但wal缓冲,索引构建等基本操作是不可避免的,相对iotdb挂载文件,性能要低。可以通过集群节点增加吞吐量,但对于汇聚查询来说,需要将不同机器数据传到一台,网络资源是有限的,所以和iotdb没有区别,且在python端使用不支持numpy格式传输,在python端使用时,iotdb更优。以上情况是将数据取出来运算的评估,如果不是运行simulin等外部模型,则可采取内部引擎,无需传输直接执行回写即可,C语言特性是内存自主管控,相同数据不必拷贝多份,但在全量处理情况下,最少也得加载200多G的数据。
开放性:原始文件访问---通过sql查询访问,速度较慢;过程文件---如取出操作则程序可控,采用内置引擎则无法提供;结果文件---通过sql访问,速度较慢。
潜在风险:全量处理时,需要控制数据总量,可通过taosdump 导出数据,进行云存储,达到基于数据库的 "无限量"的云数据库。导入则必须按 库级别 进行导入,不能像iotdb一样,先挂载需要用到的tsfile,快速投入使用。当外部需要大批量数据时,查询时长会增加。
综合以上,可以看出,时序数据库具有 "重分析引擎"的特点,对于数据吞吐(存储特性)不够重视。因此如果是大批量数据迅速录入,或 具有自有分析引擎时,采用时序库是不明智的。反之,数据量较少或持续缓慢输入(如20m/s数据)时,需要依赖数据库函数及分析引擎时,选择时序库是明智的。以下是吞吐量和引擎分析表:
|------|-------------------------------------|-------------------------------------|---------------------------|
| | arrow | iotdb | tdengine |
| 数据吞吐 | 存:高,基于文件传输及快速内存映射 取:高,基于文件传输及快速内存映射 | 存:一般,先写Tsfile后挂载 取:较弱,除python外,取数较慢 | 存:弱,批量写入 取:弱, 列表取出 |
| 分析引擎 | 很弱:本身支持基本筛选功能,基本依赖外部引擎 | 一般,基于java不如基于C有性能优势 | 较好,内置引擎优秀,但udf扩展等问题严重拉低性能 |
最后,软件要实现一些功能或性能要求,通过不断演变肯定能实现,比如时序库通过优化UDF,把外部模型转换为UDF函数,再优化执行UDF的传输格式,甚至集群模式下进行 基于本地化的"分区"等,当然这是时序库本身的工作,不是使用者的工作。