时序数据库深入浅出之存储篇——本质LSMtree,同时 metric(比如温度)+tags 分片
什么是时序数据库
先来介绍什么是时序数据。时序数据是基于时间的一系列的数据。在有时间的坐标中将这些数据点连成线,往过去看可以做成多纬度报表,揭示其趋势性、规律性、异常性;往未来看可以做大数据分析,机器学习,实现预测和预警。
时序数据库就是存放时序数据的数据库,并且需要支持时序数据的快速写入、持久化、多纬度的聚合查询等基本功能。
对比传统数据库仅仅记录了数据的当前值,时序数据库则记录了所有的历史数据。同时时序数据的查询也总是会带上时间作为过滤条件。
时序数据示例
p1- 北上广三地 2015 年气温变化图
p2- 北上广三地当前温度实时展现
下面介绍下时序数据库的一些基本概念(不同的时序数据库称呼略有不同)。
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。
p3- 时序数据库基本概念图
时序数据库遇到的挑战
很多人可能认为在传统关系型数据库上加上时间戳一列就能作为时序数据库。数据量少的时候确实也没问题,但少量数据是展现的纬度有限,细节少,可置信低,更加不能用来做大数据分析。很明显时序数据库是为了解决海量数据场景而设计的。
可以看到时序数据库需要解决以下几个问题
- 时序数据的写入:如何支持每秒钟上千万上亿数据点的写入。
- 时序数据的读取:又如何支持在秒级对上亿数据的分组聚合运算。
- 成本敏感:由海量数据存储带来的是成本问题。如何更低成本的存储这些数据,将成为时序数据库需要解决的重中之重。
这些问题不是用一篇文章就能涵盖的,同时每个问题都可以从多个角度去优化解决。在这里只从数据存储这个角度来尝试回答如何解决大数据量的写入和读取。
传统数据库存储采用的都是 B tree,这是由于其在查询和顺序插入时有利于减少寻道次数的组织形式。我们知道磁盘寻道时间是非常慢的,一般在 10ms 左右。磁盘的随机读写慢就慢在寻道上面。对于随机写入 B tree 会消耗大量的时间在磁盘寻道上,导致速度很慢。我们知道 SSD 具有更快的寻道时间,但并没有从根本上解决这个问题。
对于 90% 以上场景都是写入的时序数据库,B tree 很明显是不合适的。
业界主流都是采用 LSM tree 替换 B tree,比如 Hbase, Cassandra 等 nosql 中。
分片设计
分片设计简单来说就是以什么做分片,这是非常有技巧的,会直接影响写入读取的性能。
结合时序数据库的特点,根据 metric+tags 分片是比较好的一种方式,因为往往会按照一个时间范围查询,这样相同 metric 和 tags 的数据会分配到一台机器上连续存放,顺序的磁盘读取是很快的。再结合上面讲到的单机存储内容,可以做到快速查询。
进一步我们考虑时序数据时间范围很长的情况,需要根据时间范围再将分成几段,分别存储到不同的机器上,这样对于大范围时序数据就可以支持并发查询,优化查询速度。
如下图,第一行和第三行都是同样的 tag(sensor=95D8-7913;city= 上海),所以分配到同样的分片,而第五行虽然也是同样的 tag,但是根据时间范围再分段,被分到了不同的分片。第二、四、六行属于同样的 tag(sensor=F3CC-20F3;city= 北京)也是一样的道理。
p5- 时序数据分片说明
真实案例
下面我以一批开源时序数据库作为说明。
InfluxDB:
非常优秀的时序数据库,但只有单机版是免费开源的,集群版本是要收费的。从单机版本中可以一窥其存储方案:在单机上 InfluxDB 采取类似于 LSM tree 的存储结构 TSM;而分片的方案 InfluxDB 先通过+(事实上还要加上 retentionPolicy)确定 ShardGroup,再通过+的 hash code 确定到具体的 Shard。
Kairosdb:
底层使用 Cassandra 作为分布式存储引擎,如上文提到单机上采用的是 LSM tree。
OpenTsdb:
底层使用 Hbase 作为其分布式存储引擎,采用的也是 LSM tree。
Hbase 采用范围划分的分片方式。使用 row key 做分片,保证其全局有序。每个 row key 下可以有多个 column family。每个 column family 下可以有多个 column。
结束语
可以看到各分布式时序数据库虽然存储方案都略有不同,但本质上是一致的,由于时序数据写多读少的场景,在单机上采用更加适合大吞吐量写入的单机存储结构,而在分布式方案上根据时序数据的特点来精心设计,目标就是设计的分片方案能方便时序数据的写入和读取,同时使数据分布更加均匀,尽量避免热点的产生。
相关文章
- C# 数据库存储过程的讲解应用
- SSM框架中将时间写入数据库的格式定义
- 批量修改mysql数据库引擎
- SQLite使用教程4 创建数据库
- OpenSergo & ShardingSphere 社区共建微服务视角的数据库治理标准
- 数据库1
- EntityFramework :数据库创建
- SSDB 数据库如何换用 rocksdb 引擎?
- 数据库记录安全解决方案
- 数据库内核月报 - 2015 / 11-MySQL · 社区见闻 · OOW 2015 总结 MySQL 篇
- 大数据时代的数据存储,非关系型数据库MongoDB
- 授人以渔-在 SAP MM 物料显示界面上看到一个字段,如何查找哪张数据库表的哪个字段进行的存储的试读版
- SAP CRM Enterprise Search change pointer的存储数据库表
- Atitit 综合原则 软件与项目开发中的理念信念 目录 1.1. 建议组合使用扬长避短1 1.2. 常见数据库 mysql oracle mssql mongodb postgre sqlit
- Atitit sql之道 艾龙著 attilax 1. Ddl dml3 2. Crud3 3. 高级sql3 3.1. Merge3 3.2. 数据库翻页 limit offset系列
- Database之SQL:RDBMS关系型数据库的简介、SQL语言的简介(原理/各大方言对比)、基础(SQL执行顺序/五大类函数/索引/视图/事务/安全/存储过程/游标/优化)之详细攻略
- 【万字干货】OpenMetric与时序数据库存储模型分析
- Springboot+Vue实现将图片和表单一起提交到后端,同时将图片地址保存到数据库、再次将存储的图片展示到前端vue页面
- 数据库炸了——是谁动了我的wait_timeout
- PostgreSQL的学习心得和知识总结(六十四)|关于PostgreSQL数据库 图式搜索(graph search)及递归查询 的场景说明
- mysql数据库存储过程——筑梦之路
- 为什么要用数据库
- ORMBase对象/关系型数据库映射在MVC中的应用(二)
- Facebook开源时间序列内存数据库Beringei,追求极致压缩率——如果是int根据大多数时间序列中的值与相邻数据点相比并没有显著的变化,只要使用XOR将当前值与先前值进行比较,然后存储发生变化的比特。最终,该算法将整个数据集至少压缩了90%
- scrapy 管道里面使用mysql插入数据库 python操作mysql
- 【MySQL笔记】MySQL数据库之存储过程、异常处理、事务管理的使用
- MySQL数据库操作、存储引擎