这一节我们简单介绍一下HBase的行信息。文章前半部分会对照源码介绍,后面会有我自己画的图,大家如果对这些信息已经比较了解了,跳过源码对照部分看后面的图,加深一下印象。
  下面简单分析一下HBase中对于每一行的存储,这个知识点至关重要,以至于会影响到我们在后面的很多流程的分析。
  根据下图,我们可以得到以下分析:
  1.首先计算了keyLength,让我们来到KeyValue.getKeyDataStructureSize。可以看到这里有一个常量KEY_INFRASTRUCTURE_SIZE。
  其中常量由以下三部分组成
  ROW_LENGTH_SIZE + FAMILY_LENGTH_SIZE + TIMESTAMP_TYPE_SIZE
 
  ROW_LENGTH_SIZE = Bytes.SIZEOF_SHORT
  FAMILY_LENGTH_SIZE = Bytes.SIZEOF_BYTE
  TIMESTAMP_TYPE_SIZE = TIMESTAMP_SIZE + TYPE_SIZE
  TIMESTAMP_SIZE = Bytes.SIZEOF_LONG
  TYPE_SIZE = Bytes.SIZEOF_BYTE
   也就是说,这里的KeyValue.getKeyDataStructureSize获得的是一行中除value以外的总长度。
  2.接下来计算了总长度,让我们来到KeyValue.getKeyValueDataStructureSize。
  让我们首先分析没有tags的长度。
  来看两个公式:
  1.KEYVALUE_INFRASTRUCTURE_SIZE = ROW_OFFSET
  2.ROW_OFFSET =
    Bytes.SIZEOF_INT /*keylength*/ +
    Bytes.SIZEOF_INT /*valuelength*/;
  由这两个公式我们就容易知道,这里的key的最大长度不得大于Integer.MAX
  value的长度不得大于Integer.MAX_VALUE。
  然后获取了key的总长度,最后获取了value的长度。这些就是这一行的总长度。
   接着我们来分析含tags的长度。
  让我们先来看两个公式:
  KEYVALUE_WITH_TAGS_INFRASTRUCTURE_SIZE = ROW_OFFSET + TAGS_LENGTH_SIZE
  TAGS_LENGTH_SIZE = Bytes.SIZEOF_SHORT
  这里的含义就是tags的总长度不得大于Short.MAX_VALUE。因此,其总长度的值相比没有tags,多了一个 Bytes.SIZEOF_SHORT,也多了一个tagsLength。
 
  同样,我们可以从下面的图得到佐证。
  其中row的长度不得大于Short.MAX_VALUE
  family的长度不得大于Byte.MAX_VALUE
  qualifier的长度不得大于Integer.MAX_VALUE - rlength - flength
  也就是说row + family + qualifier的总长度不得大于Integer.MAX_VALUE
  另外 2 + 1 + 8 + 1 + row + family + qualifier 的总长度不得大于Integer.MAX_VALUE
  这里的2 + 1 + 8 + 1 就是KeyValue.KEY_INFRASTRUCTURE_SIZE
  根据上面的分析我们就可以得出结论。每个Cell的byte[]中的存放数据的规则是这样的。
  首先我们分析不含tags的长度:
  2 Size of the row length field in bytes
  1 Size of the family length field in bytes
  8 Size of the timestamp field in bytes
  1 Size of the key type field in bytes
  rlength row length
  flength family length
  qlength qualifier length
  以上的总长度为keyLength
  vlength value length
  上面的长度为vlength
 
  keyLength vlength rlength row flength family qualifier timestamp type.getCode() value
 
  下面我们分析含tags的长度:
  上面的长度一样,只是在后面添加了一系列与tags相关的长度
    keyLength vlength rlength row flength family qualifier timestamp type.getCode() value
  tagsLength tlen + Tag.TYPE_LENGTH_SIZE t.getType() tag.value ...
  getKeyLength获取的是rlength row flength family qualifier timestamp type.getCode()
  getValueLength获取的是value
  也就是说这里的总长度为
  4 keyLength
  4 vlength
  getKeyLength() = Bytes.toInt(this.bytes, this.offset)
  getValueLength() = Bytes.toInt(this.bytes, this.offset + Bytes.SIZEOF_INT)
  首先让我们来看一张图:这里我将上面用公式描述的进行了图形化展示。
  根据上面这张图,大家可能很容易就理解了KeyValue.createByteArray方法了。接下来我们再简单介绍一下keyToString方法。这里引入一个方法toString(),主要是为了让大家知道上面方法的传参,也方便我接下来的讲解。
  做一个解说,这里的ROW_OFFSET我们在上面讲过,是8个字节。
  也就是说在keyToString方法中Bytes.toShort(b,o)获得的是rlength。由于偏移量是8,获取8后面的short的值,也就是上图所示的rlength。
  接下来的columnoffset容易理解,这里就直接偏移到了family。
  接着columnoffset - 1获取的也就是flength。
  这里的columnlength稍有费解,不过根据上面的图,还是比较简单的,只是我在刚看的时候被蒙住了。
  为了了解这里的columnlength,我们要清楚keyToString方法中传入的l,也就是在toStirng方法中调用的getKeyLength()。我在上面的图已经标出来了,包括我在上面也提到过keyLength。也就是说,这里的l就是keyLength。他在减去TIMESTAMP_TYPE_SIZE(9个字节,包括timestamp的8个字节与type.getCode的一个字节),减去(columnoffset - o)后,获得的值就是qlength。也就是我们常说的列名。置于方法后面的内容我就不一一描述了,相信大家看了上面的图后就很清楚了。
很多同学可能觉得这一节并没有什么重要意义,其实我这里之所以作为一节来讲,是要作为一个铺垫,在晚上更新的《HBase之Table.put客户端流程》会提到这个流程,到时我就简单略过,因为那个流程会比较复杂。
  这一节就简单介绍到这里,我的邮箱是15935152719@163.com,欢迎大家来信交流沟通相关技术。另外,如果感觉不错,希望留下你的赞。你的肯定是小编继续前进的动力。
 

HBase之行信息简析的更多相关文章

  1. 痞子衡嵌入式:简析i.MXRT1170 XECC功能特点及其保护串行NOR Flash和SDRAM之道

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是i.MXRT1170 XECC功能特点及其保护串行NOR Flash和SDRAM之道. ECC 是 "Error Correc ...

  2. Linux 目录结构学习与简析 Part1

    linux目录结构学习与简析 by:授客 QQ:1033553122 说明: /             linux系统目录树的起点 =============== /bin      User Bi ...

  3. DiskGenius注册算法简析

    初次接触DiskGenius已经成为遥远的记忆,那个时候还只有DOS版本.后来到Windows版,用它来处理过几个找回丢失分区的案例,方便实用.到现在它的功能越来越强大,成为喜好启动技术和桌面支持人员 ...

  4. Icarus Verilog和GTKwave使用简析

    Icarus Verilog和GTKwave使用简析 来源 http://blog.csdn.net/husipeng86/article/details/60469543 本文测试文件在window ...

  5. OpenStack之虚机冷迁移代码简析

    OpenStack之虚机冷迁移代码简析 前不久我们看了openstack的热迁移代码,并进行了简单的分析.真的,很简单的分析.现在天气凉了,为了应时令,再简析下虚机冷迁移的代码. 还是老样子,前端的H ...

  6. OpenStack之Glance源码简析

    Glance简介 OpenStack镜像服务器是一套虚拟机镜像发现.注册.检索. glance架构图: Glance源码结构: glance/api:主要负责接收响应镜像管理命令的Restful请求, ...

  7. 基于IdentityServer4的OIDC实现单点登录(SSO)原理简析

    写着前面 IdentityServer4的学习断断续续,兜兜转转,走了不少弯路,也花了不少时间.可能是因为没有阅读源码,也没有特别系统的学习资料,相关文章很多园子里的大佬都有涉及,有系列文章,比如: ...

  8. Flink源码阅读(一)——Flink on Yarn的Per-job模式源码简析

    一.前言 个人感觉学习Flink其实最不应该错过的博文是Flink社区的博文系列,里面的文章是不会让人失望的.强烈安利:https://ververica.cn/developers-resource ...

  9. ASCII、Unicode、UTF-8、UTF-16、GBK、GB2312、ANSI等编码方式简析

    ASCII.Unicode.UTF-8.UTF-16.GBK.GB2312.ANSI等编码方式简析 序言 从各种字节编码方法中,能看到那个计算机发展的洪荒时期的影子. ASCII ASCII码有标准A ...

随机推荐

  1. C# 通过 Quartz .NET 实现Timer Job并将其注册成为Windows Service

    之前的一篇文章讲述了如何通过 Quartz .NET 实现 Timer Job (http://www.cnblogs.com/mingmingruyuedlut/p/8037263.html) 在此 ...

  2. Python Trick —— 命令行显示

    1 应用场景 在命令行展示下,有以下两种场景. 进度条显示.在同一行展示不断的更新的进度条. 信息显示/隐藏控制.比如希望向多个用户展示不同信息,各个用户彼此保密. 2 进度条展示 跟c语言类似,打印 ...

  3. JS的变量的值怎么传递给PHP的变量?

    get: <script> name="xxx"; window.location='xxx.php? name='+name; post: <script> ...

  4. 【spring】-- springboot配置全局异常处理器

    一.为什么要使用全局异常处理器? 什么是全局异常处理器? 就是把错误异常统一处理的方法. 应用场景: 1.当你使用jsr303参数校验器,如果参数校验不通过会抛异常,而且无法使用try-catch语句 ...

  5. spring 应用

    Spring框架本身会托管bean. 1.使用时需要注意对于包本身扫描配置. 2.使用注解本身包需要在扫描路径下.

  6. 【省选十连测之九】【DP】【组合计数去重】【欧拉函数】基本题

    目录 题意: 输入格式: 输出格式: 数据范围: 思路: 嵌套题的转移 基本题的转移 Part1 Part2 Part3 代码 题意: 这是一个关于括号组合的题. 首先定义一道题是由'(',')',' ...

  7. 20181115 python-第一章学习小结part2

    Python基本知识 变量,用来存储中间计算结果,在后面可进行调用被使用的东西,叫做变量. 变量的命名规则: 字母,数字,下划线组合 不能用数字开头 常见的关键字不能用啊 常量,不会变的量,称作常量. ...

  8. using Sysyem.Net.Http命名空间引用不了的解决方案

    1.查看.Net Framework的框架是否是在4.5之上,如果不是要下载4.5之上的目标框架. 2.在引用器里面添加using System.Net.Http命名空间 选择项目列表中的“引用”-- ...

  9. vbs脚本实现自动打字祝福&搞笑

    脚本祝福礼物 概述 听说抖音上流行一种用代码做程序表白的东西,,,, 当然我也不是要表白,,,, 但是好像蛮有意思的,,,, 于是,又学了一下vbs脚本,做了几个很不错的祝福脚本,不懂代码的可以直接戳 ...

  10. SSM 框架搭建

    SSM框架搭建(Spring.SpringMVC.Mybatis) 一:基本概念 Spring :      Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框 ...