hbase-2.4.0源码阅读


  Hbase的主要操作有put,get和scan,这里主要针对这三种操作进行源码的解读.整体上看hbase是简单的,因为不涉及复杂的查询逻辑,作为数据库只能算是极简级别的.

1 调试类及代码更改

  Hbase的测试代码比较清晰,主要的测试工具类是以TestingUtility结尾的类,在这些工具类中模拟了迷你hbase集群等各种测试用环境,其使用了真实的源码,因此适合直接调试.
  为简单起见,此处主要从server端来调试代码,从客户端也可以,因为hbase的rpc和hadoop的一样,都是使用protocol来定义服务端的方法,因此如果使用client端进行调试,在server的相应方法上打上断点即可,这里不再详述.
  这里使用hbase-server子工程下的测试目录中的regionserver部分,测试类名为TestParallelPut,此类一共有两个方法,一个是测试单个put,一个是测试多个put,这里把testParallelPuts()方法上的@Test注解去掉,只使用testPut()方法,也就是只使用单个put方法,然后添加get和scan方法,如下所示
在这里插入图片描述

2 put方法

  Put方法调用的方法树为:
在这里插入图片描述
  其核心方法为doBatchMutate,其调用的方法树为
在这里插入图片描述
  调用的核心方法为doMiniBatchMutate,进入该方法,可以看到作者添加了许多注释,一共分为6大步:
  第一步:获取各种锁
在这里插入图片描述
  第二步:更新最新的时间戳
在这里插入图片描述
  第三和第四步:写wal
在这里插入图片描述
  第五步:写memstore
在这里插入图片描述
  第六步:收尾
在这里插入图片描述
  其中重要的是wal的写入和memstore的写入,wal的写入比较简单,这里不再分析,主要是看一看memstore的写入.

2.1 写入memstore的方法writeMiniBatchOperationsToMemStore

  此方法主要是向memstore中写入要put的数据,此cell为单位写入,其调用的方法树为
在这里插入图片描述

  可以看到,最终是类似map的操作,使用了upsert方法,不难猜测出其与排序有关.其实该memstore的主要作用就是排序,然后顺序写入硬盘,所以调大该memstore并不能提升hbase的写入速度,因为hbase的写入速度是由顺序写硬盘决定的,是硬件决定了hbase的写入速度.

3 get方法

  Get方法最终调用的也是scan方法,其调用的方法树为
在这里插入图片描述
  可以看到其最终也是调用的scan方法.

4 scan方法

  在getScanner这一方法上打上断点,这很重要,因为所有执行scan的操作就是在这一行内完成的.
在这里插入图片描述
  通过执行断点,可以看到其实际的调用方法树为
在这里插入图片描述
  进入RegionScannerImpl的构造方法,其调用的方法树为
在这里插入图片描述

  可以看到核心方法是initializeScanners方法,其调用的方法树为
在这里插入图片描述
  这里有两个重要的方法,一是getScanner方法,另一个是initializeKVHeap.从这两个方法不难推测出,查找数据的逻辑首先是构造扫描器scanner,接着使用扫描器对存储结果的堆KVHeap进行初始化,也就是把堆填上根据扫描器扫描的数据.

4.1 getScanner方法

  其主要是获取storeFile的scanner,调用树为
在这里插入图片描述
  核心方法是getScanners,调用的方法树为
在这里插入图片描述
  可以看到,主要是获取两类scanner,一类是内存memstore的scanner,另一类是硬盘storeFile的scanner,内存的比较简单,硬盘的scanner也比较简单,重要的是在获取时把文件的读取流打开了,这也为之后初始化堆做准备.
  getScannersForStoreFiles的调用树为
在这里插入图片描述

  可以看到,其打开了HStoreFile的读文件流.

4.2 initializeKVHeap方法

  此方法就是利用扫描器scanner来获取数据并放在堆上,其调用的方法树为
在这里插入图片描述
  在初始化方法中的KeyValueHeap的构造方法调用的的方法树为
在这里插入图片描述
  重要方法是pollRealKV方法,其调用的方法树为
在这里插入图片描述
  可以看到,此方法是真正的执行扫描数据获取结果的逻辑,各种扫描器在进行扫描数据.

5 总结

  这里主要从server端直接使用已有的测试类来解读了主要的操作put和scan,也就是写入和读取的操作.不难发现hbase的设计比较繁琐,相比较传统的数据库,在读和写两方面处理的都很复杂.

5.1 写和读数据的逻辑流程

  写数据主要是先写wal,以防挂机或断电造成内存数据丢失,再写内存,目的是告诉顺序的向硬盘写数据.
  读数据的流程是先准备好内存和硬盘的扫描器scanner,这里主要是硬盘的扫描器,每一个hfile文件对应一个扫描器,再利用这些扫描器进行扫描,把扫描到的数据存入内置的堆中,共后续使用.

5.2 不高效的写数据流程

  不高效的方面有:
  1 首先要写入wal,而且是调用的hdfs的写流程,这个就很繁琐
  2 其次还要定时合并lsm树,这是因为要和已有的硬盘文件保持数据的一致更新
  3 最后还需要合并各个server上的hfile文件,这又是一个繁琐的流程

5.3 不高效的读数据流程

  反映在如下方面
  1 从内存中读取数据,在jvm中维护了一个至少258M的类map结构的数据,虽然在内存中,但此数据结构的主要功能并不是用来读数据的,相反是为了排好序写数据用的
  2 从各个节点的硬盘上读数据时在内部初始化一个堆,这个堆可以很大,当读取大量数据时会发生明显的full-gc过程,因为这个很大的内部堆不会在短时间内把数据都排出
  3 虽然使用了较多的索引加跳表,但是随机查询的效率依然很低
  可以预见,未来hbase会大概率的被淘汰掉,其使用场景正在逐步消失.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值