建议使用以下浏览器,以获得最佳体验。 IE 9.0+以上版本 Chrome 31+ 谷歌浏览器 Firefox 30+ 火狐浏览器
请选择 进入手机版 | 继续访问电脑版
设置昵称

在此一键设置昵称,即可参与社区互动!

确定
我再想想
选择版块
093454tjmehwgqrskef4if.jpg 文字识别 百万调用 1元包年 2020年华为云AI实战营 华为云普惠AI

Lettle whale

发帖: 20粉丝: 4

级别 : 版主

发消息 + 关注

发表于2020-5-7 10:44:51 468 3
直达本楼层的链接
楼主
显示全部楼层
[技术分享] OpenTSDB数据模型

OpenTSDB数据模型

                                                -------本文转载自华为内部论坛-作者:zhongchaoqiang

OpenTSDB通过对HBase表数据(包括HBase RowKeyHBase QualifierHBase Value)的特殊设计,使得存储时序数据时可以更加高效和节省空间。

OpenTSDB的数据表中,存在两种类型的数据:指标(metrics)数据和注释(Annotation)数据。这两种类型的数据有不同的结构设计。

【说明:如非特殊说明,文中字节的顺序是从高位到低位进行描述的,即从左到右进行描述。】

1       指标(Metrics)数据

1.1   HBase RowKey设计

指标数据的HBase RowKey中包含主要组成部分为:盐值(Salt)、指标名、时间戳、标签名、标签值等部分。

为了统一各个值的长度以及节省空间,对指标名、标签名和标签值都进行了统一编码。所以,在HBase RowKey中实际写入的指标ID、标签名ID和标签值ID

         HBase RowKey的数据模型如下图所示:

1.png


说明:

l  SALT建议开启SALT功能,可以有效提高性能。SALT数据的长度根据设置的只觉得。如果SALT的值值少于256,那么只用一个字节表示即可;如果需要设置更大的SALT值,也会相应地占用更多的空间。

l  Metric ID指标名经过编码后,每个Metric ID的长度为三个字节。

l  Timestamp这里的时间戳是以小时为单位的。也就是真实时间戳(单位是秒)/3600的值。

l  Tag Name ID & Tag Value ID标签名和标签值经过编码后,每个Tag Name IDTag Value ID的长度都为三个字节。Tag Name IDTag Value ID必须成对出现,最少必须存在1对,最多存在8对。

1.2   HBase Qualifier设计

HBase Qualifier用于保存一个或多个DataPoint中的时间戳、数据类型、数据长度等信息。

         由于时间戳中的小时级别的信息已经保存在HBase RowKey中了,所以HBase Qualifier只需要保存一个小时中具体某秒或某毫秒的信息即可,这样可以减少数据占用的空间。

一个小时中的某一秒(少于3600)最多需要2个字节即可表示,而某一毫秒(少于3600000)最多需要4个字节才可以表示。为了节省空间,OpenTSDB没有使用统一的长度,而是对特定的类型采用特性的编码方法。

         HBase Qualifer的数据模型主要分为如下三个情况:秒、毫秒、秒和毫秒混合。

1.2.1  秒类型

OpenTSDB接收到一个新的DataPoint的时候,如果请求中的时间戳是秒,那么就会插入一个如下模型的数据。

注:判断请求中的时间戳为秒或毫秒的方法是根据时间戳的大小来判读的。如果时间戳的值的超过无符号整数的最大值(即4个字节的长度),那么该时间戳是毫秒,否则为秒。】

2.png


说明:

l  Value长度Value的实际长度是HBase Qualifier的最后3bit的值加1,即(qualifier & 0x07) + 1。表示该时间戳对应的值的字节数。所以,值的字节数的范围是18个字节。

l  Value类型Value的类型由HBase Qualifier的倒数第4bit表示,即(qualifier & 0x08)。如果值为1,表示Value的类型为float;如果值为0,表示Value的类型为long

l  时间戳:时间戳的值由HBase Qualifier的第1到第12bit表示,即(qualifier & 0xFFF0) >>>4。由于秒级的时间戳最大值不会大于3600,所以qualifer的第1bit肯定不会是1

1.2.2  毫秒类型

OpenTSDB接收到一个新的DataPoint的时候,如果请求中的时间戳是毫秒,那么就会插入一个如下模型的数据。

3.png


说明:

l  Value长度:与秒类型相同。

l  Value类型:与秒类型相同。

l  时间戳 时间戳的值由HBase Qualifier的第5到第26bit表示,即(qualifier & 0x0FFFFFC0) >>>6

l  标志位:标志位由HBase Qualifier的前4bit表示。当该HBase Qualifier表示毫秒级数据时,必须全为1,即(qualifier[0] & 0xF0) == 0xF0

l  2728bit未使用。

 

1.2.3  混合类型

当同一小时的数据发生合并后,就会形成混合类型的HBase Qualifier

合并的方法很简单,就是按照时间戳顺序进行排序后,从小到大依次拼接秒类型和毫秒类型的HBase Qualifier即可。

4.png


说明:

l  秒类型和毫秒类型的数量没有限制,并且可以任意组合。

l  不存在相同时间戳的数据,包括秒和毫秒的表示方式。

l  遍历混合类型中的所有DataPoint的方法是:

Ø  从左到右,先判断前4bit是否为0xF

Ø  如果是,则当前DataPoint是毫秒型的,读取4个字节形成一个毫秒型的DataPoint

Ø  如果否,则当前DataPoint是秒型的,读取2个字节形成一个秒型的DataPoint

Ø  以此迭代即可遍历所有的DataPoint

1.3   HBase Value设计

HBase Value部分用于保存一个或多个DataPoint的具体某个时间戳对应的值。

         由于在HBase Qualifier中已经保存了DataPoint Value的类型和DataPoint Value的长度,所以无论是秒级还是毫秒级的值,都可以用相同的表示方法,而混合类型就是多个DataPoint Value的拼接。

         HBase Value按照长度可以分为如下几种类型:

1.3.1  一字节

         DataPoint Valuelong型,且大于等于-128Byte.MIN_VALU),且少于或等于127Byte.MAX_VALUE)的时候,使用1个字节存储。

1.3.2  二字节

DataPoint Valuelong型,且大于等于-32768Short.MIN_VALU),且少于或等于32767Short.MAX_VALUE)的时候,使用2个字节存储。

1.3.3  四字节

DataPoint Valuelong型,且大于等于0x80000000Integer.MIN_VALU),且少于或等于0x7FFFFFFFInteger.MAX_VALUE)的时候,使用4个字节存储。

1.3.4  八字节

         DataPoint Valuelong型,且不是上面三种类型的时候,使用8个字节存储。

         DataPoint Valuefloat型的时候,使用8个字节表示。

1.3.5  多字节

         按照时间戳的顺序,把多个Value拼接起来的数据模型如下:

5.png


说明:

l  每个格子表示一个DataPoint Value的值,这个DataPoint Value可能是1248个字节。

l  DataPoint Value的顺序与HBase Qualifier中时间戳的顺序一一对应。

l  混合标志:最后1个字节表示是否存在秒级类型和毫秒级类型混合的情况。如果为0x01,表示是混合情况;否则不是。

2       注释(Annotation)数据

         注释数据主要用于描述某一个时间点发生的时间,注释数据的值是字符串类型,而不是指标数据中的数字类型。

注意:

n  注释数据只支持秒级时间戳的数据。

n  注释数据不会合并。

 

2.1   HBase RowKey设计

         HBase RowKey的数据模型如下图:

6.png


说明:

l  SALT/ Timestamp/Metric ID/ Tag Name ID /Tag Value ID的意义与指标数据的HBase RowKey设计中的意义相同。

l  [Metric ID/ Tag Name ID /Tag Value ID]部分统称为TSUID。实际上,读写注释数据的时候,需要指定的是TSUID,而不是像指标数据中那样分开指定的。

2.2   HBase Qualifier设计

         由于注释数据只支持秒级类型的数据,同时注释类型的数据不支持合并,所以HBase Qualifier的设计相对指标数据简单一些。

         HBase Qualifier的模型如下:

7.png


说明:

l  与指标数据的HBase Qualifier相比,注释数据的HBase Qualifer的长度是3个字节。

l  标志位:使用第1个字节表示,而且值必须为0x01。即(qualifier & 0xFF0000)>>>16 == 0x01

l  时间戳:使用第2到第3个字节表示。即时间戳的值为(qualifier & 0x00FFFF)

 

2.3   HBase Value设计

注释数据中的Value保存的是字符串类型的数据。整个HBase Value部分就是注释数据的值。

3       APPEND模式

         OpenTSDB启动APPEND模式后,每个插入的新DataPoint,都会以HBaseappend的方式写入。

注意:

n  由于使用了HBaseappend的接口,每次插入一个新数据,都需要对同一小时的数据都执行一次读取和插入的操作;另外多线程对同一小时的数据进行更新的时候,是不能并发的。这样就大大限制了数据写入的速度了,一般情况下不建议使用这种模式。

n  APEEND的数据其实就是合并过的数据了,所以不会参与OpenTSDBCompaction流程。

3.1   HBase RowKey设计

APPEND模式的HBase RowKey设计与HBase RowKey设计是相同的。

3.2   HBase Qualifier设计

         APPEND模式下,由于同1小时的数据中不存在多个HBase Qualifier,所以只需要使用一个固定的Qualifier即可。

8.png


说明:

l  APPEND模式的HBase Qualifier使用3个字节表示。

l  标志位: 由第1个字节表示,而且值必须为0x05。即(qualifier & 0xFF0000)>>>16 == 0x05

l  固定部分:由第2到第3个字节表示,这部分的值固定为0x0000

l  所以,APPEND模式的HBase Qualifier固定为0x050000

3.3   HBase Value设计

APPEND模式下,HBase Value部分既要保存时间戳,数值类型和数值长度,也要保存对应的数值。

         Value的数据结构如下:

9.png


说明:

l  每个Qualifier的格式与HBase Qualifier设计中的格式相同。

l  每个Value的格式与HBase Qualifier设计中的格式相同。

l  遍历Value中的所有DataPoint的方法是:

Ø  从左到右,先判断前4bit是否为0xF

Ø  如果是,则当前DataPoint是毫秒型的读取4个字节形成一个毫秒型的HBase Qualifier,从HBase Qualifier中获得Value的长度,然后再读取对应长度的字节数;

Ø  如果否,则当前DataPoint是秒型的,读取2个字节形成一个秒型的HBase Qualifier,从HBase Qualifier中获得Value的长度,然后再读取对应长度的字节数;

Ø  依此迭代即可遍历所有的DataPoint

 

本文转载自华为内部论坛-作者:zhongchaoqiang


tsdb

举报
分享

分享文章到朋友圈

分享文章到微博

找虫虫

发帖: 0粉丝: 0

级别 : 中级会员

发消息 + 关注

发表于2020-6-11 19:58:56
直达本楼层的链接
沙发
显示全部楼层

mark,很好的分享~


点赞 评论 引用 举报

whisper_chen

发帖: 1粉丝: 0

级别 : 新手上路

发消息 + 关注

发表于2020-6-16 17:49:59
直达本楼层的链接
板凳
显示全部楼层

学习~

点赞 评论 引用 举报

一朵翔云

发帖: 3粉丝: 0

级别 : 新手上路

发消息 + 关注

发表于2020-6-16 17:57:11
直达本楼层的链接
地板
显示全部楼层

原来数据还可以这样存储!

点赞 评论 引用 举报

游客

富文本
Markdown
您需要登录后才可以回帖 登录 | 立即注册