OpenTSDB-数据存储详解

46次阅读

共计 5562 个字符,预计需要花费 14 分钟才能阅读完成。

本文首发于 vivo 互联网技术 微信公众号
链接:https://mp.weixin.qq.com/s/qayKiwk5QAIWI7-nyD3FVA
作者:DuZhimin

随着互联网、尤其是物联网的倒退,咱们须要把各种类型的终端实时监测、查看与剖析设施所采集、产生的数据记录下来,在有工夫的坐标中将这些数据连点成线,往过来看能够做成多纬度报表,揭示其趋势性、规律性、异样性; 往将来看能够做大数据分析,机器学习,实现预测和预警。

这些数据的典型特点是:产生频率快 (每一个监测点一秒钟内可产生多条数据)、 重大依赖于采集工夫 (每一条数据均要求对应惟一的工夫)、 测点多信息量大(实时监测零碎均有成千上万的监测点,监测点每秒钟都产生数据,每天产生几十 GB 的数据量)。

基于工夫序列数据的特点,关系型数据库无奈满足对工夫序列数据的无效存储与解决,因而迫切需要一种专门针对工夫序列数据来做优化解决的数据库系统。

一、简介

1、时序数据

时序数据是基于工夫的一系列的数据。

2、时序数据库

时序数据库就是寄存时序数据的数据库,并且须要反对时序数据的疾速写入、长久化、多纬度的聚合查问等基本功能。

比照传统数据库仅仅记录了数据的以后值,时序数据库则记录了所有的历史数据。同时时序数据的查问也总是会带上工夫作为过滤条件。

3、OpenTSDB

毫无脱漏的接管并存储大量的工夫序列数据。

3.1、存储

  1. 无需转换,写的是什么数据存的就是什么数据
  2. 时序数据以毫秒的精度保留
  3. 永恒保留原始数据

3.2、扩展性

  1. 运行在 Hadoop 和 HBase 之上
  2. 可扩大到每秒数百万次写入
  3. 能够通过增加节点扩容

3.3、读能力

  1. 间接通过内置的 GUI 来生成图表
  2. 还能够通过 HTTP API 查问数据
  3. 另外还能够应用开源的前端与其交互

4、OpenTSDB 外围概念

咱们来看一下这样一段信息:2019-12-5 22:31:21 版本号为‘3.2.1’的某产品客户端的首页 PV 是 1000W

  1. Metric:指标,即平时咱们所说的监控项。譬如下面的 PV
  2. Tags:维度,也即标签,在 OpenTSDB 外面,Tags 由 tagk 和 tagv 组成的键值对,即 tagk=takv。标签是用来形容 Metric 的,比方下面的某产品客户端的版本号 version=‘3.2.1’
  3. Value:一个 Value 示意一个 metric 的理论数值,比方:1000W
  4. Timestamp:即工夫戳,用来形容 Value 是什么时候产生的:比方:2019-12-5 22:31:21
  5. Data Point:即某个 Metric 在某个工夫点的数值,Data Point 包含以下局部:Metric、Tags、Value、Timestamp
  6. 保留到 OpenTSDB 的数据就是无数个 DataPoint

下面形容 2019-12-5 22:31:21 版本号为‘3.2.1’的某产品客户端的首页 PV 是 1000W,就是 1 个 DataPoint。

二、OpenTSDB 的部署架构

1、架构图

2、阐明

  1. OpenTSDB 底层是应用 HBase 来存储数据的,也就是说搭建 OpenTSDB 之前,必须先搭建好 HBase 环境。
  2. OpenTSDB 是由一系列的 TSD 和实用的命令行工具组成。
  3. 利用通过运行一个或多个 tsd(Time Series Daemon,OpenTSDB 的节点)来与 OpenTSDB 的交互。
  4. 每个 TSD 是独立的,没有 master,没有共享状态,所以你能够运行尽可能多的 TSD 来解决工作负载。

三、HBase 简介

从 OpenTSDB 的部署架构中咱们看到 OpenTSDB 是建设在 HBase 之上的,那么 HBase 又是啥呢?为了更好的分析 OpenTSDB,这里咱们简要介绍一下 HBase。

1、HBase 是一个高可靠性、强一致性、高性能、面向列、可伸缩、实时读写的分布式开源 NoSQL 数据库。

2、HBase 是无模式数据库,只须要提前定义列簇,并不需要指定列限定符。同时它也是无类型数据库,所有数据都是按二进制字节形式存储的。

3、它把数据存储在表中,表按“行键,列簇,列限定符和工夫版本”的四维坐标系来组织,也就是说如果要惟一定位一个值,须要四个都惟一才行。上面参考 Excel 来阐明一下:

4、对 HBase 的操作和拜访有 5 个根本形式,即 Get、Put、Delete 和 Scan 以及 Increment,HBase 基于非行键值查问的惟一路径是通过带过滤器的扫描。

5、数据在 HBase 中的存储(物理上):

6、数据在 HBase 中的存储(逻辑上):

四、撑持 OpenTSDB 运行的 HBase 表

如果你第一次用你的 HBase 实例运行 OpenTSDB,须要创立必要的 HBase 表,OpenTSDB 运行仅仅须要四张表:tsdb, tsdb-uid, tsdb-tree 和 tsdb-meta,所有的 DataPoint 数据都保留在这四张表中,建表语句如下:

1、tsdb-uid

create 'tsdb-uid',
{NAME => 'id', COMPRESSION => 'NONE', BLOOMFILTER => 'ROW', DATA_BLOCK_ENCODING => 'PREFIX_TREE'},
{NAME => 'name', COMPRESSION => 'NONE', BLOOMFILTER => 'ROW', DATA_BLOCK_ENCODING => 'PREFIX_TREE'}

2、tsdb

create 'tsdb',
{NAME => 't', VERSIONS => 1, COMPRESSION => 'NONE', BLOOMFILTER => 'ROW', DATA_BLOCK_ENCODING => 'PREFIX_TREE'}

3、tsdb-tree

create 'tsdb-tree',
{NAME => 't', VERSIONS => 1, COMPRESSION => 'NONE', BLOOMFILTER => 'ROW', DATA_BLOCK_ENCODING => 'PREFIX_TREE'}

4、tsdb-meta

create 'tsdb-meta',
{NAME => 'name', COMPRESSION => 'NONE', BLOOMFILTER => 'ROW', DATA_BLOCK_ENCODING => 'PREFIX_TREE'}

前面将对照理论数据来专门解说这四张表别离存储的内容。

五、OpenTSDB 是如何把一个数据点保留到 HBase 中的呢?

1、首先检查一下四个表外面的数据

从下面看,四个表外面的数据都是空的

2、而后咱们往 OpenTSDB 写一个数据点

@Test
public void addData() {
    String metricName = "metric";
    long value = 1;
    Map<String, String> tags = new HashMap<String, String>();
    tags.put("tagk", "tagv");
    long timestamp = System.currentTimeMillis();
    tsdb.addPoint(metricName, timestamp, value, tags);
    System.out.println("------------");
}

3、插入数据之后咱们再来查看一下四个表数据

发现 HBase 外面有数据,在 tsdb-uid、tsdb、和 tsdb-meta 表外面有数据,而 tsdb-tree 表外面没任何数据,上面咱们针对这些数据做一下具体分析。

4、tsdb-tree 表

它是一张索引表,用于展现树状构造的,相似于文件系统,以不便其余零碎应用,这里咱们不做深刻的剖析。

通过配置项 tsd.core.tree.enable_processing 来关上是否须要往此表外面写入数据。

5、tsdb-meta 表

这个表是 OpenTSDB 中不同工夫序列的一个索引,能够用来存储一些额定的信息,该表只有一个列族 name,两个列,别离为 ts_meta、ts_ctr。这个表外面的数据是能够依据配置项配置来管制是否生成与否,生成几个列,具体的配置项有:

tsd.core.meta.enable_realtime_ts
tsd.core.meta.enable_tsuid_incrementing
tsd.core.meta.enable_tsuid_tracking

Row Key 和 tsdb 表一样,其中不蕴含工夫戳,<metric_uid><tagk1><tagv1>[…<tagkN><tagvN>]

ts_meta Column 和 UIDMeta 类似,其为 UTF- 8 编码的 JSON 格局字符串

ts_ctr Column 计数器,用来记录一个工夫序列中存储的数据个数,其列名为 ts_ctr,为 8 位有符号的整数。

6、tsdb-uid 表数据分析

tsdb-uid 用来存储 UID 映射,包含正向的和反向的。存在两列族,一列族叫做 name 用来将一个 UID 映射到一个字符串,另一个列族叫做 id,用来将字符串映射到 UID。列族的每一行都至多有以下三列中的一个:

  • metrics 将 metric 的名称映射到 UID
  • tagk 将 tag 名称映射到 UID
  • tagv 将 tag 的值映射到 UID

如果配置了 metadata,则 name 列族还能够包含额定的 metatata 列。

6.1、id 列族

  • Row Key:理论的指标名称或者 tagK 或者 tagV
  • Column Qualifiers:metrics、tagk、tagv 三种列类型中一种
  • Column Value:一个无符号的整数,默认是被编码为 3 个 byte,自增的数字,其值为 UID

6.2、name 列族

  • Row Key:UID,就是 ID 列簇的值
  • Column Qualifiers:metrics、tagk、tagv、metrics_meta、tagk_meta、tagv_meta 六种列类型中一种,*_meta 是须要开启 tsd.core.meta.enable_realtime_uid 才会生成
  • Column Value:与 UID 对应的字符串,对于一个 *_meta 列,其值将会是一个 UTF- 8 编码的 JSON 格局字符串。不要在 OpenTSDB 内部去批改该值,其中的字段程序会影响 CAS 调用。

7、tsdb 表:

工夫点数据就保留在此表中,只有一个列簇 t:

7.1、RowKey 格局

  • UID:默认编码为 3 Bytes,而工夫戳会编码为 4 Bytes
  • salt:打散同一 metric 不同工夫线的热点
  • metric, tagK, tagV:理论存储的是字符串对应的 UID(在 tsdb-uid 表中)
  • timestamp:每小时数据存在一行,记录的是每小时整点秒级工夫戳

7.2、Column 格局

column qualifier 占用 2 Bytes 或者 4 Bytes,

占用 2 Bytes 时示意以秒为单位的偏移,格局为:

  • 12 bits: 绝对 row 示意的小时的 delta, 最多 2^ 12 = 4096 > 3600 因而没有问题
  • 1 bit: an integer or floating point
  • 3 bits: 表明数据的长度,其长度必须是 1、2、4、8。000 示意 1 个 byte,010 示意 2byte,011 示意 4byte,100 示意 8byte

占用 4 Bytes 时示意以毫秒为单位的偏移,格局为:

  • 4 bits:十六进制的 1 或者 F
  • 22 bits: 毫秒偏移
  • 2 bit: 保留
  • 1 bit: an integer or floating point,0 示意整数,1 示意浮点数
  • 3 bits: 表明数据的长度,其长度必须是 1、2、4、8。000 示意 1 个 byte,010 示意 2byte,011 示意 4byte,100 示意 8byte

7.3、value

value 应用 8 Bytes 存储,既能够存储 long, 也能够存储 double。

7.4、tsdb 表设计的特点:

  1. metric 和 tag 映射成 UID,不存储理论字符串,以节约空间。
  2. 每条工夫线每小时的数据点归在一行,每列是一个数据点,这样每列只须要记录与这行起始工夫偏移,以节俭空间。
  3. 每列就是一个 KeyValue。

六、写在最初

1、利用场景

  • 作为时序数据库,OpenTSDB 不仅仅能够提供原始数据的查问,并且还反对对原始数据的聚合能力,反对过滤、过滤之后的聚合计算。
  • 反对降采样查问,比方原始数据是 1 分钟一个数据点,如果我想 1 个小时一个数据点进行展现,也能反对。
  • 反对依据维度分组查问,比方我有一个中国地市的数据,当初我想依据省份进行分组之后查问,也能反对。

2、应用注意事项

  • OpenTSDB 默认状况下的字符集是 ISO-8859-1, 为什么会应用这个字符集呢,是因为它的编码是单字节编码,编码后的长度是固定的,如果要反对中文,须要对源码进行编译,批改为 UTF- 8 即可。
  • 默认提供的 HBase 建表语句是没有预分区的,这样会导致大批量数据写入的时候有热点问题,倡议进行预分区。
  • OpenTSDB 不适宜超大数据量,在千万级、亿级中提取几万条数据,比方某个指标半年内的 5 分钟级别的数据,还是很快响应的。但如果再提取多点数据,几十万,百万这样的量级,又或者提取后再做个聚合运算,OpenTSDB 就勉为其难,理论应用的时候用作服务端机器的监控无任何问题,如果作为客户端 APP 监控,响应就比拟缓慢。
  • OpenTSDB 只有 4 张 HBase 表,所有的数据都寄存在一张表,这就象征在 OpenTSDB 这个层级上是无奈更小的粒度来区别对待不同业务,比方不同的业务建不同的表存储数据。
  • OpenTSDB 反对实时聚合计算性能,然而基于单点,所以运算能力无限。

3、瞻望

如果须要反对特大批量时序数据,倡议应用 Druid 或 InfluxDB,其中 InfluxDB 是最易用的时序数据库。

更多内容敬请关注 vivo 互联网技术 微信公众号

注:转载文章请先与微信号:Labs2020分割。

正文完
 0