写点什么

深入浅出时序数据库之分级存储

  • 2017-07-25
  • 本文字数:3016 字

    阅读完需:约 10 分钟

物联网领域近期如火如荼,互联网和传统公司争相布局物联网。作为物联网领域数据存储的首选,时序数据库也越来越多进入人们的视野,而早在 2016 年 7 月,百度云在其天工物联网平台上发布了国内首个多租户的分布式时序数据库产品 TSDB,成为支持其发展制造,交通,能源,智慧城市等产业领域的核心产品,同时也成为百度战略发展产业物联网的标志性事件。

前文提到低成本的存储是时序数据库需要解决的一个主要问题,而上一篇文章介绍了通过针对时序数据的压缩方法,从利用数据本身特征的方面,降低时序数据的存储成本。

本文将介绍通过对数据进行分级存储,从使用不同存储介质,以及减少数据的副本数的方面,介绍如何在保证时序数据的查询性能的前提下,降低时序数据的存储成本。

1. 分级存储

分级存储,就是按某一特征,将数据划分为不同的级别,每个级别的数据存储在不同成本的存储介质上。为什么需要对数据进行分级存储?为什么不把所有的数据都存储在最便宜的存储介质上?这是因为在降低存储成本的同时,还需要保证数据访问的性能(我们知道,存储介质的读写性能与成本一般成正比),分级存储是对两者比较好的平衡方法。分级存储的这一思想也体现在计算机的体系结构里(寄存器、L1/L2 Cache、内存、硬盘)。

2. 时序数据的分级存储

时序数据应该按什么特征进行分级呢?时序数据的时间戳是一种非常合适的分级依据,越近期的数据查询得越多,是热数据;越久以前的数据查询得越少,是冷数据。例如,用户会经常查询一个设备的最新温度,或者查看这个设备最近 1 小时或者最近 1 天的温度曲线;很难想象用户会经常查询一个设备 1 年前的温度,这些 1 年前的数据一般会用于大数据分析或者机器学习中,而这些批处理的场景一般对查询的延时不会像交互式场景那么敏感。

如图 1 所示,一般可以将时序数据分为 3 级,第一级是最近 1 天的数据保存在内存缓存 Cache 中,第二级是最近 1 年的数据存储在固态硬盘 SSD 中,第三级是 1 年以上的数据存储在机械硬盘 HDD 中。Cache 中的数据可以使用写回(write back)或者写通(write through)的策略写入 SSD,而 SSD 中的数据可以通过后台程序定期批量的迁移到 HDD。为了保证数据持久性,一般会为数据保存 2 个或者 3 个副本,通过 EC 编码可以将副本数降低到 1.5 甚至更低,但却不影响数据的持久性。不过 EC 编码会消耗更多的 CPU 和网络带宽,进而影响查询性能,因此一般只应用在存储冷数据的 HDD 上。

(点击放大图像)

图1 时序数据的分级存储

3. 内存缓存

时序数据库大部分请求的数据都集中在最近 1 天,将这些数据保存在内存中,可以保证这些数据能被快速的读取。虽然内存的访问速度快,但是成本很高(价格大约比 SSD 高一个数量级),并且容量有限。因此需要对数据进行压缩,以减少每个数据的内存占用,压缩相关的内容已经在上一篇文章中进行了介绍,在这里不再赘述。另一方面,由于内存中的数据是易失的、非持久化的,一旦重启进程或者重启机器后就会丢失,如果不恢复数据,所有请求将落到下一级的存储上,对下一级存储造成巨大的压力。因此一般会在写入内存的同时写入本地硬盘,在重启后重新加载到内存中。

Beringei 是 Facebook 开源的一款内存时序数据库,是 Facebook 发表的 Gorilla 论文的开源实现。Beringei 使用一种三级的内存数据结构,如图 2 所示,其中第一级为分片索引,第二级为时间序列索引,第三级为时序数据,通过该数据结构可以支持快速的数据读写;Beringei 实现了一种高效的流式的压缩算法,从而使内存占用最小化;Beringei 支持写入内存的同时写入硬盘,并在重启后恢复数据。然而 Beringei 也有一些限制,譬如只支持浮点型数值、时间精度只到秒、只能按时间戳顺序的写入数据。

(点击放大图像)

图2 Beringei 的内存数据结构

4. SSD 与 HDD

用户有时会关注时序数据在过去 1 周、过去 1 个月、过去 1 年的趋势,把最近 1 年的数据存储在固态硬盘 SSD 上,可以实现在秒级甚至亚秒级读取过去 1 年的数据。而 1 年以上的时序数据则很少用于交互式查询,这些数据往往会用于大数据分析或者机器学习,这些批处理场景对查询的延时不会像交互式场景那么敏感,因此可以把这些 1 年以上的数据存储在机械硬盘 HDD 上。

SSD 的价格大约是 HDD 的几倍,但是 SSD 的性能要远远高于 HDD。在前文中我们介绍过,时序数据库会对时序数据进行分片,一个分片的数据会连续的存放在一台机器的硬盘上,因此读取一个分片的数据是顺序读取的。对于顺序读取来说,SSD 和 HDD 的性能是差不多的,因此这种存储方式对于 SSD 和 HDD 来说都是合适的。但是,一台机器上会存储大量的分片,当同时读取多个分片时,硬盘的访问就变成了随机读取。对于随机读取来说,HDD 由于需要平均 10 毫秒的寻道时间,因此只能做到百这个量级的 IOPS,而 SSD 能做到万级甚至十万级的 IOPS,比 HDD 高 2 到 3 个数量级(注 3)。由此可见,HDD 只能应付批处理这种并发量较低、顺序读取大量数据的场景,而只有 SSD 能支持高并发、低延时的交互式查询场景。

5. EC 编码

为了保证时序数据在机器宕机、硬盘故障的时候还能正常的访问、不会丢失,也就是为了保证数据的可用性和持久性,会为数据保存多个备份(也称为副本),根据可用性和持久性的需求一般是保存 2 到 3 个副本,这样当其中的 1 个或者 2 个机器宕机、硬盘故障的时候也能保证数据的正常访问以及不会丢失。但是这也大大增加了存储的成本,3 个副本就是 3 倍的存储成本。通过 EC 编码,可以将存储成本降到 1.5 倍,同时不会降低数据的可用性和持久性。

EC 编码全称是 Erasure Coding 纠删码,是一种数据保护技术,最早应用于通信行业的数据传输的数据恢复中,同时也用于 RAID-5 和 RAID-6 存储阵列技术中。EC 编码主要是利用算法对原始数据块进行编码得到校验块,并将原始数据块和校验块都存储起来。当原始数据块丢失时,通过其他原始数据块以及校验块能重新计算出丢失的数据块;当校验块丢失时,重新计算即可得到校验块。这样就能对丢失的数据进行恢复,从而达到容错的目的。对于 k 个原始数据块和 m 个校验块,算法能保证在丢失任意 m 个块后,都可以通过算法恢复出原来的 k 个原始数据块。如图 3 所示,一个生成矩阵 GT 乘以 k 个原始数据块组成的向量,可以得到由 k 个原始数据块和 m 个校验块组成的向量。

(点击放大图像)

图3 EC 编码过程(注4)

将EC 编码应用于时序数据,关键问题在于如何定义什么是数据块。一种直观的方法是一个分片作为一个数据块(注意,一个分片是存储在一个机器上的,不同的数据块是存储在不同机器上的,因此不应该把一个分片再划分为多个数据块)。但是由于分片的数据量不一致,需要将数据块都对齐到最大的数据块,而且得到的校验块也是跟最大的数据块一样大,这会导致存储空间和计算资源的浪费。举个极端的例子,譬如1 个分片的大小是1M,其他k-1 个分片的大小都是1K,那么就需要将这k-1 个分片都对齐(可以通过补0)到1M 再计算EC 编码,得到的m 个校验块都是1M 的。更好的方法是利用底层存储的数据块作为EC 编码的数据块,譬如使用Hbase 存储时序数据的话,就可以利用底层HDFS 提供的EC 编码功能

6. 总结

根据时序数据天然的时序上的冷热划分,可以对时序数据进行分级存储,将最近的最热的数据保存在内存中,将中期的次热数据存储在 SSD 上,将远期的冷数据存储在 HDD 上,能在保证查询性能的前提下,降低存储成本。另外,通过 EC 编码技术,能减少数据的副本数,从而使存储成本能降至更低的水平。

2017-07-25 17:533711

评论

发布
暂无评论
发现更多内容

利用Docker极速下载OpenJDK11源码

程序员欣宸

Docker Openjdk 6月月更

K8S V1.23 安装--Kubeadm+contained+公网 IP 多节点部署

云原生 k8s Kubernetes 集群

ABAP-时间函数

桥下本有油菜花

abap

OLAP数据库引擎如何选型?

奇点云

OLAP 数据库引擎 OLAP数据库

Serverless 在阿里云函数计算中的实践

阿里巴巴云原生

阿里云 Serverless 云原生 函数计算

Flutter的特别之处在哪里

Geek_99967b

小程序 Flutter 小菜

今晚19:00知识赋能第2期直播丨OpenHarmony智能家居项目之控制面板界面设计

OpenHarmony开发者

Open Harmony

科普达人丨漫画图解什么是eRDMA?

阿里云弹性计算

大数据 TCP/IP RDMA

用Python编写学生成绩计算系统

王小王-123

Python 成绩计算系统 成绩项目 日常编程

用Python自动化办公(csv项目实战)

王小王-123

csv python项目 自动化办公 大数据分割

阅读Skeleton.css源码,改善睡眠质量(尽管它只有419行代码)

德育处主任

CSS 源码 前端 6月月更 skeleton.css

Flutter 中的 ValueNotifier 和 ValueListenableBuilder

坚果

flutter dart 6月月更

【值得收藏】HTML5使用多种方法实现移动页面自适应手机屏幕的方法总结

迷彩

前端 自适应 HTML5, CSS3 6月月更

Dart 开发技巧

Geek_0a3437

flutter android dart 6月月更

云技能提升好伙伴,亚马逊云师兄今天正式营业

亚马逊云科技 (Amazon Web Services)

亚马逊云

我的远程办公深度体验 | 社区征文

6个核桃

初夏征文

用Python编写学生成绩管理系统(内附源码)

王小王-123

Python 系统设计 用python编写成绩管理系统 学生成绩管理系统

IOS技术分享| iOS快速生成开发文档(二)

anyRTC开发者

ios objective-c 音视频 移动开发 Jazzy

优惠券种类那么多,先区分清楚再薅羊毛!

CRMEB

Seata 与三大平台携手编程之夏,百万奖金等你来拿

阿里巴巴云原生

阿里云 开源 云原生 seata

Scala 基础 (四):函数式编程【从基础到高阶应用】

百思不得小赵

scala 函数式编程 大数据开发 6月月更

14岁懂社会-《关于“工作的幸福”这件事儿》读书笔记

懒时小窝

14岁懂社会

传统微服务框架如何无缝过渡到服务网格 ASM

阿里巴巴云原生

阿里云 微服务 云原生 Service Mesh 服务网格 服务网格

我们如何拿到自己满意的薪资呢?这些套路还是需要掌握的

看山

闲聊

直播带货源码开发中,如何降低直播中的延迟?

开源直播系统源码

软件开发 直播系统 直播源码

架构实战营模块 5 作业

Roy

架构实战营

小心transmittable-thread-local的这个坑

看山

Java’

架构实战营模块5作业

挖了蘑菇哩斯

架构实战营

用Python写一个简易机器人,超级简单!

王小王-123

python编写机器人 python项目 语法知识大全

国内首批!阿里云云原生数据湖产品通过信通院评测认证

阿里云大数据AI技术

大数据 运维 存储

揭秘得物客服IM全链路通信过程

得物技术

前端 大前端 通信 IM 客服

深入浅出时序数据库之分级存储_数据库_百度云时序数据库资深工程师_InfoQ精选文章