时间序列数据的存储和计算 - 开源时序数据库解析

摘要: Prometheus 开源时序数据库解析的系列文章在之前已经完成了几篇,对比分析了Hbase系的OpenTSDB、Cassandra系的KairosDB、BlueFlood及Heroic,最后是tsdb ranking top 1的InfluxDB。

点此查看原文:http://click.aliyun.com/m/40930/

Prometheus

开源时序数据库解析的系列文章在之前已经完成了几篇,对比分析了Hbase系的OpenTSDB、Cassandra系的KairosDB、BlueFlood及Heroic,最后是tsdb ranking top 1的InfluxDB。InfluxDB是从底到上纯自研的一款TSDB,在看他相关资料时对其比较感兴趣的是底层的TSM,一个基于LSM思想针对时序数据场景优化的存储引擎。InfluxDB分享了他们从最初使用LevelDB,到替换为BoltDB,最后到决定自研TSM的整个过程,深刻描述了每个阶段的痛点及过度到下个阶段需要解决的核心问题,以及最终TSM的核心设计思路。这类分享是我比较喜欢的,不是直接一上来告诉你什么技术是最好,而是一步一步告诉你整个技术演进的历程。这其中对每个阶段遇到的问题的深刻剖析、最终做出技术选择的理由等,让人印象深刻,能学到很多东西。

但InfluxDB的TSM,细节描述还是不够多,更多的是策略和行为的描述。最近看到了一篇文章《Writing a Time Series Database from Scratch》,从零开始写一个时序数据库,虽然有点标题党,但内容确是实打实的干货,描述了一个TSDB存储引擎的设计思路。而且这个存储引擎不是一个概念或玩具,而是真实应用到生产了,是Prometheus在2017年11月对外发布的2.0版里的一个完全重写的新的存储引擎。这个新版存储引擎号称是带来了『huge performance improvements』,由于变化太大,做不到向后兼容,估计也是真的带来了很多惊喜,才能这样子去耍流氓。
而本篇文章,主要是对那篇文章的一个解读,大部分内容来自原文,略有删减。想了解更详细的内容的话,建议可以去看英文原文,有理解错误的地方欢迎指正。

数据模型

Prometheus与其他主流时序数据库一样,在数据模型定义上,也会包含metric name、一个或多个labels(同tags)以及metric value。metric name加一组labels作为唯一标识,来定义time series,也就是时间线。在查询时,支持根据labels条件查找time series,支持简单的条件也支持复杂的条件。存储引擎的设计,会根据时序数据的特点,重点考虑数据存储(写多读少)、数据回收(retention)以及数据查询,Prometheus这里暂时还没提数据分析。
图片描述
上图是所有数据点分布的一个简单视图,横轴是时间,纵轴是时间线,区域内每个点就是数据点。Prometheus每次接收数据,收到的是图中区域内纵向的一条线。这个表述很形象,因为在同一时刻,每条时间线只会产生一个数据点,但同时会有多条时间线产生数据,把这些数据点连在一起,就是一条竖线。这个特征很重要,影响数据写入和压缩的优化策略。

V2存储引擎

这篇文章主要阐述的是新的V3存储引擎的一些设计思想,老的存储引擎就是V2。V2存储引擎会把每条时间线上的数据点分别存储到不同的文件,这种设计策略下,文中提出了几个问题来探讨:
针对写入要做的优化:针对SSD和HDD的写入优化,均可遵循顺序写和批量写的原则。但是如上面所说,Prometheus一次性接收到的数据是一条竖线,包含很多的数据点,但是这些数据点属于不同的时间线。而当前的设计是一条时间线对应一个独立的文件,所以每次写入都会需要向很多不同的文件写入极少量的数据。针对这个问题,V2存储引擎的优化策略是Chunk写,针对单个时间线的写入必须是批量写,那就需要数据在时间线维度累积一定时间后才能凑到一定量的数据点。Chunk写策略带来的好处除了批量写外,还能优化热数据查询效率以及数据压缩率。V2存储引擎使用了和Facebook Gorilla一样的压缩算法,能够将16个字节的数据点压缩到平均1.37个字节,节省12倍内存和空间。Chunk写就要求数据一定要在服务器内存里积累一定的时间,即热数据基本都在内存中,查询效率很高。

针对查询要做的优化:时序数据的查询场景多遍,可以查某个时间线的某个时间点、某个时间点多条时间线或者是某个时间范围多条时间线的数据等等。在上面的数据模型图上示意出来,就是在二维象限内一个矩形的数据块。不断是针对SSD还是HDD,对磁盘数据读取比较友好的优化,均是优化到一次查询只需要少量的随机定位加上大块的顺序读取。这个和数据在磁盘的分布有很大的关系,归根到底,还是和数据写有关系,但不一定是实时写优化,也可以通过后续的数据整理来优化。

V2存储引擎里,有一些已经做的比较好的优化策略,主要是Chunk写以及热数据内存缓存,这两个优化延续到了V3。但是除了这两点,V2还是存在很多的缺陷:
文件数会随着时间线的数量同比增长,慢慢会耗尽inode。

即便使用了Chunk写优化,若一次写入涉及的时间线过多,IOPS要求还是会很高。
每个文件不可能会时刻保持open状态,一次查询可能需要重新打开大量文件,增大查询延迟。

数据回收需要从大量文件扫描和重写数据,耗时较长。

数据需要在内存中积累一定时间以Chunk写,V2会采用定时写Checkpoint的机制来尽量保证内存中数据不丢失。但通常记录Checkpoint的时间大于能承受的数据丢失的时间窗口,并且在节点恢复时从checkpoint restore数据的时间也会很长。
另外关于时间线的索引,V2存储引擎使用LevelDB来存储label到时间线的映射。当时间线到一定规模后,查询的效率会变得很低。在一般场景下,时间线的基数都是比较小的,因为应用环境很少变更,运行稳定的话时间线基数也会处于一个稳定的状态。但是若label设置不合理,例如采用一个动态值,比如是程序版本号作为label,每次应用升级label的值都会改变。那随着时间的推进,会存在越来越多无效的时间线(Prometheus称其为Series Churn)。时间线的规模会变得越来越大,影响索引查询效率。

V3存储引擎

V3引擎完全重新设计,来解决V2引擎中存在的这些问题。V3引擎可以看做是一个简单版、针对时序数据场景优化过后的LSM,可以带着LSM的设计思想来理解,先看一下V3引擎中数据的文件目录结构。
图片描述
data目录下存放所有的数据,data目录的下一级目录是以’b-‘为前缀,顺序自增的ID为后缀的目录,代表Block。每个Block下有chunks、index和meta.json,chunks目录下存放chunk的数据。这个chunk和V2的chunk是一个概念,唯一的不同是一个chunk内会包含很多的时间线,而不再只是一条。index是这个block下对chunk的索引,可以支持根据某个label快速定位到时间线以及数据所在的chunk。meta.json是一个简单的关于block数据和状态的一个描述文件。要理解V3引擎的设计思想,只需要搞明白几个问题:1. chunk文件的存储格式?2. index的存储格式,如何实现快速查找?3. 为何最后一个block没有chunk目录但有一个wal目录?

设计思想

图片描述
Prometheus将数据按时间维度切分为多个block,每个block被认为是独立的一个数据库,覆盖不同的时间范围的数据,完全没有交叉。每个Block下chunk内的数据dump到文件后即不可再修改,只有最近的一个block允许接收新数据。最新的block内数据写入会先写到一个内存的结构,为了保证数据不丢失,会先写一份WAL(write ahead log)。

V3完全借鉴了LSM的设计思想,针对时序数据特征做了一些优化,带来很多好处:
当查询一个时间范围的数据时,可快速排除无关的block。每个block有独立的index,能够有效解决V2内遇到的『无效时间线 Series Churn』的问题。
内存数据dump到chunk file,可高效采用大块数据顺序写,对SSD和HDD都很友好。

和V2一样,最近的数据在内存内,最近的数据也是最热的数据,在内存可支持最高效的查询。

老数据的回收变得非常简单和高效,只需要删除少量目录。
图片描述
V3内block以两个小时的跨度来切割,这个时间跨度不能太大,也不能太小。太大的话若内存中要保留两个小时数据,则内存占用会比较大。太小的话会导致太多的block,查询时需要对更多的文件做查询。所以两个小时是一个综合考虑后决定的值,但是当查询大跨度时间范围时,仍不可避免需要跨多个文件,例如查询一周时间跨度需要84个文件。V3也是采用了LSM一样的compaction策略来做查询优化,把小的block合并为大的block,compaction期间也可做其他一些事,例如删除过期数据或重构chunk数据以支持更高效的查询。这篇文章中对V3的compaction描述的比较少,这个倒可以去看看InfluxDB怎么做的,InfluxDB有多种不同的compaction策略,在不同的时刻使用,具体可以看看这篇文章。
图片描述
这个图是V3内对过期数据回收的一个示意图,相比V2会简单很多。对整个block已经过期的数据,直接删除文件夹即可。但对只有部分数据过期的block,无法进行回收,只能等全部过期或者compaction。这里有个问题要讨论,随着对历史数据不断的做compaction,block会变得越来越大,覆盖的时间范围会越大,则越难被回收。这里必须控制block的上限,通常是根据一个retention window的周期来配置。

以上基本讲完了数据存储的一些设计要点,还是比较简单明了的。和其他时序数据库一样,除了数据存储库,还有一份索引库。V3的索引结构比较简单,直接引用文章中给的例子:
图片描述
图片描述
从文章描述看,V3没有和V2一样采用LevelDB,在已经持久化的Block,Index已经固定下来,不可修改。而对于最新的还在写数据的block,V3则会把所有的索引全部hold在内存,维护一个内存结构,等到这个block被关闭,再持久化到文件。这样做会比较简单一点,内存里维护时间线到ID的映射以及label到ID列表的映射,查询效率会很高。而且Prometheus对Label的基数会有一个假设:『a real-world dataset of ~4.4 million series with about 12 labels each has less than 5,000 unique labels』,这个全部保存在内存也是一个很小的量级,完全没有问题。InfluxDB采用的是类似的策略,而其他一些TSDB则直接使用ElasticSearch作为索引引擎。

总结
针对时序数据这种写多读少的场景,类LSM的存储引擎还是有不少优势的。有些TSDB直接基于开源的LSM引擎分布式数据库例如Hbase或Cassandra,也有自己基于LevelDB/RocksDB研发,或者再像InfluxDB和Prometheus一样纯自研,因为时序数据这一特定场景还是可以做更多的优化,例如索引、compaction策略等。Prometheus V3引擎的设计思想和InfluxDB真的很像,优化思路高度一致,后续在有新的需求的出现后,会有更多变化。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/522855.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

flowable modler为任务节点增加自定义属性

如何在modler设计器中为任务节点,添加自定义的属性。 文章目录1、modler设计器中所有元素的定义2、flowable如何处理stencilset_bpmn.json文件3、为UserTask任务节点添加一个扩展属性3.1. 添加属性的名称3.2. 为任务节点添加扩展属性3.3. 查看效果1、modler设计器中…

微软对OpenAI投资10亿美元欲开发AI技术;华晨宝马宣布建成全球首个5G汽车生产基地;传苹果将收购英特尔调制解调器芯片业务...

关注并标星星CSDN云计算极客头条:速递、最新、绝对有料。这里有企业新动、这里有业界要闻,打起十二分精神,紧跟fashion你可以的!每周三次,打卡即read更快、更全了解泛云圈精彩newsgo go go 索尼Xperia 1R信息曝光&…

java se 与j2se_javaSE和 j2SE的区别?

javaSE和 j2SE的区别?关注:71 答案:4 mip版解决时间 2021-01-28 18:29提问者耍硪ミ倪配么2021-01-27 20:19javaSE和 j2SE的区别?最佳答案二级知识专家自然卷的气质2021-01-27 21:53JavaEE 比 se多了许多包,用于开发大规模的,分布式的Java应用/服务器…

[高速通道进阶一]如何理解高速通道的就近接入和一点接入连接全球

摘要: 经常有用户问,我在上海有个IDC,在北京有个VPC,我想通过专线把IDC和VPC连接起来,我是不是要找运营商直接拉一根上海到北京的专线?其实不是这样的,用户只需要接入到最近的接入点即可。高速通…

Flowable决策任务(decision task)

摘要:Flowable中引入了一个decision task(我们可以将其称之为决策任务)。在讲解decision task之前,我们不妨看一下dmn引擎。因为如果大家不了解dmn,那肯定不知道如何使用decision task了。 dmn是decision Modeling Not…

PyODPS 安装常见问题解决

摘要: 本文将用户安装 PyODPS 时遇到的常见问题列举如下,希望在遇到类似问题时可供借鉴。在参考下列步骤之前,请首先尝试卸载并重装 PyODPS。卸载的步骤为执行“pip uninstall pyodps”。 点此查看原文:http://click.aliyun.com/m…

flowable理论(一)工作流理论

文章目录一、工作流是什么?二、为什么要用工作流?三、市面上有哪些工作流:四、工作流的规范一、工作流是什么? 工作流是将一组任务组织起来以完成某个经营过程:定义了任务的触发顺序和触发条件,每个任务可…

5G精华问答 | 5G技术已经成熟了吗?

1G时我们用手机打电话,2G时我们能互发短信、看文字信息,3G时上网看图片,而4G时我们看视频和直播,从1G到4G,不仅信号越来越好,安全性越来越高,上网也越来越快了。1Q:5G技术已经成熟了…

python局部变量含义_Python的变量

1. 概念Python变量是用于存储值所在的内存位置。换句话说,python程序中的变量将数据提供给计算机进行处理。Python中的每个值都有一个数据类型。Python中不同的数据类型是Number,List,Tuple,String,Dictionary等。变量…

PyODPS DataFrame:统一的数据查询语言

摘要: 前几天,PyODPS发布了0.7版本,这篇文章给大家介绍下PyODPS新版本带来的重要特性。 之前也有若干篇文章介绍过了,我们PyODPS DataFrame是延迟执行的,在调用立即执行的方法,比如execute、persist等之前&…

flowable理论(三)flowable简介

flowable 2017发布,主创人员来自Activiti团队,目前支持BPMN和CMMN、DMN规范、它的主要含有五个引擎和一个官方自带的Modeler流程设计器,以及一套数据库表,以及发布版本(5个war)/源代码等: 文章目录一、五大…

AliOS Things 持续集成(CI)系统介绍

摘要: AliOS Things在快速的迭代进化之中,如何保证提交的代码质量,并保证在各个硬件平台上的稳定性,是一个非常大的挑战。同时物联网硬件碎片化,资源紧张,对持续集成(CI)系统也提出了…

从青铜到王者,助力企业轻松上云的四大绝招!

戳蓝字“CSDN云计算”关注我们哦!IBM在7月份发生了很多大事,其中这两件你知道吗?第一,IBM(NYSE: IBM)与美国电话电报公司(AT&T)(NYSE: T)达成一项为期多年的战略联盟…

python模块用法教程_Python学习之asyncore模块用法实例教程

本文以实例分析了Python中asyncore模块的原理及用法,分享给大家供大家参考。具体分析如下:asyncore库是python的一个标准库,它是一个异步socket的包装。我们操作网络的时候可以直接使用socket等底层的库,但是asyncore使得我们可以…

PyODPS开发中的最佳实践

摘要: PyODPS支持用 Python 来对 MaxCompute 对象进行操作,它提供了 DataFrame API 来用类似 pandas 的接口进行大规模数据分析以及预处理,并且可以用 ml 模块来执行机器学习算法。 点此查看原文:http://click.aliyun.com/m/41091…

flowable实战(一)flowable与spring boot集成

文章目录一、添加依赖pom.xml二、关掉认证和Mapper接口的扫描三、添加数据库连接池一、添加依赖pom.xml <dependency><groupId>org.flowable</groupId><artifactId>flowable-spring-boot-starter</artifactId><version>${flowable.version…

PyODPS 中使用 Python UDF

摘要&#xff1a; PyODPS 中使用 Python UDF 包含两方面&#xff0c;一个是直接使用&#xff0c;也就是在 MaxCompute SQL 中使用&#xff1b;一个是间接的方式&#xff0c;也就是 PyODPS DataFrame&#xff0c;这种方式你不需要直接写 Python UDF&#xff0c;而是写普通的 Pyt…

无服务器计算,如何节省时间和成本?

戳蓝字“CSDN云计算”关注我们哦&#xff01;译者 | 风车云马出品 | CSDN云计算&#xff08;ID&#xff1a;CSDNcould&#xff09;为了解决面临的业务问题&#xff0c;通常需要开发人员花费一定的时间编写完代码&#xff0c;再交由运维工程师确保正常的运行&#xff0c;整个过程…

gen文件下有两个R.java_android工程gen目录中R.java包名是怎么确定

新建一个工程&#xff0c;包名用的com.mythroad.adskiller, 后来觉得不好&#xff0c;又改成com.mythroad.adsinscepter,但是我发现gen下的R.java文件的包名还是原来的com.mythroad.adskiller。甚至手动新建了R.java,包名为com.mythroad.adsinscepter&#xff0c;我把com.mythr…

flowable实战(二)flowable流程模型管理接口

文章目录一、流程模型资源二、流程模型资源的部署&#xff1a;2.1. 流程资源xml部署&#xff1a;2.2. zip/bar打包&#xff0c;多个流程资源文件部署&#xff1a;2.3. Model部署三、部署有关的数据库表四、流程模型的常见管理接口4.1. 部署api4.2.验证部署4.3.获取所有部署api4…