OpenTSDB原理系列:数据表设计

2024-04-06 19:08

本文主要是介绍OpenTSDB原理系列:数据表设计,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

上一篇文章《OpenTSDB原理系列:元数据模型》讲到了OpenTSDB的基础概念,以及元数据模型,这篇文章介绍OpenTSDB的HBase数据表设计。OpenTSDB共涉及两种类型的数据:Metrics数据以及Annotation(注释)数据,在将这些数据存到HBase表中时,针对RowKey, Qualifier以及Value信息都做了特殊设计,从而使得存储更加高效。

Metrics RowKey设计

metrics数据的HBase RowKey中包含主要组成部分为盐值(Salt)、metrics名称、时间戳、tagKey、tagValue等部分。上篇文章已经讲到,为了统一各个值的长度以及节省空间,对metrics名称、tagKey和tagValue分配了UID信息。所以,在HBase RowKey中实际写入的metrics UID、tagKey UID和tagValue UID。

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

  • SALT:建议开启SALT功能,可以有效提高性能。SALT数据的长度是变长的:如果SALT的值值少于256,那么只用一个字节表示即可;如果需要设置更大的SALT值,也会相应地占用更多的空间。
  • Metric ID:metrics名经过编码后,每个Metric ID的长度为三个字节。
  • Timestamp:这里是整点小时时间戳。
  • tagKey UID & tagValue UID:tagKey和tagValue经过编码后,每个tagKey UID和tagValue UID的长度都为三个字节。tagKey UID和tagValue UID必须成对出现,最少必须存在1对,最多存在8对。

Metrics Qualifier设计

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

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

一个小时中的某一秒(少于3600)最多需要2个字节即可表示,而某一毫秒(少于3600000)最多需要4个字节才可以表示。为了节省空间,OpenTSDB没有使用统一的长度,而是对特定的类型采用特性的编码方法。Qualifer的数据模型主要分为如下三种情况:秒、毫秒、秒和毫秒混合。

秒类型

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

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

  • Value长度:Value的实际长度是Qualifier的最后3个bit的值加1,即(qualifier & 0x07) + 1。表示该时间戳对应的值的字节数。所以,值的字节数的范围是1到8个字节。
  • Value类型:Value的类型由Qualifier的倒数第4个bit表示,即(qualifier & 0x08)。如果值为1,表示Value的类型为float;如果值为0,表示Value的类型为long。
  • 时间戳:时间戳的值由Qualifier的第1到第12个bit表示,即(qualifier & 0xFFF0) >>>4。由于秒级的时间戳最大值不会大于3600,所以qualifer的第1个bit肯定不会是1前4个bits肯定不是1111。

毫秒类型

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

  • Value长度:与秒类型相同。
  • Value类型:与秒类型相同。
  • 时间戳: 时间戳的值由Qualifier的第5到第26个bit表示,即(qualifier & 0x0FFFFFC0) >>>6。
  • 标志位:标志位由Qualifier的前4个bit表示。当该Qualifier表示毫秒级数据时,必须全为1,即(qualifier[0] & 0xF0) == 0xF0。
  • 第27到28个bit未使用。

混合类型

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

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

  • 秒类型和毫秒类型的数量没有限制,并且可以任意组合。
  • 不存在相同时间戳的数据,包括秒和毫秒的表示方式。
  • 遍历混合类型中的所有DataPoint的方法是:
    • 从左到右,先判断前4个bit是否为0xF
    • 如果是,则当前DataPoint是毫秒型的,读取4个字节形成一个毫秒型的DataPoint
    • 如果否,则当前DataPoint是秒型的,读取2个字节形成一个秒型的DataPoint
    • 以此迭代即可遍历所有的DataPoint

Metrics Value设计

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

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

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

单字节

当DataPoint Value为long型,且大于等于-128(Byte.MIN_VALUE),且少于或等于127(Byte.MAX_VALUE)的时候,使用1个字节存储。

两字节

当DataPoint Value为long型,且大于等于-32768(Short.MIN_VALUE),且少于或等于32767(Short.MAX_VALUE)的时候,使用2个字节存储。

四字节

当DataPoint Value为long型,且大于等于0x80000000(Integer.MIN_VALUE),且少于或等于0x7FFFFFFF(Integer.MAX_VALUE)的时候,使用4个字节存储。

八字节

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

当DataPoint Value为float型的时候,使用8个字节表示。

多字节

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

  • 每个格子表示一个DataPoint Value的值,这个DataPoint Value的长度可能是1或2或4或8个字节。
  • DataPoint Value的顺序与Qualifier中时间戳的顺序一一对应。
  • 混合标志:如果最后1个字节为0x01,表示存在秒级类型和毫秒级类型混合的情况。

Annotation数据

Annotation用于描述某一个时间点发生的事件,Annotation的数据为字符串类型,这与数字类型的metrics数据并不同。

注意

  1. Annotation数据只支持秒级时间戳的数据。
  2. Annotation数据不会合并。

Annotation RowKey设计

RowKey的数据模型如下图:

Annotation-RowKey

  • SALT/ Timestamp/Metric UID/ tagKey UID /tagValue UID的意义与metrics RowKey中的意义相同。
  • 把[Metric UID/ tagKey UID /tagValue UID]部分统称为TSUID。实际上,读写注释数据的时候,需要指定的是TSUID,而不是像metrics数据中那样分开指定的。

Annotation Qualifier设计

由于注释数据只支持秒级类型的数据,同时注释类型的数据不支持合并,所以Qualifier的设计相对metrics数据简单一些。Qualifier定义如下:

  • 与metrics数据的Qualifier相比,注释数据的HBase Qualifer的长度是3个字节。
  • 标志位:使用第1个字节表示,而且值必须为0x01。即(qualifier & 0xFF0000)>>>16 == 0x01。
  • 时间戳:使用第2到第3个字节表示。即时间戳的值为(qualifier & 0x00FFFF)。

Annotation Value设计

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

Append模式

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

注意:

  1. 由于使用了HBase的append的接口,每次插入一个新数据,都需要对同一小时的数据都执行一次读取和插入的操作;另外多线程对同一小时的数据进行更新的时候,是不能并发的。这样就大大限制了数据写入的速度了,一般情况下不建议使用这种模式。
  2. append的数据其实就是合并过的数据了,所以不会参与OpenTSDB的Compaction流程。

Append模式RowKey设计

Append模式的RowKey设计与普通模式下写入的metrics数据的RowKey是相同的。

Append模式Qualifier设计

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

  • Append模式的Qualifier使用3个字节表示
  • 标志位: 由第1个字节表示,而且值必须为0x05。即(qualifier & 0xFF0000)>>>16 == 0x05
  • 固定部分:由第2到第3个字节表示,这部分的值固定为0x0000,因此,Append模式的Qualifier固定为0x050000

Append模式Value设计

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

Value的数据结构如下:

  • 上图每一个方块表示的Qualifier与Value的定义,与普通写入模式下的定义相同
  • 遍历Value中的所有DataPoint的方法是:
    • 从左到右,先判断前4个bit是否为0xF
    • 如果是,则当前DataPoint是毫秒型的读取4个字节形成一个毫秒型的Qualifier,从Qualifier中获得Value的长度,然后再读取对应长度的字节数
    • 如果否,则当前DataPoint是秒型的,读取2个字节形成一个秒型的Qualifier,从Qualifier中获得Value的长度,然后再读取对应长度的字节数;
    • 依此迭代即可遍历所有的DataPoint。

本文源自:NoSQL漫谈(nosqlnotes.com)

http://www.nosqlnotes.com/technotes/opentsdb-tabledesign/

这篇关于OpenTSDB原理系列:数据表设计的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/880597

相关文章

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

MySQL按时间维度对亿级数据表进行平滑分表

《MySQL按时间维度对亿级数据表进行平滑分表》本文将以一个真实的4亿数据表分表案例为基础,详细介绍如何在不影响线上业务的情况下,完成按时间维度分表的完整过程,感兴趣的小伙伴可以了解一下... 目录引言一、为什么我们需要分表1.1 单表数据量过大的问题1.2 分表方案选型二、分表前的准备工作2.1 数据评估

Python中的filter() 函数的工作原理及应用技巧

《Python中的filter()函数的工作原理及应用技巧》Python的filter()函数用于筛选序列元素,返回迭代器,适合函数式编程,相比列表推导式,内存更优,尤其适用于大数据集,结合lamb... 目录前言一、基本概念基本语法二、使用方式1. 使用 lambda 函数2. 使用普通函数3. 使用 N

MyBatis-Plus 与 Spring Boot 集成原理实战示例

《MyBatis-Plus与SpringBoot集成原理实战示例》MyBatis-Plus通过自动配置与核心组件集成SpringBoot实现零配置,提供分页、逻辑删除等插件化功能,增强MyBa... 目录 一、MyBATis-Plus 简介 二、集成方式(Spring Boot)1. 引入依赖 三、核心机制

redis和redission分布式锁原理及区别说明

《redis和redission分布式锁原理及区别说明》文章对比了synchronized、乐观锁、Redis分布式锁及Redission锁的原理与区别,指出在集群环境下synchronized失效,... 目录Redis和redission分布式锁原理及区别1、有的同伴想到了synchronized关键字

Linux中的HTTPS协议原理分析

《Linux中的HTTPS协议原理分析》文章解释了HTTPS的必要性:HTTP明文传输易被篡改和劫持,HTTPS通过非对称加密协商对称密钥、CA证书认证和混合加密机制,有效防范中间人攻击,保障通信安全... 目录一、什么是加密和解密?二、为什么需要加密?三、常见的加密方式3.1 对称加密3.2非对称加密四、

setsid 命令工作原理和使用案例介绍

《setsid命令工作原理和使用案例介绍》setsid命令在Linux中创建独立会话,使进程脱离终端运行,适用于守护进程和后台任务,通过重定向输出和确保权限,可有效管理长时间运行的进程,本文给大家介... 目录setsid 命令介绍和使用案例基本介绍基本语法主要特点命令参数使用案例1. 在后台运行命令2.