前言
首先了解下时序数据的一些概念:
metric: 度量的数据集,类似于关系型数据库中的 table;
point: 一个数据点,类似于关系型数据库中的 row;
timestamp: 时间戳,表征采集到数据的时间点;
tag: 维度列,代表数据的归属、属性,表明是哪个设备/模块产生的,一般不随着时间变化,供查询使用;
field: 指标列,代表数据的测量值,随时间平滑波动,不需要查询。
目前业界比较流行的几款时序数据库:
1、influxdb时序数据库是业内用得比较多的,但是开源版本没有集群的功能。
2、OpenTSDB是一个基于HBase的分布式、可伸缩的开源时序数据库。对于我们来说又太重。
3、Prometheus 定位是采集模块,其采集的数据是直接存储在本机器上的tsdb中,无集群功能,只提供了对接外部存储的接口。
由于我们有太多OLAP的分析场景,会基于时序数据做业务分析汇总。最后我们尝试了ClickHouse,兼顾时序数据的存储及OLAP分析。
度量数据建模
度量表ods_metric表定义如下:
通过val_type来定义指标值的类型,比如:0代表string、1代表float,2代表int。由于我们指标数据明细需要一直保存,所以直接使用了MergeTree引擎。也可使用Clickhouse GraphiteMergeTree引擎存储指标数据,以加速查询性能、降低存储成本。
预聚合
之前我们使用influxdb或者直接使用prometheus的tsdb,再进行指标分析汇总的时候,完全依赖于原始指标的tag信息。使用tsdb的时候,直接通过PromQL实时查询汇总。这样做有如下几个弊端:
1、随着业务的发展,维度会越来越多,通过在数据入库的时候,增加维度的方式,不便于后续扩展且难以维护。
2、时序数据库并不擅长OLAP,更别提相关数仓分层。
在Clickhouse中就容易了很多,直接使用物化视图进行维度数据的补齐
预聚合SQL如下:
图中有两个核心的物化视图:
view_metric_ods2dwd:负责维度数据的补齐。对于数据量较少的维表,在ClickHouse中直接使用字典表,数据会加载到内存中,然后使用dictGetInt64来获取,性能最好。
view_metric_mid_dws_day_device:对dws数据以天为粒度进行预聚合:
维度:天、产品、设备、指标。
指标:总数、总和、最大值、最小值。
`counts` AggregateFunction(count),
`val_sum` AggregateFunction(sum,Nullable(Float64)),
`val_max` AggregateFunction(max,Nullable(Float64)),
`val_min` AggregateFunction(min,Nullable(Float64)),
预聚合SQL如下:
汇总分析
对于天报、月报等dws、dw层数据,直接使用ETL工具编写SQL进行汇总,并将集市层数据抽取到MySQL或者HBase中。
由于中间表预聚合字段使用了AggregateFunction,在读取的时候需要通过countMerge、sumMerge、maxMerge、minMerge函数进行读取,对应预聚合中使用的countState、sumState、maxState、minStata。