在工业MES等应用中,时序数据库是会被频繁使用的数据存储方案,由于工业环境中设备数量多,需要采集的数据点位数量庞大,因此在于数据存储和查询、统计过程中需要有一些基本方法。
1. 数据存储
关于InfluxDB的数据存储,以下是一些需要遵循的基本原则:
1.1 数据存储时长
不同类型数据的重要性是不同的,因此有些类型的数据需要保留的时间要求更长一些(例如趋势和统计数据,往往需要存储一年以上的时间),以方便管理者了解宏观信息与趋势,而明细类数据存储时间则往往要求上会更低一些(3个月~半年时间)。
根据 InfluxDB 的存储方案,数据清理是可以通过 Bucket 的存储时长设置自动完成的,不需要人工主动干预,因此统计类数据往往需要存储到独立的 Bucket 中。实际操作层面,可以考虑将分钟、小时、日、月维度的数据存储到不同的Bucket中,以方便独立控制数据存储的时长。周维度的存储数据由于比较容易从日维度数据进行聚合,可以考虑不进行单独存储。
1.2 存储空间与查询性能
InfluxDB 的数据存储与查询性能与 Series 存储的所用的 tag 数量及 tag 值数量的笛卡尔积相关,因此当tag组合数量笛卡尔积值比较大的时候(e.g. > 50万),就需要非常谨慎地设计 TAG 的存储了。特别是数据查询的内存使用也与此相关。以下是一些常用的应用措施:
-
擅用 Measurement
Series 组合笛卡尔积的计算通常是按照
Measurement
进行划分的,因此首先考虑将不同业务类型的数据存储到隔离的 Measurement 当中。 -
结合其他存储辅助方案
由于TAG值的组合空间可能巨大,但是在实际应用中可能出现的情况又是非常稀疏的,因此某些属性的值并不适合作为TAG值进行存储。
举一个实际的例子,假设某工厂有近百台设备,每台设备有数千个需要进行状态采集的子节点,则
设备ID编号 x 子节点编号
的组合数量就接近100万了。特别是单个子节点的故障概率更不高,实际产生故障的节点数据是非常稀疏的,但是由于数据存储的时长足够长,因此就比较难以预估实际的数据组合情况。对于这一类数据,就适用于其他存储方案相结合的方式,因为某一时段内,实际要查询的故障子节点数据结果并不多。
2. 数据查询与性能优化
以实际场景中遇到的应用案例:为某10台同型号设备实时记录异常状态,每天可能产生2万条异常记录,假设每条记录查询数据结果长度为200字节,则一次全量查询所返回的数据长度就会达到 3~4 MB 的长度,耗时700ms左右,在用户交互过程中体验不太能接受。这个时候需要结合实际场景考虑以下方案:
-
查询结果属性精简
InfluxDB API 的数据查询由于考虑到通用性,返回结果往往是比较冗余的,例如查询某时段内的数据明细每条记录都会返回对应的 start, stop 时间,_field 通常也是在查询指令中已经指定,对于业务并没有实际价值,网络传输开销也会更高,因此首先在结果集中使用
keep
仅保留所需的字段(或是通过drop
去掉不需要的数据字段)
|
|
-
根据时间窗口进行聚合
InfluxDB 非常擅长时间维度的数据聚合,因此数据查询并不需要返回时间段内每条数据的明细,可以按照固定的时长间隔汇总该时间段内的数据均值、加总等。这在于曲线图展示中是比较常用的场景,例如查询小时、3小时、24小时、周维度数据的数据曲线,可以通过提前计算出数据时间间隔作为聚合时间窗口。
由于曲线图实际能够展示的数据有限,一个比较实用的小习惯是,根据目前查询的时长除以预设的数据点数量(例如 500个点)。24小时曲线的聚合窗口可以设置为 24小时 / 500 ,限定数据长度 limit 1000。
-
定时任务 + 预计算
如果只需要查询统计数据,而不需要查看每条记录的具体明细,通过定时任务预计计算出用户高频查询的数据是一个很好的习惯。