时序数据库技术体系中一个非常重要的技术点是时序数据模型设计,不同的时序系统有不同的设计模式,不同的设计模式对时序数据的读写性能、数据压缩效率等各个方面都有不同程度的影响。这篇文章笔者将会分别针对OpenTSDB、Druid、InfluxDB以及Beringei这四个时序系统中的时序数据模型设计进行介绍。
网站建设哪家好,找创新互联!专注于网页设计、网站建设、微信开发、微信小程序定制开发、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了珲春免费建站欢迎大家使用!
在详细介绍时序数据模型之前,还是有必要简单回顾一下时序数据的几个基本概念,如下图所示:
上图是一个典型的时序数据示意图,由图中可以看出,时序数据由两个维度坐标来表示,横坐标表示时间轴,随着时间的不断流逝,数据也会源源不断地吐出来;和横坐标不同,纵坐标由两种元素构成,分别是数据源和metric,数据源由一系列的标签(tag,也称为维度)唯一表示,图中数据源是一个广告数据源,这个数据源由publisher、advertiser、gender以及country四个维度值唯一表示,metric表示待收集的数据源指标。一个数据源通常会采集很多指标(metric),上图中广告数据源就采集了impressions、clicks以及revenue这三种指标,分别表示广告浏览量、广告点击率以及广告收入。
看到这里,相信大家对时序数据已经有了一个初步的了解,可以简单的概括为:一个时序数据点(point)由datasource(tags)+metric+timestamp这三部分唯一确定。然而,这只是逻辑上的概念理解,那具体的时序数据库到底是如何将这样一系列时序数据点进行存储的呢?下文笔者针对OpenTSDB、Druid、InfluxDB以及Beringei四种系统进行介绍。
OpenTSDB(HBase)时序数据存储模型
OpenTSDB基于HBase存储时序数据,在HBase层面设计RowKey规则为: metric+timestamp+datasource(tags) 。HBase是一个KV数据库,一个时序数据(point)如果以KV的形式表示,那么其中的V必然是point的具体数值,而K就自然而然是唯一确定point数值的datasource+metric+timestamp。 这种规律不仅适用于HBase,还适用于其他KV数据库,比如Kudu。
既然HBase中K是由datasource、metric以及timestamp三者构成,现在我们可以简单认为rowkey就为这三者的组合,那问题来了:这三者的组合顺序是怎么样的呢?
首先来看哪个应该排在首位。因为HBase中一张表的数据组织方式是按照rowkey的字典序顺序排列的,为了将同一种指标的所有数据集中放在一起,HBase将将metric放在了rowkey的最前面。假如将timestamp放在最前面,同一时刻的数据必然会写入同一个数据分片,无法起到散列的效果;而如果将datasource(即tags)放在最前面的话,这里有个更大的问题,就是datasource本身由多个标签组成,如果用户指定其中部分标签查找,而且不是前缀标签的话,在HBase里面将会变成大范围的扫描过滤查询,查询效率非常之低。举个上面的例子,如果将datasource放在最前面,那rowkey就可以表示为publisher=ultrarimfast.com&advertiser:google.com&gender:Male&country:USA_impressions_20110101000000,此时用户想查找20110101000000这个时间点所有发布在USA的所有广告的浏览量,即只根据country=USA这样一个维度信息查找指定时间点的某个指标,而且这个维度不是前缀维度,就会扫描大量的记录进行过滤。
确定了metric放在最前面之后,再来看看接下来应该将datasource放在中间呢还是应该将timestamp放在中间?将metric放在前面已经可以解决请求均匀分布(散列)的要求,因此HBase将timestamp放在中间,将datasource放在最后。试想,如果将datasource放在中间,也会遇到上文中说到的后缀维度查找的问题。
因此,OpenTSDB中rowkey的设计为:metric+timestamp+datasource,好了,那HBase就可以只设置一个columnfamily和一个column。那问题来了,OpenTSDB的这种设计有什么问题?在了解设计问题之前需要简单看看HBase在文件中存储KV的方式,即一系列时序数据在文件、内存中的存储方式,如下图所示:
上图是HBase中一个存储KeyValue(KV)数据的数据块结构,一个数据块由多个KeyValue数据组成,在我们的事例中KeyValue就是一个时序数据点(point)。其中Value结构很简单,就是一个数值。而Key就比较复杂了,由rowkey+columnfamily+column+timestamp+keytype组成,其中rowkey等于metric+timestamp+datasource。
虽说有这样那样的问题,但是OpenTSDB还是针对存储模型做了两个方面的优化:
上述两个优化可以参考OpenTSDB这张经典的示意图:
Druid时序数据存储模型设计
和HBase和Kudu这类KV数据库不同,Druid是另一种玩法。Druid是一个不折不扣的列式存储系统,没有HBase的主键。上述时序数据在Druid中表示是下面这个样子的:
Druid是一个列式数据库,所以每一列都会独立存储,比如Timestamp列会存储在一起形成一个文件,publish列会存储在一起形成一个文件,以此类推。细心的童鞋就会说了,这样存储,依然会有数据源(tags)大量冗余的问题。针对冗余这个问题,Druid和HBase的处理方式一样,都是采用编码字典对标签值进行编码,将string类型的标签值编码成int值。但和HBase不一样的是,Druid编码是局部编码,Druid和HBase都采用LSM结构,数据先写入内存再flush到数据文件,Druid编码是文件级别的,局部编码可以有效减小对内存的巨大压力。除此之外,Druid的这种列式存储模式还有如下好处:
数据存储压缩率高。每列独立存储,可以针对每列进行压缩,而且可以为每列设置对应的压缩策略,比如时间列、int、fload、double、string都可以分别进行压缩,压缩效果更好。
支持多维查找。Druid为datasource的每个列分别设置了Bitmap索引,利用Bitmap索引可以有效实现多维查找,比如用户想查找20110101T00:00:00这个时间点所有发布在USA的所有广告的浏览量,可以根据country=USA在Bitmap索引中找到要找的行号,再根据行号定位待查的metrics。
然而,这样的存储模型也有一些问题:
InfluxDB时序数据存储模型设计
相比OpenTSDB以及Druid,可能很多童鞋对InfluxDB并不特别熟悉,然而在时序数据库排行榜单上InfluxDB却是遥遥领先。InfluxDB是一款专业的时序数据库,只存储时序数据,因此在数据模型的存储上可以针对时序数据做非常多的优化工作。
为了保证写入的高效,InfluxDB也采用LSM结构,数据先写入内存,当内存容量达到一定阈值之后flush到文件。InfluxDB在时序数据模型设计方面提出了一个非常重要的概念:seriesKey,seriesKey实际上就是datasource(tags)+metric,时序数据写入内存之后按照seriesKey进行组织:
内存中实际上就是一个Map:>,Map中一个SeriesKey对应一个List,List中存储时间线数据。数据进来之后根据datasource(tags)+metric拼成SeriesKey,再将Timestamp|Value组合值写入时间线数据List中。内存中的数据flush的文件后,同样会将同一个SeriesKey中的时间线数据写入同一个Block块内,即一个Block块内的数据都属于同一个数据源下的一个metric。
这种设计我们认为是将时间序列数据按照时间线挑了出来。先来看看这样设计的好处:
细心的同学可能会问了,将datasource(tags)和metric拼成SeriesKey,不是也不能实现多维查找。确实是这样,不过InfluxDB内部实现了倒排索引机制,即实现了tag到SeriesKey的映射关系,如果用户想根据某个tag查找的话,首先根据tag在倒排索引中找到对应的SeriesKey,再根据SeriesKey定位具体的时间线数据。 InfluxDB的这种存储引擎称为TSM,全称为Timestamp-Structure Merge Tree,基本原理类似于LSM。后期笔者将会对InfluxDB的数据写入、文件格式、倒排索引以及数据读取进行专题介绍。
Beringei时序数据存储模型设计
Beringei是今年Facebook开源的一个时序数据库系统。InfluxDB时序数据模型设计很好地将时间序列按照数据源以及metric挑选了出来,解决了维度列值冗余存储,时间列不能有效压缩的问题。但InfluxDB没有很好的解决写入缓存压缩的问题:InfluxDB在写入内存的时候并没有压缩,而是在数据写入文件的时候进行对应压缩。我们知道时序数据最大的特点之一是最近写入的数据最热,将最近写入的数据全部放在内存可以极大提升读取效率。Beringei很好的解决了这个问题,流式压缩意味着数据写入内存之后就进行压缩,这样会使得内存中可以缓存更多的时序数据,这样对于最近数据的查询会有很大的帮助。
Beringei的时序数据模型设计与InfluxDB基本一致,也是提出类似于SeriesKey的概念,将时间线挑了出来。但和InfluxDB有两个比较大的区别:
后续笔者也会针对Beringei的数据写入、流式压缩、文件格式等进行介绍。在笔者看来,如果将Beringei和InfluxDB有效结合起来,就能够将时序数据高效存储在内存,另外数据按照维度进行组织,可以非常高效的提高数据在文件的存储效率以及查询效率,最后结合InfluxDB的倒排索引功能可以有效提高多维查询能力。
本文是时序数据库技术体系的第一篇文章,笔者主要结合OpenTSDB、Druid、InfluxDB以及Beringei这四种时序数据库分别对时序数据这种数据形式的存储模型进行了介绍。每种数据库都有自己的一套存储方式,而每种存储方式都有各自的一些优势以及缺陷,正是这些优劣式直接决定了相应时序数据库的压缩性能、读写性能。
分享标题:时序数据库技术体系-时序数据存储模型设计
当前地址:http://www.shufengxianlan.com/qtweb/news47/219997.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联