TSDB(Time Series Database)时序列数据库,我们可以简单的理解为一个优化后用来处理时间序列数据的软件,并且数据中的数组是由时间进行索引的。
为什么需要时序数据库:
试想一下:Tesla 自动驾驶、华尔街自动交易算法、智能家居、能够实现日内闪电般运抵的交通网络和纽约市警察局发布的开放数据,它们都有哪些共同点?
一方面,它们预示着我们的世界正以曲速般变化,我们捕获和解析的数据比以往更多,速度比以往更快。
但是,如果仔细观察你会发现,这些应用程序都需要一种特殊的数据:
- 自动驾驶汽车持续收集所处环境中的变化数据
- 自动交易算法持续收集市场的变化数据
- 智能家居系统持续监控房屋内的变化,调整温度,识别侵入者,对于使用者总是有求必应(“Alexa,播放一些轻松的音乐”)。
- 零售行业精确高效地监控资产运转状况,使得日内运抵的成本足够低廉且能够为绝大多数人所使用。
- 纽约警察局通过跟踪车辆来更好地履行其职责(例如,分析911 报警电话的响应次数)
- 为了保障用户的使用体验,将用户的每次网络卡顿、网络延迟都会记录到时序数据库。由时序数据库直接生成报表以供技术产品做分析,尽早的发现、解决问题,保证用户的使用体验。
这些应用程序均依赖一种衡量事物随时间的变化的数据形式,这里的时间不只是一个度量标准,而是一个坐标的主坐标轴。
这就是时间序列数据,它渐渐在我们的世界中发挥更大的作用。
时间序列数据库的特点:
- 大部分时间都是写入操作。
- 写入操作几乎是顺序添加,大多数时候数据到达后都以时间排序。
- 写操作很少写入很久之前的数据,也很少更新数据。大多数情况在数据被采集到数秒或者数分钟后就会被写入数据库。
- 删除操作一般为区块删除,选定开始的历史时间并指定后续的区块。很少单独删除某个时间或者分开的随机时间的数据。
- 基本数据大,一般超过内存大小。一般选取的只是其一小部分且没有规律,缓存几乎不起任何作用。
- 读操作是十分典型的升序或者降序的顺序读。
- 高并发的读操作十分常见。
常见的时间序列数据库:
TSDB项目 |
官网 |
---|---|
influxDB | https://influxdata.com/ |
RRDtool | http://oss.oetiker.ch/rrdtool/ |
Graphite | http://graphiteapp.org/ |
OpenTSDB | http://opentsdb.net/ |
Kdb+ | http://kx.com/ |
Druid | http://druid.io/ |
KairosDB | http://kairosdb.github.io/ |
Prometheus | https://prometheus.io/ |
时间序列数据库存储:
基本概念:
数据库的一些基本概念(不同的时序数据库称呼略有不同)。
metric: 度量,相当于关系型数据库中的table。
data point: 数据点,相当于关系型数据库中的row。
timestamp:时间戳,代表数据点产生的时间。
field: 度量下的不同字段。比如位置这个度量具有经度和纬度两个field。一般情况下存放的是会随着时间戳的变化而变化的数据。
tag: 标签,或者附加信息。一般存放的是并不随着时间戳变化的属性信息。timestamp加上所有的tags可以认为是table的primary key。
如下图,度量为Wind,每一个数据点都具有一个timestamp,两个field:direction和speed,两个tag:sensor、city。它的第一行和第三行,存放的都是sensor号码为95D8-7913的设备,属性城市是上海。随着时间的变化,风向和风速都发生了改变,风向从23.4变成23.2;而风速从3.4变成了3.3。
InfluxDB:
非常优秀的时序数据库,但只有单机版是免费开源的,集群版本是要收费的。从单机版本中可以一窥其存储方案:在单机上InfluxDB采取类似于LSM tree的存储结构TSM;而分片的方案InfluxDB先通过+(事实上还要加上retentionPolicy)确定ShardGroup,再通过+的hash code确定到具体的Shard。
这里timestamp默认情况下是7天对齐,也就是说7天的时序数据会在一个Shard中。
Kairosdb:
底层使用Cassandra作为分布式存储引擎,如上文提到单机上采用的是LSM tree。
Cassandra有两级索引:partition key和clustering key。其中partition key是其分片ID,使用的是一致性哈希;而clustering key在一个partition key中保证有序。
Kairosdb利用Cassandra的特性,将 ++<数据类型>+作为partition key,数据点时间在timestamp上的偏移作为clustering key,其有序性方便做基于时间范围的查询。
partition key中的timestamp是3周对齐的,也就是说21天的时序数据会在一个clustering key下。3周的毫秒数是18亿正好小于Cassandra每行列数20亿的限制。
OpenTsdb:
底层使用Hbase作为其分布式存储引擎,采用的也是LSM tree。
Hbase采用范围划分的分片方式。使用row key做分片,保证其全局有序。每个row key下可以有多个column family。每个column family下可以有多个column。
上图是OpenTsdb的row key组织方式。不同于别的时序数据库,由于Hbase的row key全局有序,所以增加了可选的salt以达到更好的数据分布,避免热点产生。再由与timestamp间的偏移和数据类型组成column qualifier。
他的timestamp是小时对齐的,也就是说一个row key下最多存储一个小时的数据。并且需要将构成row key的metric和tags都转成对应的uid来减少存储空间,避免Hfile索引太大。下图是真实的row key示例。
时间序列数据库问题:
l 时序数据的写入:如何支持每秒钟上千万上亿数据点的写入。
l 时序数据的读取:又如何支持在秒级对上亿数据的分组聚合运算。
l 成本敏感:由海量数据存储带来的是成本问题。如何更低成本的存储这些数据,将成为时序数据库需要解决的重中之重。
参考资料:
https://www.hi-linux.com/posts/25047.html
https://www.infoq.cn/article/2017/07/Why-time-series-database
https://juejin.im/entry/5915614f8d6d8100585e753d