openTSDB源码详解之rowKey生成

版权声明:如若转载,请联系作者。 https://blog.csdn.net/liu16659/article/details/84031862

openTSDB源码详解之rowKey生成

openTSDB的一个非常好的设计就是其rowKey的生成。下面详细介绍一下。

1.相关处理类

openTSDB往hbase中写入数据的处理过程,我之前就已经分析过,主要涉及的类有:

  • addPointInternal(...)
    在这里插入图片描述

这里主要讲解的是,如何一个row key是如何生成的。

2.具体步骤

2.1 row_size的确定
2.1.2 SALT_WIDTH

首先对于一个rowKey,肯定是有大小的,但是这个rowKey的大小该怎么确定呢?因为这个rowKey是需要写入到HBase中的,也就是需要通过网络的传输才能到达HBase端,所以不可能无限长,即需要精确到一个具体的长度。
openTSDB中的rowKey的大小用变量row_size表示。其具体的生成规则如下图所示:
在这里插入图片描述其中的 SALT_WIDTH()函数返回的是SALT WIDTH,它是一个static修饰的int型变量,初始值为0,如下图所示:
在这里插入图片描述

2.1.2 metric_widthtag_name_widthtag_value_width

metric_width 代表的就是metric的长度。在openTSDB系统中,默认的长度是3。该值来自tsdb.metrics.width()函数的返回值。
在这里插入图片描述

width() 方法如下:
在这里插入图片描述
而id_width的值设置过程如下:
在这里插入图片描述在这里插入图片描述
调用构造函数UniqueId(...)的过程如下:
在这里插入图片描述
最终可以看到这些值默认为3
在这里插入图片描述
针对笔者传输的数据,可以推导出最后生成的row_size的大小就是row_size = 0 + 3 + 4 + 3*1 + 3*1 = 13,经过debug验证,也可以看到的确就是13。

2.2 字节数组row

在这里插入图片描述

2.3 pos变量

在这里插入图片描述
问题1:使用pos变量的原因是,控制对字节数组row的复制控制【每将一个值复制到row[]之后,就需要动态改变row[]的起始位置,这个位置就是pos定义的】
因为我没有开启 加盐处理功能,所以这里的pos的初始值就是0。

2.4 为字节数组row赋值

在这里插入图片描述上述copyInRowKey(…)的功能就是将metric对应的uid值放入到row中。而其中的 getOrCreateId()方法则是获取metric对应的uid值。该方法主要调用的其它方法如下:

  • getIdAsync() 方法
    在这里插入图片描述

  • 从缓存中获取uid
    在这里插入图片描述

  • Deferred 类的构造方法
    在这里插入图片描述

  • copyInRowKey()方法
    在这里插入图片描述
    注意上面一张图中row和下面一张图的row的变化。这个变化就体现了将metric的id放到了rowKey中。
    在这里插入图片描述

2.3 pos值的变化

在这里插入图片描述因为已经处理了metric,所以需要将其pos自增一下。
同时,因为暂时不着急处理timestamp,所以再次将pos自增处理。

2.4 tag pair的处理

在这里插入图片描述
最后,需要在row中放入 tag pair,方式是采用for循环处理。
主要调用方法如下:

  • resolveOrCreateAll()
    在这里插入图片描述
  • resolveAllInternal()方法
    在这里插入图片描述
2.5 row的大致部分

经过上述几个步骤的处理,则会生成一个row值:
在这里插入图片描述

2.6 rowKey的完善

上述的步骤只是生成了一个rowKey的框架,但是还没有完全生成一个rowKey,因为还有最后一个步骤。接着会进入WriteCB这个回调类,如下:
在这里插入图片描述
注意这里的offset的取值:metrics.width() + Const.SALT_WIDTH()这个是用于将当前value所在小时的时间戳放入到row中。所以需要偏移metrics.width() + Const.SALT_WIDTH() 这样的长度。这里使用base_time = 1542096000举例,在未执行Bytes.setInt()方法之前,row的值如下图示:

在这里插入图片描述
使用Bytes类的setInt()方法修改row的值。setInt()主要的是>>>运算,这个运算符的意思是指:右移指定的位数,左边的空白位置0。得到的row值如下:

在这里插入图片描述
可能有人会问,为什么使用的是Bytes.setInt()这个方法?要知道,openTSDB只是根据timestamp(实质是 base_time,这个base_time我在后面会补充介绍)去生成rowKey的一部分,所以这一部分是什么样的逻辑不重要了,重要的是这个逻辑需要保持相同的base_time 映射到固定的byte[] 值。而openTSDB在rowKey的生成过程中采取的方法就是使用>>>去处理(timestamp)base_time ,从而保证rowKeybase_time相同时,其base_time对应的rowKey部分也相同。

到这里,一个完整的rowKey就生成了。

3.其它

3.1 base_time字段的生成

这个base_time代表的值就是当前value传递过来所在的timestamp。例如:对于一个timestamp=1542088140,处理过程就是取该timestamp所在小时 0分0秒的timestamp值。这也能解释为什么opentsdb中的存储按照每小时进行行存储,而不是每个时间戳一行。
在这里插入图片描述
这个Const.MAX_TIMESPAN定义如下:

  /** Max time delta (in seconds) we can store in a column qualifier.  */
  public static final short MAX_TIMESPAN = 3600;

代表的是一个小时的秒跨度。对其MAX_TIMESPAN 取余之后,该余数就是秒数,再减去这个秒数就得到hh:00:00的值。
上面的值处理之后,得到的base_time值变为了1542085200。如下示:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/liu16659/article/details/84031862