0%

lwh 时序数据库

1.时序场景特点

  • 写入平稳、高并发高吞吐:时序数据的产生通常是以一个固定的时间频率产生,不会受其他因素的制约,其数据生成的速度是相对比较平稳的。时序数据是由每个个体独立生成,所以当个体数量众多时,写入的并发和吞吐量都是很高的
  • 数据量大:每天可能会有TB,PB级的数据需要存储
  • 写多读少:监控的指标很多,但是通常只关心几个特定的指标、特定的场景。
  • 实时写入:时序数据的写入是实时的,且每次写入都是最近生成的数据。因为其数据生成是随着时间推进的,很少有更新删除的操作。
  • 近期数据的关注度更高,时间久远的数据极少被访问,冷热分明
  • 多维查询、分析

2.对时序数据库的要求

  • 高吞吐、高并发的写入能力:时序数据具有典型的写多读少特征,在读和写上,首要权衡的是写的能力。对于数据库的高并发、高吞吐写入能力有很高的要求。
  • 高可用:分布式架构,系统要具有水平扩展的能力。
  • 数据分级存储 :将最近小时级别的数据放到内存中,将最近天级别的数据放到SSD,更久远的数据放到更加廉价的HDD或者直接使用TTL过期淘汰掉。
  • 高压缩率:一方面是节省成本,另一个方面是压缩后的数据可以更容易保证存储到内存中
  • 多维度查询、聚合:交互级的查询延迟,并且是在数据基数(TB级)较大的情况下,也能够达到很低的查询延迟。在很大的数据量的基础上将满足条件的原始数据查询出来并聚合,原始值可能因为时间比较久远而不在内存。

3.时序建模

核心概念

  • metric 采集的数据指标
  • tag 标签
  • field 域
  • timestamp 时间戳

按数据源建模

image-20210407153555192

按指标建模

4.时序数据库分类

第一种,在关系数据库基础上进行改进的时序数据库,比如基于PG开发的Timescale。

第二种,在KV数据库的基础之上进行改进的时序数据库,比如,基于HBase开发的OpenTSDB、基于Cassandra的KairosDB

第三种,为时序数据量身定制的时序数据库,InfluxDB、ApacheIoTDB等

5.时序数据为什么不适合存在关系型数据库

  • 存储成本大 对时序数据的压缩不佳
  • 维护成本高 单机系统
  • 写入吞吐差 单机写入吞吐低,无法满足千万级的写入压力
  • 查询性能差 适用于交易处理,海量数据的聚合能力差

基于B/B+树:造成很多随机IO 存储的地址不连续->关系型数据库写入速度慢

如果一个节点已经写入磁盘了,后面树形发生变化之后,节点分裂,原先存储到一个磁盘块的数据,就会分开存储到2个新的磁盘块,那么原先的磁盘块就要删除。这样反复的操作,那就造成了Btree/B+tree很多的随机IO

6.LSM tree

核心思路:假定内存足够大,因此不需要每次有数据更新就必须将数据写入到磁盘中,而可以先将最新的数据驻留在内存中,等到积累到足够多之后,再使用归并排序的方式将内存内的数据合并追加到磁盘队尾。放弃部分读能力,换取写能力。

WAL 预写log 。当插入一条数据时,数据先顺序写入 WAL 文件中,之后插入到内存中的 MemTable 中。这样就保证了数据的持久化,不会丢失数据,并且都是顺序写,速度很快。

MemTable: 对应的就是 WAL 文件,是该文件内容在内存中的存储结构。写入操作会直接将数据写入到Memtable后返回。读取操作又会首先尝试从Memtable中进行查询,允许写入和读取。当Memtable写入的数据占用内存到达指定数量,则自动转换为Immutable Memtable,等待Dump到磁盘中,系统会自动生成新的Memtable供写操作写入新数据。

SSTable: 是 MemTable 中的数据在磁盘上的有序存储,其内部数据是根据 key 从小到大排列的。通常为了加快查找的速度,需要在 SSTable 中加入数据索引,可以快读定位到指定的 k-v 数据

7.基于kv

​ 基于LSM设计的面向分布式场景的HBase,再基于HBase设计了openTSDB。这类时序数据库都是采用了一个比较成熟的数据库来作为底层存储引擎。自己的主要逻辑仅仅是在存储引擎层之上很薄的一个逻辑层

基于HBase的数据库的问题?

  • 为了套用HBase结构,存储中有很多无用的信息。Rowkey里面的metric是一个业务字符串,这些数据在实际存储过程中很多冗余,造成存储成本的浪费
  • 数据采集指标冗余
  • HBase是弱类型问题,不能对Value部分根据业务的不同字段类型进行专门的压缩
  • Rowkey部分包含很多tag信息,没有对Rowkey和tag进行倒排索引,不能完全保证多维度的查询能力

openTSDB的优化:

  • 时间粒度为小时,每次读一个小时
  • 将业务字符串映射为uid,简化存储

8.原生时序数据库

基于LSM设计面向时序数据的influxDb,ioTDB

influxdb(tsm)

  • tags不再冗余存储 metric+tag -> series key

  • 数据分区:按不同的时间范围划分为不同的分区(Shard),写入通常是在最新的分区,而不会散列到多个分区。分区的优点是数据回收的物理删除非常简单,直接把整个分区删除即可

  • 针对时序和不同类型的压缩方案 delta-delta

    • 时间戳8byte-> 64bit 最大间隔3600秒->13bit
    • delta 64 + 13 *7 = 155bit
    • delta of delta 64 + 9 4 + 1 3 = 103bit
  • 倒排索引 高效查找

  • 对cache的设计:Cache内部提供了一个ring结构,取series key前8个bit进行hash,来对数据进行分桶/分区管理,降低读写时候锁的竞争。确保连续数据存储在一个磁盘块。

  • 对于时序实用的功能:

    • ContinuousQueries,每小时触发一次,每次待计算数据区间是90分钟,分组区间是30分钟

参考

时序数据库技术体系-时序数据存储模型设计:http://hbasefly.com/2017/11/19/timeseries-database-2/

No.1-时序数据库随笔 - Time Series DBMS 综述:https://developer.aliyun.com/article/782579?spm=a2c6h.13262185.0.0.60b372994locIc

Writing a Time Series Database from Scratch:https://fabxc.org/tsdb/

时间序列数据的存储和计算 - 概述:https://zhuanlan.zhihu.com/p/32709932

B+tree:https://zhuanlan.zhihu.com/p/149287061

delta-of-delta编码:https://blog.csdn.net/yapuge/article/details/102765248