分布式时序数据库QTSDB的设计与实现


发布时间: 2019-08-17

  附Java/C/C++/机器学习/算法与数据结构/前端/安卓/Python/程序员必读书籍书单大全:

  ④【Web前端】从HTML到JS到AJAX到HTTP从框架到全栈帮你走更少弯路(珍藏版)

  ⑤【python】书最全已整理好(从入门到进阶)(珍藏版)⑥【机器学习】+python整理技术书(从入门到进阶已经整理好)(珍藏版)

  ⑧【安卓】入门到进阶推荐书籍整理pdf书单整理(珍藏版)⑨【架构师】之路史诗级必读书单吐血整理四个维度系列80+本书(珍藏版)⑩【C++】吐血整理推荐书单从入门到进阶成神之路100+本(珍藏)⑪【ios】IOS书单从入门到进阶吐血整理(珍藏版)

  现有的开源时序数据库influxdb只支持单机运行,在面临大量数据写入时,会出现查询慢,机器负载高,单机容量的限制。

  为了解决这一问题,360基础架构团队在单机influxdb的基础上,开发了集群版——QTSDB

  QTSDB是一个分布式时间序列数据库,用于处理海量数据写入与查询。实现上,是基于开源单机时序数据库influxdb 1.7开发的分布式版本,除了具有influxdb本身的特性之外,还有容量扩展、副本容错等集群功能。

  influxdb架构层次最高是database,database下边根据数据保留时长不同分成了不同的retension policy,形成了database下面的多个存储容器,因为时序数据库与时间维度关联,所以将相同保留时长的内容存放到一起,便于到期删除。除此之外,在retension policy之下,将retension policy的保留时长继续细分,每个时间段的数据存储在一个shard group中,这样当某个分段的shard group到期之后,会将其整个删掉,避免从存储引擎内部抠出部分数据。例如,在database之下的数据,可能是30天保留时长,可能是7天保留时长,他们将存放在不同的retension policy之下。假设将7天的数据继续按1天进行划分,就将他们分别存放到7个shard group中,当第8天的数据生成时,会新建一个shard group写入,并将第 1天的shard group整个删除。

  到此为止,同一个retension policy下,发来的当下时序数据只会落在当下的时间段,也就是只有最新的shard group有数据写入,为了提高并发量,一个shard group又分成了多个shard,这些shard全局唯一,分布于所有物理节点上,每个shard对应一个tsm存储引擎,负责存储数据。

  在请求访问数据时,通过请求的信息可以锁定某个database和retension policy,然后根据请求中的时间段信息,锁定某个(些)shard group。对于写入的情况,每条写入的数据都对应一个serieskey(这个概念后面会介绍),通过对serieskey进行哈希取模就能锁定一个shard,进行写入。而shard是有副本的,在写入的时候会采用无主多写的策略同时写入到每个副本中。查询时,由于查询请求中没有serieskey的信息,所以只能将shard group内的shard都查询一遍,针对一个shard,会在其副本中选择一个可用的物理节点进行访问。

  那么一个shard group要有多少shard呢,为了达到最大并发量,又不过分干扰数据整体的有序性,在物理节点数和副本数确定后,一个shard group内的shard数量是机器数除以副本数,保障了当下的数据可以均匀写入到所有的物理节点之上,也不至于因为shard过多影响查询效率。例如,图上data集群有6个物理节点,用户指定双副本,那么就有3个shard。

  整个系统分成**三个部分:proxy、meta集群、data集群。**proxy负责接收请求,无状态,其前可接lvs支持水平扩展。meta集群保存上面提到的逻辑存储层次及其与物理节点的对应关系,通过raft协议保障元数据的强一致,这里meta信息保存在内存中,日志和快照会持久化到磁盘。data集群是真正的数据存储节点,数据以shard为单位存储于其上,每个shard都对应一个tsm存储引擎。

  请求到来的时候,经过lvs锁定一台proxy,proxy先根据database、retension policy和时间段到meta集群查找meta信息,最终得到一个shard到物理节点的映射,然后将这个映射关系转换为物理节点到shard的映射返回给proxy,最后根据这个映射关系,到data集群指定的物理节点中访问具体的shard,至于shard之下的数据访问后边会介绍。

  influxdb的查询提供类似于关系数据库的查询方式,展示出来类似一个关系表:measurement,时序数据库的时间作为一个永恒的列,除此之外的列分成两类:

  一类是field,他们是时序数据最关键的数据部分,其值会随着时间的流动源源不断的追加,例如两台机器之间在每个时间点上的延迟。

  另一类是tag,他们是一个field值的一些标记,所以都是字符串类型,并且取值范围很有限。例如某个时间点的延迟field值是2ms,对应有两个标记属性,从哪台机器到哪台机器的延迟,因此可以设计两个tag:from、to。

  如果一行中存在多个field就会划分成多条这样的数据存储。influxdb的存储引擎可以理解为一个map,从measurement到fieldkey作为存储key,后边的fieldvalue和time是存储value,这些值会源源不断追加的,在存储引擎中,这些值会作为一列存储到一起,因为是随时间渐变的数据,将他们保存到一起可以提升压缩的效果。另外将存储key去掉fieldkey之后剩余部分就是上边提到的serieskey。

  上边提到,访问请求在集群中如何锁定shard,这里介绍在一个shard内的访问。

  influxdb的查询类似于sql语法,但是跟sql语句的零散信息无法直接查询存储引擎,所以需要一些策略将sql语句转换成存储key。influxdb通过构建倒排索引来将where后的tag信息转换为所有相关的serieskey的集合,然后将每个serieskey拼接上select后边的fieldkey就组成了存储key,这样就可以按列取出对应的数据了。

  通过对tsm存储引擎中存储key内serieskey的分析,能够构建出倒排索引,新版本influxdb将倒排索引持久化到每个shard中,与存储数据的tsm存储引擎对应,叫做tsi存储引擎。倒排索引相当于一个三层的map,map的key是measurment,值是一个二层的map,这个二层的map的key是tagkey,对应的值是一个一层的map,这个一层map的key是tagval,对应的值是一个serieskey的集合,这个集合中的每个serieskey字串都包含了map索引路径上的measurement、tagkey和tagval。

  这样可以分析查询sql,用from后的measurement查询倒排索引三级map获得一个二级map,然后再分析where之后多个过滤逻辑单元,以tagkey1=tagval1为例,将这两个信息作为二层map的key,查到最终的值:serieskey的集合,这个集合的每个serieskey字串都包含了measurment、tagkey1和tagval1,他们是满足当下过滤逻辑单元的serieskey。根据这些逻辑单元的与或逻辑,将其对应的serieskey的集合进行交并运算,最终根据sql的语义过滤出所有的符合其逻辑的serieskey的集合,然后将这些serieskey与select后边的fieldkey拼接起来,得到最终的存储·key,就可以读取数据了。

  不带聚合函数的查询:如图,对于一个serieskey,需要拼接众多的fieldkey,进而取出多个列的数据,他们出来后面临的问题是怎么组合为一行的数据,influxdb行列约束比较松散,不能单纯按照列内偏移确定行。Influxdb把serieskey和time作为判断列数据为一行的依据,每一个serieskey对应的多列就汇集为一个以多行为粒度的数据流,多个serieskey对应的数据流按照一定顺序汇集为一个数据流,作为最终的结果集返回到客户端。

  带聚合函数的查询:这种方式与上边的查询正好相反,这里是针对聚合函数参数field,拼接上众多的serieskey,当然最终目的都是一样,得到存储key,多个存储key可以读取多个数据流,这些数据流面临两种处理,先将他们按照一定的顺序汇集为一个数据流,然后按照一定的策略圈定这个数据流内相邻的一些数据进行聚合计算,进而得到最终聚合后的值。这里的顺序和策略来自于sql语句中group by后的聚合方式。

  对于访问的整个流程上边都已经提到了,这里整体梳理一下:分成两个阶段,在shard之上的查询,在shard之下的查询。

  对于写入操作,根据写入时的serieskey,锁定一个shard进行写入,由于shard存在多副本,需要同时将数据写入到多个副本。对于查询,无法通过请求信息得到serieskey,因此需要查询所有的shard,针对每个shard选择一个可用的副本,进行访问。

  经过上边的处理就获得shard到物理节点的映射,然后将其反转为物理节点到shard的映射,返回给proxy,proxy就可以在data集群的某个节点访问对应的shard了。

  在shard之下的写入访问,需要拆解insert语句,组合为存储键值对存入tsm存储引擎,然后根据组合的serieskey更新倒排索引。

  在shard之下的查询访问,分析sql语句,查询倒排索引,获取其相关的serieskey集合,将其拼接field,形成最终的存储key,进行数据访问。然后将众多数据在data节点上进行shard之上的合并聚合,在proxy上进行data之上的合并聚合。

  上边提到influxdb针对shard提供副本容错,当写入数据发送到proxy,proxy将数据以无主多写的形式发送到所有的shard副本。meta集群以心跳的形式监控data节点是否在线,在读取的时候,针对同一shard会在在线的data节点中随机选择一个读取节点进行读取。

  在写入时如果一个data节点不可用,则会写入到proxy的一个临时文件中,等网络恢复正常会将这些暂存的数据发送到指定节点。

  当有全新节点加入data集群,目前还不支持自动将现有数据进行迁移,不过也做了些努力,为了使当下写入数据尽快应用到新的节点,在新加入节点的时候,会将当下时间作为当下shard group的结尾时间,然后按照全新的data节点数量新建一个shard group,这样当下数据量马上就能均分到各个data节点,而每个shard group相关的meta信息都存储在meta集群里,因此不会对之前数据的读取造成干扰。

  如果data节点处于短期不可用状态,包括短暂的网络故障后自恢复,或者硬件故障后运维人员干预,最终data节点还存有掉线前的数据,那么就可以以原来的身份加入到data集群。对于写入来说,不可用期间proxy会临时存放此data节点的数据,在data加入集群时会将这部分数据再次发送到data节点,保障数据最终一致。

  如果data节点由于一些原因,不能或者不需要以原来的身份加入到集群,需要运维人员手动将原来不可用的data节点下线,那么这台机器可用时,可以以全新的data身份加入到集群中,这等同于集群的扩容。

  QTSDB集群实现为:写入时根据serieskey将数据写到指定shard,而读取时无法预知serieskey,因此需要查询每个shard。将整个读取过程切分为两个阶段:在data节点上进行存储引擎的读取以及节点内部多shard的合并聚合,在proxy节点将多个data节点的数据汇总,进行后期的合并聚合,形成最终的结果集返回到客户端。

  背景   可用性(Availability)和一致性(Consistency)是分布式系统的基本问题,先有著名的CAP理论定义过分布式环境下二者不可兼得的关系,又有神秘的Paxos协议号称是史上最简单...博文来自:若干年后你会感谢现在付出的你的博客

  物联网领域近期如火如荼,互联网和传统公司争相布局物联网。作为物联网领域数据存储的首选,时序数据库也越来越多进入人们的视野,而早在2016年7月,百度云在其天工物联网平台上发布了国内首个多租户的分布式时...博文来自:java的平凡之路

  转自:新的infludb版本已经取消...博文来自:纸上得来终觉浅,绝知此事要躬行

  如何设计实现最基础的分布式应用,我们可以从如下两个ID入手:一个是全球唯一标识,另一个分布式hash散列值。前一个保证你各个服务器之间产生的不通ID是不重复的,因为它的主要算法是跟时间和MAC地址有关...博文来自:背着JAVA的蜗牛

  InfluxDB 是一个开源分布式时序、事件和指标数据库。使用Go语言编写,无需外部依赖。其设计目标是实现分布式和水平伸缩扩展。特点schemaless(无结构),可以是任意数量的列Scalablem...博文来自:weixin_33755554的博客

  MyDataServer,主要用于存储有时间标记的仪器仪表数据和日志数据。我利用开发的业余时间,共7个月完成开发和测试。如果您发现关系数据库在存储仪表数据时的性能不理想,那么这可能就是您在找的替代产品...博文来自:wzh191920的博客

  Graphite就属于一种时序数据库,作用是存储和聚合监控数据并绘制图标,不负责数据的收集。之所以想写一篇关于Graphite的博文主要是因为这是我接触到的另一种新型数据库,其特点和功能让人眼前一亮。...博文来自:咖啡男孩之SRE之路

  在设计RPC的实现的时候,有几个问题需要提前说明一下:基于接口的编程实现与RPC有关的调用语义透明性:是本地调用和远程调用相同;...博文来自:lmy86263的博客

  分布式爬虫设计和实现1.总体设计功能模块划分:数据抓取引擎1.1调研市面上爬虫框架或库pholcuscollygocrawl开发工具:goland开发语言:golang数据存储:ElasticSear...博文来自:脚踏实地,不断挑战自己极限,每天有收获就OK

  时序数据库InfluxDB什么是时间序列数据库?最简单的定义就是数据格式里包含Timestamp字段的数据,比如某一时间环境的温度,CPU的使用率等。但是,有什么数据不包含Timestamp呢?几乎所...博文来自:weixin_30558305的博客

  一、概述项目是分布式的架构,需要设计一款分布式全局ID,参照了多种方案,博主最后基于snowflake的算法设计了一款自用ID生成器。具有以下优势:保证分布式场景下生成的ID是全局唯一的 生成的全局I...博文来自:的博客

  为了提高FrP系统在并发多用户状态下的数据传输速率和响应速度,设计了基于分布式理论的新型FTP系统,将命令处理和数据处理分离,并应用JAVA RMI技术实现了该分布式FIP系统。介绍了分布式FIP系统的设计和实现过程,给出了FIP元命令处...

  在现代企业互联网应用中,分布式数据缓存技术能够减少对数据库层的访问负载量, 提高系统的整体性能,在系统架构中发挥着重要作用。本文针对现有的分布式数据缓存产品 在数据冗余备份和失败恢复方面的不足,设计并实现了一种具备数据冗余备份和失败恢复功...

  本文介绍了如何利用分布式的思想在网络环境下设计实现分布式软件测试系统 一篇有参考价值的论文

  1-时序数据库有多少种类型DB-Engines:博文来自:vtnews的专栏

  数据库的模型包含关系型、key-value型、Document型等很多种,那么为什么新型的时序数据库成为监控数据存储的新宠呢?下面就会从为什么需要时序数据库?时序数据库的数据结构两个方面来介绍一下时序...博文来自:phantom_111的博客

  十分钟看懂时序数据库(I)-存储十分钟看懂时序数据库(III)-压缩十分钟看懂时序数据库(IV)-分级存储十分钟看懂时序数据库(V)-分布式计算时序数据库技术体系(一)时序数据库技术体系(二)...博文来自:要啥自行车,老牌芳草地心水论坛,一把梭~

  看了一些时序数据库,没有太深入,有一些大概认识,记录下来。1.  核心数据存储分为行存储或者列存储,由于列存储的高压缩比,现在使用列存储的比较多一些。当前有很多时序数据库采用了在底层KV存储(Cads...博文来自:ransom的博客

  用搜索引擎搜索下“tsdb”或者“时序数据库”,你可以看到各种开源的时序数据库,我没有对各种开源时序数据库进行过详细对比,只是大致上看了下别人的评论。从评论来看InfluxDB应该是目前综合性能最好...博文来自:Felix_阳的博客

  背景介绍:作为一名Infra,管理平台的各种基础组建以及基本的服务质量是必修的功课,而如何对复杂和繁多的基础平台,甚至包括上面运行的Ops系统、业务系统,其稳定性的各项指标都是衡量Infra是否称职的...博文来自:weixin_33743703的博客

  Jconf介绍:Jconf是基于Java的分布式配置管理平台,随着业务的不断变化,许多地方需要对数据进行配置,为了避免在分布式环境中对数据集中进行配置,分布式配置管理平台应运而生,目前性能比较优良的开...博文来自:wenbo20182的博客

  引言云硬盘对IaaS云计算平台有至关重要的作用,几乎已成为必备组件,如亚马逊的EBS(ElasticBlockStore)、阿里云的盘古、OpenStack中的Cinder等。云硬盘可为云计算平台带来...博文来自:MeituanTech的博客

  随着存储系统的快速发展,以及实际应用中对存储系统的要求日益苛刻,为了研究存储系统I/O子系统的运行形态,设计并实现了一种分布式I/O日志收集系统,该系统能够通过总控制台同时控制分布式系统的多个节点并行收集分布式系统的I/O日志,为分析和回...

  基于J2EE的分布式项目管理系统的设计与实现 主要是项目管理,着重于项目本身

  James_F:楼主,想要将写好的java程序放到手机上用,利用Android怎么进行开发,是需要下载东西,还是有什么要学的,求教,谢谢。

友情链接:
Copyright 2018-2021 牛牛高手论坛 版权所有,未经授权,禁止转载。