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

本文涉及的产品
对象存储 OSS,20GB 3个月
阿里云盘企业版 CDE,企业版用户数5人 500GB空间
对象存储 OSS,内容安全 1000次 1年
简介: 开源时序数据库   如图是17年6月在db-engines上时序数据库的排名,我会挑选开源的、分布式的时序数据库做详细的解析。前十的排名中,RRD是一个老牌的单机存储引擎,Graphite底层是Whisper,可以认为是一个优化的更强大的RRD数据库。

开源时序数据库

image

  如图是17年6月在db-engines上时序数据库的排名,我会挑选开源的、分布式的时序数据库做详细的解析。前十的排名中,RRD是一个老牌的单机存储引擎,Graphite底层是Whisper,可以认为是一个优化的更强大的RRD数据库。kdb+、eXtremeDB和Axibase都未开源,不做解析。InfluxDB开源版和Prometheus的底层都是基于levelDB自研的单机的存储引擎,InfluxDB的商业版支持分布式,Prometheus的roadmap上也规划了分布式存储引擎的支持计划。
  综合看下来,我会选择OpenTSDB、KairosDB和InfluxDB做一个详细的解析。我对OpenTSDB比较熟悉,研究过它的源码,所以对OpenTSDB会描述的格外详细,而对其他时序数据库了解的没那么深入,如果有描述错的地方,欢迎指正。

OpenTSDB

  OpenTSDB是一个分布式、可伸缩的时序数据库,支持高达每秒百万级的写入能力,支持毫秒级精度的数据存储,不需要降精度也可以永久保存数据。其优越的写性能和存储能力,得益于其底层依赖的HBase,HBase采用LSM树结构存储引擎加上分布式的架构,提供了优越的写入能力,底层依赖的完全水平扩展的HDFS提供了优越的存储能力。OpenTSDB对HBase深度依赖,并且根据HBase底层存储结构的特性,做了很多巧妙的优化。关于存储的优化,我在这篇文章中有详细的解析。在最新的版本中,还扩展了对BigTable和Cassandra的支持。

架构

image
  如图是OpenTSDB的架构,核心组成部分就是TSD和HBase。TSD是一组无状态的节点,可以任意的扩展,除了依赖HBase外没有其他的依赖。TSD对外暴露HTTP和Telnet的接口,支持数据的写入和查询。TSD本身的部署和运维是很简单的,得益于它无状态的设计,不过HBase的运维就没那么简单了,这也是扩展支持BigTable和Cassandra的原因之一吧。

数据模型

  OpenTSDB采用按指标建模的方式,一个数据点会包含以下组成部分:

  • metric:时序数据指标的名称,例如sys.cpu.user,stock.quote等。
  • timestamp:秒级或毫秒级的Unix时间戳,代表该时间点的具体时间。
  • tags:一个或多个标签,也就是描述主体的不同的维度。Tag由TagKey和TagValue组成,TagKey就是维度,TagValue就是该维度的值。
  • value:该指标的值,目前只支持数值类型的值。

存储模型

  OpenTSDB底层存储的优化思想,可以参考这篇文章,简单总结就是以下这几个关键的优化思路:

  • 对数据的优化:为Metric、TagKey和TagValue分配UniqueID,建立原始值与UniqueID的索引,数据表存储Metric、TagKey和TagValue对应的UniqueID而不是原始值。
  • 对KeyValue数的优化:如果对HBase底层存储模型十分了解的话,就知道行中的每一列在存储时对应一个KeyValue,减少行数和列数,能极大的节省存储空间以及提升查询效率。
  • 对查询的优化:利用HBase的Server Side Filter来优化多维查询,利用Pre-aggregation和Rollup来优化GroupBy和降精度查询。

UIDTable

  接下来看一下OpenTSDB在HBase上的几个关键的表结构的设计,首先是tsdb-uid表,结构如下:

image

Metric、TagKey和TagValue都会被分配一个相同的固定长度的UniqueID,默认是三个字节。tsdb-uid表使用两个ColumnFamily,存储了Metric、TagKey和TagValue与UniqueID的映射和反向映射,总共是6个Map的数据。

从图中的例子可以解读出:

  • TagKey为'host',对应的UniqueID为'001'
  • TagValue为'static',对应的UniqueId为'001'
  • Metric为'proc.loadavg.1m',对应的UniqueID为'052'

  为每一个Metric、TagKey和TagValue都分配UniqueID的好处,一是大大降低了存储空间和传输数据量,每个值都只需要3个字节就可以表示,这个压缩率是很客观的;二是采用固定长度的字节,可以很方便的从row key中解析出所需要的值,并且能够大大减少Java堆内的内存占用(bytes相比String能节省很多的内存占用),降低GC的压力。
  不过采用固定字节的UID编码后,对于UID的个数是有上限要求的,3个字节最多只允许有16777216个不同的值,不过在大部分场景下都是够用的。当然这个长度是可以调整的,不过不支持动态更改。

DataTable

第二张关键的表是数据表,结构如下:

image

  该表中,同一个小时内的数据会存储在同一行,行中的每一列代表一个数据点。如果是秒级精度,那一行最多会有3600个点,如果是毫秒级精度,那一行最多会有3600000个点。
  这张表设计的精妙之处在于row key和qualifier(列名)的设计,以及对整行数据的compaction策略。row key格式为:

<metric><timestamp><tagk1><tagv1><tagk2>tagv2>...<tagkn><tagvn>

  其中metric、tagk和tagv都是用uid来表示,由于uid固定字节长度的特性,所以在解析row key的时候,可以很方便的通过字节偏移来提取对应的值。Qualifier的取值为数据点的时间戳在这个小时的时间偏差,例如如果你是秒级精度数据,第30秒的数据对应的时间偏差就是30,所以列名取值就是30。列名采用时间偏差值的好处,主要在于能大大节省存储空间,秒级精度的数据只要占用2个字节,毫秒精度的数据只要占用4个字节,而若存储完整时间戳则要6个字节。整行数据写入后,OpenTSDB还会采取compaction的策略,将一行内的所有列合并成一列,这样做的主要目的是减少KeyValue数目。

查询优化

  HBase仅提供简单的查询操作,包括单行查询和范围查询。单行查询必须提供完整的RowKey,范围查询必须提供RowKey的范围,扫描获得该范围下的所有数据。通常来说,单行查询的速度是很快的,而范围查询则是取决于扫描范围的大小,扫描个几千几万行问题不大,但是若扫描个十万上百万行,那读取的延迟就会高很多。
  OpenTSDB提供丰富的查询功能,支持任意TagKey上的过滤,支持GroupBy以及降精度。TagKey的过滤属于查询的一部分,GroupBy和降精度属于对查询后的结果的计算部分。在查询条件中,主要的参数会包括:metric名称、tag key过滤条件以及时间范围。上面一章中指出,数据表的rowkey的格式为:<metric><timestamp><tagk1><tagv1><tagk2>tagv2>...<tagkn><tagvn>,从查询的参数上可以看到,metric名称和时间范围确定的话,我们至少能确定row key的一个扫描范围。但是这个扫描范围,会把包含相同metric名称和时间范围内的所有的tag key的组合全部查询出来,如果你的tag key的组合有很多,那你的扫描范围是不可控的,可能会很大,这样查询的效率基本是不能接受的。

我们具体看一下OpenTSDB对查询的优化措施:

  • Server side filter
    HBase提供了丰富和可扩展的filter,filter的工作原理是在server端扫描得到数据后,先经过filter的过滤后再将结果返回给客户端。Server side filter的优化策略无法减少扫描的数据量,但是可以大大减少传输的数据量。OpenTSDB会将某些条件的tag key filter转换为底层HBase的server side filter,不过该优化带来的效果有限,因为影响查询最关键的因素还是底层范围扫描的效率而不是传输的效率。
  • 减少范围查询内扫描的数据量
    要想真正提高查询效率,还是得从根本上减少范围扫描的数据量。注意这里不是减小查询的范围,而是减少该范围内扫描的数据量。这里用到了HBase一个很关键的filter,即FuzzyRowFilter,FuzzyRowFilter能够根据指定的条件,在执行范围扫描时,动态的跳过一定数据量。但不是所有OpenTSDB提供的查询条件都能够应用该优化,需要符合一定的条件,具体要符合哪些条件就不在这里说明了,有兴趣的可以去了解下FuzzyRowFilter的原理。
  • 范围查询优化成单行查询
    这个优化相比上一条,更加的极端。优化思路非常好理解,如果我能够知道要查询的所有数据对应的row key,那就不需要范围扫描了,而是单行查询就行了。这里也不是所有OpenTSDB提供的查询条件都能够应用该优化,同样需要符合一定的条件。单行查询要求给定确定的row key,而数据表中row key的组成部分包括metric名称、timestamp以及tags,metric名称和timestamp是能够确定的,如果tags也能够确定,那我们就能拼出完整的row key。所以很简单,如果要能够应用此优化,你必须提供所有tag key对应的tag value才行。

  以上就是OpenTSDB对HBase查询的一些优化措施,但是除了查询,对查询后的数据还需要进行GroupBy和降精度。GroupBy和降精度的计算开销也是非常可观的,取决于查询后的结果的数量级。对GroupBy和降精度的计算的优化,几乎所有的时序数据库都采用了同样的优化措施,那就是pre-aggregation和auto-rollup。思路就是预先进行计算,而不是查询后计算。不过OpenTSDB在已发布的最新版本中,还未支持pre-aggregation和rollup。而在开发中的2.4版本中,也只提供了半吊子的方案,它只提供了一个新的接口支持将pre-aggregation和rollup的结果进行写入,但是对数据的pre-aggregation和rollup的计算还需要用户自己在外层实现。

总结

  OpenTSDB的优势在于数据的写入和存储能力,得益于底层依赖的HBase所提供的能力。劣势在于数据查询和分析的能力上的不足,虽然在查询上已经做了很多的优化,但是不是所有的查询场景都能适用。可以说,OpenTSDB在TagValue过滤查询优化,是这次要对比的几个时序数据库中,优化的最差的。在GroupBy和Downsampling的查询上,也未提供Pre-aggregation和Auto-rollup的支持。不过在功能丰富程度上,OpenTSDB的API是支持最丰富的,这也让OpenTSDB的API成为了一个标杆。

欢迎扫码加入钉钉群与我交流!
_

目录
相关文章
|
8天前
|
关系型数据库 MySQL 数据库
RDS MySQL灾备服务协同解决方案构建问题之数据库备份数据的云上云下迁移如何解决
RDS MySQL灾备服务协同解决方案构建问题之数据库备份数据的云上云下迁移如何解决
|
2天前
|
存储 JSON API
淘系API接口(解析返回的json数据)商品详情数据解析助力开发者
——在成长的路上,我们都是同行者。这篇关于商品详情API接口的文章,希望能帮助到您。期待与您继续分享更多API接口的知识,请记得关注Anzexi58哦! 淘宝API接口(如淘宝开放平台提供的API)允许开发者获取淘宝商品的各种信息,包括商品详情。然而,需要注意的是,直接访问淘宝的商品数据API通常需要商家身份或开发者权限,并且需要遵循淘宝的API使用协议。
淘系API接口(解析返回的json数据)商品详情数据解析助力开发者
|
5天前
|
数据采集 API 开发工具
淘系商品详情数据解析(属性youhui券sku详情图等)API接口开发系列
在电商领域,特别是像淘宝(淘系)这样的平台,商品详情数据对于商家、开发者以及数据分析师来说至关重要。这些数据包括但不限于商品属性、优惠券信息、SKU(Stock Keeping Unit)详情、商品图片、售后保障等。然而,直接访问淘宝的内部API接口通常需要特定的权限和认证,这通常只对淘宝的合作伙伴或内部开发者开放。 不过,对于需要这些数据的第三方开发者或商家,有几种方式可以间接获取或解析淘系商品详情数据: ——在成长的路上,我们都是同行者。这篇关于商品详情API接口的文章,希望能帮助到您。期待与您继续分享更多API接口的知识,请记得关注Anzexi58哦!
|
7天前
|
运维 安全 Cloud Native
核心系统转型问题之分布式数据库和数据访问中间件协作如何解决
核心系统转型问题之分布式数据库和数据访问中间件协作如何解决
|
6天前
|
存储 SQL JSON
【Azure Logic App】微软云逻辑应用连接到数据库,执行存储过程并转换执行结果为JSON数据
【Azure Logic App】微软云逻辑应用连接到数据库,执行存储过程并转换执行结果为JSON数据
【Azure Logic App】微软云逻辑应用连接到数据库,执行存储过程并转换执行结果为JSON数据
|
7天前
|
JavaScript Java 关系型数据库
毕设项目&课程设计&毕设项目:基于springboot+vue实现的前后端分离的考试管理系统(含教程&源码&数据库数据)
在数字化时代背景下,本文详细介绍了如何使用Spring Boot框架结合Vue.js技术栈,实现一个前后端分离的考试管理系统。该系统旨在提升考试管理效率,优化用户体验,确保数据安全及可维护性。技术选型包括:Spring Boot 2.0、Vue.js 2.0、Node.js 12.14.0、MySQL 8.0、Element-UI等。系统功能涵盖登录注册、学员考试(包括查看试卷、答题、成绩查询等)、管理员功能(题库管理、试题管理、试卷管理、系统设置等)。
毕设项目&课程设计&毕设项目:基于springboot+vue实现的前后端分离的考试管理系统(含教程&源码&数据库数据)
|
2天前
|
SQL Oracle 关系型数据库
实时计算 Flink版产品使用问题之Oracle数据库是集群部署的,怎么进行数据同步
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
4天前
|
JSON API 数据格式
基于服务器响应的实时天气数据进行JSON解析的详细代码及其框架
【8月更文挑战第25天】这段资料介绍了一个使用Python从服务器获取实时天气数据并解析JSON格式数据的基本框架。主要分为三个部分:一是安装必要的`requests`库以发起HTTP请求获取数据,同时利用Python内置的`json`库处理JSON数据;二是提供了具体的代码实现,包括获取天气数据的`get_weather_data`函数和解析数据的`parse_weather_data`函数;三是对代码逻辑进行了详细说明,包括如何通过API获取数据以及如何解析这些数据来获取温度和天气描述等信息。用户需要根据实际使用的天气API调整代码中的API地址、参数和字段名称。
|
9天前
|
SQL 关系型数据库 MySQL
【揭秘】MySQL binlog日志与GTID:如何让数据库备份恢复变得轻松简单?
【8月更文挑战第22天】MySQL的binlog日志记录数据变更,用于恢复、复制和点恢复;GTID为每笔事务分配唯一ID,简化复制和恢复流程。开启binlog和GTID后,可通过`mysqldump`进行逻辑备份,包含binlog位置信息,或用`xtrabackup`做物理备份。恢复时,使用`mysql`命令执行备份文件,或通过`innobackupex`恢复物理备份。GTID模式下的主从复制配置更简便。
47 2
|
4天前
|
弹性计算 关系型数据库 数据库
手把手带你从自建 MySQL 迁移到云数据库,一步就能脱胎换骨
阿里云瑶池数据库来开课啦!自建数据库迁移至云数据库 RDS原来只要一步操作就能搞定!点击阅读原文完成实验就可获得一本日历哦~

推荐镜像

更多
下一篇
云函数