本文首发于 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写一个数据点

@Testpublic 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_tstsd.core.meta.enable_tsuid_incrementingtsd.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分割。