简介
例如,你在负责运维一个三方的支付平台,整个系统大致分为了 交易、支付、帐务 三个系统。
假设今天凌晨两点时有用户保障,说无法创建交易,首先判断下是否是由于负载过大引起的,那么我们需要查询 “今天两点交易服务器的负载超过15的机器有那些”,对于这样的多纬度分组聚合查询,时序数据库是一个很好的选择。
时序数据
时序数据以时间作为主要的查询纬度,通常会将连续的多个时间序列数据绘制成线,可制作基于时间的多纬度报表,用揭示其趋势、规律、异常,除了实时在线预测和预警,还可以做离线的数据分析甚至是机器学习。
时序数据库就是存放时序数据的数据库,并且需要支持时序数据的快速写入、持久化、多纬度的聚合查询等基本功能。
基本概念
不同的时序数据库定义可能会有所不同,如下是其使用时常见的基本概念。
- metric 度量,相当于关系型数据库中的 table;
- data point 数据点,相当于关系型数据库中的 row;
- timestamp 时间戳,代表数据点产生的时间,一般是必须的列,常作为主健;
- field 度量下的不同字段,一般存放随着时间戳的变化而变化的数据;
- tag 标签,一般存放的是标示数据点来源的属性信息。
通常 timestamp 加上所有的 tags 可以认为是 table 的 key;如下图是采集风向的数据:
难点
时序数据库需要解决以下几个核心的问题:
- 时序数据的写入,支持每秒钟上千万上亿数据点的写入;
- 时序数据的读取,支持在秒级对上亿数据的分组聚合运算;
- 存储成本,如何保存大量的数据,降低存储成本;
存储方案
一般分为了单机存储以及分布式存储。
单机存储
如果只存储数据,直接写日志即可,但因为需要快速聚合查询,所以需要考虑存储的结构。
传统数据库存储采用的都是 B-Tree,主要用于在查询和顺序插入时有利于减少寻道次数,对于普通机械磁盘,一般寻道时间大概需要 10ms 左右,对于随机读写大部分时间会消耗在寻道上,从而导致整个查询非常慢。
虽然 SSD 具有更快的寻道时间,但并没有从根本上解决这个问题,而且会引入新的问题。
对于 90% 以上场景都是写入的时序数据库,B Tree 很明显是不合适,大部分采用 LSM Tree 替换,如 HBase、Cassandra 等;LSM Tree 包括内存里的数据结构和磁盘上的文件两部分,分别对应 HBase 里的 MemStore/HLog 以及 Cassandra 里的 MemTable/SSTable 。
LSM Tree 的操作流程如下:
- 数据写入和更新先写入内存里的数据结构,为了避免数据丢失同时也会先写到 WAL 文件中。
- 内存里的数据会定时或者当达到固定大小时刷到磁盘,这些磁盘上的文件不会被修改。
- 随着磁盘上积累的文件越来越多,会定时的进行合并操作,消除冗余数据,减少文件数量。
可以看到 LSM Tree 的核心思想就是通过内存写和后续磁盘的顺序写入获得更高的写入性能,避免了随机写入,但同时也牺牲了读取性能,因为同一个 key 的值可能存在于多个 HFile 中。
为了获取更好的读取性能,可以通过 BloomFilter 和 Compaction 机制。
分布式存储
时序数据库面向的是海量数据的写入存储读取,单机是无法解决问题的,所以需要采用多机存储,也就是分布式存储;除了数据量的问题之外,通常也可以通过分布式解决单点问题。
对于分布式存储首先需要考虑如何将数据分布到多台机器上面,目前采用最多的是分片,也可以通过单独结点管理数据分片;关于分片,其核心问题是分片方法的选择和分片的设计。
分片方法
时序数据库的分片方法和其他分布式系统是相通的,基本分为如下几种:
- 哈希分片,实现简单,均衡性较好,但是集群不易扩展,动态增删结点容易导致大部分数据重新分布。
- 一致性哈希,这种方案均衡性好,集群扩展容易,只是实现相比略微复杂,例如 DynamoDB(Amazon)、Cassandra 。
- 范围划分,通常配合全局有序,复杂度在于合并和分裂,例如 Hbase 。
分片设计
所谓的分片设计,简单来说就是通过什么计算分片,这是非常有技巧的,将会直接影响读写性能。
结合时序数据的特点,通常会根据 metric+tags 进行分片,因为往往会按照一个时间范围查询,这样相同 metric 和 tags 的数据会在一台机器上连续存放,顺序的磁盘读取是很快的。
如下图,第一行和第三行都是同样的 tag(sensor=95D8-7913;city=上海),所以分配到同样的分片,而第五行虽然也是同样的 tag,但是根据时间范围再分段,被分到了不同的分片;而第二、四、六行与上述相同。
数据查询
对于时序数据的查询分为两种:原始数据的查询和时序数据聚合运算的查询,前者主要对历史高精度时序数据的查询,查询结果粒度太细,并不利于分析其规律或者趋势,也不适合展现给用户;后者主要用来对数据做分析。