HFile是HBase存储数据的文件组织形式。HFile经历了三个版本,其中V2在0.92引入,V3在0.98引入。HFileV1版本的在实际使用过程中发现它占用内存多,HFile V2版本针对此进行了优化,HFile V3版本基本和V2版本相同,只是在cell层面添加了Tag数组的支持。

一 HFile 文件结构

从以上图片可以看出HFile主要分为四个部分:

Scanned Block Section: 顺序扫描HFile,这个section的所有数据块都被读取,包括Leaf Index Block 和 Bloom Block

Non-Scanned Block Section: 顺序扫描HFile,这个section的数据不会被读取,主要包括元数据数据块等

Load-On-Open-Section: 这部分数据在HRegionServer启动时候,实例化HRegion并创建HStore的时候会将所有HFile的Load-On-Open-Section里的数据加载进内存,主要存放了Root Data Index, Meta Index,FileInfo以及BloomFilter的元数据等

Trailer: 这部分主要记录HFile的一些基本信息,各个部分的偏移量和寻址信息

从物理角度看,如图示:

二 HFileBlock

HFile会被切分为多个大小相等的block,每一个block大小可以在创建表列簇的时候通过blockSize参数指定,默认是64K,较大的blockSize有利于scan,较小的有利于随即查询(get)。

所有的block都有相同的数据结构,HBase将block块抽象成HFile

Block。HFileBlock支持2种类型:一种类型不支持checksum,一种不支持。我们选用不支持checksum的HFileBlock解释,下面是HFile

Block的内部结构:

从上图可知,HFileBlock主要分为2个部分: Block Header 和 Block Dada. 其中Block Header 用来存储元数据,包括block 类型,压缩block大小,上一个block的偏移量等; 而Block Data主要存储具体的数据。

Block Type: 主要用来记录该Block的类型,HBase总共有8种Block

Type, 每一种block type对应的block都存储不同的数据内容,有的存储用户数据,有的存储索引数据,有的存储meta元数据。对于任意一种类型的HFileBlock,都有着相同结构的Block Header,但是 Block Data结构可能去不相同,以下是简单的Block Type介绍:

2.1 Trailer Block

主要记录了HFile的基本信息以及各个部分的偏移量等

HFile在读取数据的时候,首先会解析Trailer Block,并加载到内存,然后再进一步加载Load-On-Open section的数据,具体步骤如下:

2.1.1 首先加载HFile版本信息: HBase中version包含major version和minor version两部分,前者决定了HFile的主版本v1,v2 or v3,后者决定了在主版本的基础上是否支持一些微小的修正,比如是否支持checkum等。

2.1.2 根据HFile版本信息,获取trailer的长度,因为版本的trailer长度或许不一样,然后再根据trailer长度加载整个HFile Trailer Block

2.1.3 加载Load-On-Open section到内存,起始偏移量是trailer中记录的LoadOnOpenDataOffset,结束位置是HFile的length – trailer的length

2.2 Data Block

Data Block是HBase中数据存储的最小单元,它存储的是用户KeyValue数据,数据结构如图所示:

KeyValue: 是由四部分组成的

2.2.1 Key Length: 存储key的长度,本身是4个字节

2.2.2 Value Length: 存储value的长度,本身是4个字节

2.2.3 Key: 存储数据的key,由Row Key Length+Row Key+Column Family Length +Column Family+Column Qualifier + TimeStamp+Key Type

2.2.3.1 Row Key Length: 存储row key的长度,总共2字节

2.2.3.2 Row : 存储row的实际内容,其大小为row key length

2.2.3.3 Column Family Length:存储列簇 Column Family的长度,占1字节

2.2.3.4 Column Family:存储Column Family实际内容,大小为Column Family Length;

2.2.3.5 Column Qualifier:存储Column Qualifier对应的数据,既然key中其他所有字段的大小都知道了,整个key的大小也知道了,那么这个Column Qualifier大小也是明确的了,无需再存储其length

2.2.3.6 Time Stamp:存储时间戳Time Stamp,占8字节

2.2.3.7 Key Type:存储Key类型Key Type,占1字节,Type分为Put、Delete、DeleteColumn、DeleteFamilyVersion、DeleteFamily等类型,标记这个KeyValue的类型

KEY基础设施大小(存储各个部分长度的大小):

KEY_INFRASTRUCTURE_SIZE = ROW_LENGTH_SIZE + FAMILY_

LENGTH_SIZE + TIMESTAMP_SIZE + TYPE_SIZE;

也就是:存储 row key的长度的大小 + 存储 column family 的长度的大小 + 存储timestamp长度的大小 + 存储key type长度的大小 = 2 + 1 + 8 + 1 = 12字节

KEY数据结构大小 = KEY_INFRASTRUCTURE_SIZE + ROW KEY LENGTH + COLUMN FAMILY LENGTH + COLUMNQUALIFIER LENGTH + TIMESTAMP LENGTH + KEY TYPE LENGTH

也就是:KEY基础设施大小 + ROW KEY数据长度 + COLUMN FAMILY 数据长度 + COLUMN QUALIFEIR 数据长度 + 时间戳长度 + KEY TYPE数据长度

2.2.4 Value 存储单元格CELL实际对应的值

2.3 BloomFilter Meta Block & Bloom Block

BloomFilter对于HBase随机读的性能至关重要,他可以避免读取一些不会用到HFile,减少实际的IO次数,提高随机读的性能。

它的原理就是通过位数组来实现过滤,初始状态每一位都是0

然后BloomFilter对一个集合使用k个独立的hash函数,分别将集合中的每一个元素进行映射到{1,m}的范围。对于任何一个元素,然后根据映射的数字到位数组确定位置,然后在该位置被置为1

下图中集合S只有两个元素x和y,分别被3个hash函数进行映射,映射到的位置分别为(0,2,6)和(4,7,10),对应的位会被置为1:

现在假如要判断另一个元素是否是在此集合中,只需要被这3个hash函数进行映射,查看对应的位置是否有0存在,如果有的话,表示此元素肯定不存在于这个集合,否则有可能存在。下图所示就表示z肯定不在集合{x,y}中:

HBase中每个HFile都有对应的位数组,KeyValue在写入HFile时会先经过几个hash函数的映射,映射后将对应的数组位改为1,get请求进来之后再进行hash映射,如果在对应数组位上存在0,说明该get请求查询的数据不在该HFile中。

HFile中的位数组就是Bloom Block存储的值,可以想象,一个HFile文件越大,里面存储的KeyValue就越多,位数组也就会越大。一旦太大就不适合直接加载到内存,因此HFile V2在设计上将位数组进行了拆分,拆分成多个独立的数组(根据key进行拆分,一部分连续的key使用一个位数组),这样一个HFile就会包含多个位数组,根据key进行查询,首先会定位到具体的某一个位数组,只需要加载此位数组到内存即可

在结构上,每一个位数组对应HFile一个Bloom Block,为了方便根据key定位具体需要加载哪个位数组,HFile V2又设计了对应的索引

Bloom Index Block,对应的内存和逻辑结构如下:

2.3.1 TotalByteSize: 表示位数组大小

2.3.2 NumChunks: 表示Bloom Block个数

2.3.3 HashCount: 表示hash函数个数、

2.3.4 HashType: 表示hash函数类型

2.3.5 TotalKeyCount: 表示Bloom Filter已经包含的key数据

2.3.6 TotalMaxKeys: 表示Bloom Filter 当前包含最多的key的数目

Bloom Index Entry:

BlockOffset: 表示对应的Bloom Block在HFile中偏移量

FirstKey: 表示BloomBlock中第一个Key

根据上文所说,一次get请求进来,首先会根据key在所有的索引条目中进行二分查找,查找到对应的Bloom Index Entry,就可以定位到该key对应的位数组,加载到内存进行过滤判断。

HBase之HFile详解相关推荐

  1. 大数据技术Hbase 和 Hive 详解

    目录 两者的特点 各自的限制 应用场景 大数据技术Hbase 和 Hive 详解, 今天给大家介绍一下关于零基础学习大数据视频教程之HBASE 和 HIVE 是多么重要的技术,那么两者有什么区别呢 ? ...

  2. python提取hbase数据_详解python操作hbase数据的方法介绍

    配置 thrift python使用的包 thrift 个人使用的python 编译器是pycharm community edition. 在工程中设置中,找到project interpreter ...

  3. HBase基本数据操作详解

    引言 之前详细写了一篇HBase过滤器的文章,今天把基础的表和数据相关操作补上. 本文档 参考最新 (截止2014年7月16日)的 官方 Ref Guide. Developer API编写 . 所有 ...

  4. 【甘道夫】HBase基本数据操作详解【完整版,绝对精品】

    引言 之前详细写了一篇HBase过滤器的文章,今天把基础的表和数据相关操作补上. 本文档参考最新(截止2014年7月16日)的官方Ref Guide.Developer API编写. 所有代码均基于& ...

  5. HBase的BulkLoad详解

    HBase的BulkLoad主要分为HFile生成和HFile导入两个阶段. HFile生成阶段 HFile导入阶段

  6. HBase NoSQL数据库详解

    一.HBase简介 HBase是Hadoop的生态系统,是建立在Hadoop文件系统(HDFS)之上的分布式.面向列的数据库,通过利用Hadoop的文件系统提供容错能力.如果你需要进行实时读写或者随机 ...

  7. 如何像海豚一样在数据海洋里遨游?|Hbase数据处理流程详解

    写在前面:我是「且听风吟」,目前是某上市游戏公司的大数据开发工程师,热爱大数据开源技术,喜欢分享自己的所学所悟,现阶段正在从头梳理大数据体系的知识,以后将会把时间重点放在Spark和Flink上面. ...

  8. HBase集成Hive详解

    目录 一.HBase与Hive的对比 二.HBase整合Hive配置 三.需求一:将Hive表当中分析的结果保存到HBase表 四.需求二:创建Hive外部表,映射HBase当中已有的表模型 Hive ...

  9. Hbase Java API详解

    2019独角兽企业重金招聘Python工程师标准>>> HBase是Hadoop的数据库,能够对大数据提供随机.实时读写访问.他是开源的,分布式的,多版本的,面向列的,存储模型. 在 ...

最新文章

  1. CVPR2020论文解析:实例分割算法
  2. C0301 代码块{}的使用,重定向, 从文件中读取行
  3. uva 10110——Light, more light
  4. C++ mutable 的用法
  5. Android开发,并不见得是一个走得长远的路子
  6. 20211213软件测试基础达内视频笔记
  7. MATLAB--数字图像处理 频域图像分析
  8. SketchUp + Ruby 二次开发初识
  9. linux ahci 驱动下载,linux ahci驱动分析 SylixOS中AHCI驱动框架分析
  10. Step1我学习ros2的一些经历(从ubuntu安装到ros2中的位姿转换)
  11. 云服务器系统种类,云服务器系统种类
  12. 输入一个字符,将大写字母换小写,小写变大写
  13. 【ffmpeg】音频重采样
  14. 一如职场深似海,怎样避开人际关系的冰山?
  15. 棋牌微信小游戏之多人在线斗地主源码分享
  16. 什么是IC卡、M1卡,有啥区别
  17. 【学习笔记17】buu [安洵杯 2019]easy_web
  18. 昆兰士科技大学计算机排名,2019QS学科排名重磅发布!昆士兰科技大学多个学科跻身全球前100...
  19. 韩国计算机网络电子书,韩老师 计算机网络安全精讲视频课程 共34节课
  20. 物联网系统串口通信程序设计

热门文章

  1. python常量列表_Python中实现常量(Const)功能
  2. java解析ajax的数据_java ajax 请求后获取 json 数据 以及 使用 解析 ,解惑
  3. manual setting mysql_mysql 5.5配置
  4. 绕安全狗mysql_技术讨论 | Fuzz绕过安全狗4.0实现SQL注入
  5. 日志文件设计学习(一)
  6. php图像无法显示,php – 无法显示图像,因为它包含错误[图像生成器]
  7. 中专计算机网络技术试卷,2018年中职对口升学计算机网络技术模拟试题
  8. Oracle varchar类型数值排序问题
  9. Python保存dict字典类型数据到Mysql,并自动创建表与列
  10. 解决ray报错AttributeError: module ‘aioredis‘ has no attribute ‘create_redis_pool‘