Hbase2.x源码分析

0. 前言

目前在国内,使用大数据技术的公司,几乎都会使用HDFS这一技术,在这之上有很多的开源产品,例如Hive、Hbase等,今天我们就来研究一下HBase。

什么是HBase? HBASE是一个高可靠性、高性能、面向列、可伸缩分布式存储系统,利用HBASE技术可在廉价PC Server上搭建起大规模结构化存储集群。HBASE的目标是存储并处理大型的数据,更具体来说是仅需使用普通的硬件配置,就能够处理由成千上万的行和列所组成的大型数据。HBASE是Google Bigtable的开源实现,但是也有很多不同之处。比如:Google Bigtable利用GFS作为其文件存储系统,HBASE利用Hadoop HDFS作为其文件存储系统;Google运行MAPREDUCE来处理Bigtable中的海量数据,HBASE同样利用Hadoop MapReduce来处理HBASE中的海量数据;Google Bigtable利用Chubby作为协同服务,HBASE利用Zookeeper作为对应。

那么HBase和传统数据库有什么区别呢?

Hbase2.x源码分析_第1张图片

上图来自 https://developer.ibm.com/zh/articles/ba-cn-bigdata-hbase/

我们可以看得出来,HBase是一个类似 key-value的数据库,也就是说 HBase 适用于结构化的存储。并且 HBase 是一种列式的分布式数据库,是由当年的 Google 公布的 BigTable 的论文而生。不过这里也要注意 HBase 底层依旧依赖 HDFS 来作为其物理存储,这点类似于 Hive。

接下来我们看一下Hbase的架构图

Hbase2.x源码分析_第2张图片

Client:

1、HBase有两张特殊表:
.META.:记录了用户所有表拆分出来的的Region映射信息,.META.可以有多个Regoin
-ROOT-:记录了.META.表的Region信息,-ROOT-只有一个Region,无论如何不会分裂
2、Client访问用户数据前需要首先访问ZooKeeper,找到-ROOT-表的Region所在的服务器位置,然后访
问-ROOT-表,接着访问.META.表,最后才能找到用户数据的服务器位置去访问,中间需要多次网络操作,不
过client端会做cache缓存。

ZooKeeper:

1、ZooKeeper为HBase提供Failover机制,选举Master,避免单点Master单点故障问题
2、存储所有Region的寻址入口:-ROOT-表在哪台服务器上。-ROOT-这张表的位置信息
3、实时监控RegionServer的状态,将RegionServer的上线和下线信息实时通知给Master
4、存储HBase的Schema,包括有哪些Table,每个Table有哪些Column Family

HMaster:

1、为RegionServer分配Region

2、负责RegionServer的负载均衡

3、发现失效的RegionServer并重新分配其上的Region

4、master是管理者,一个hbase系统会有很多表,每个表又有很多region,那么这些region到底交给那些region来管理就是由 master来决定

5、HDFS上的垃圾文件(HBase)回收 ,region会compact也会split,必然会有失效的数据

6、处理Schema更新请求(表的创建,删除,修改,列簇的增加等等)这些关于schema的数据都是存储在Zookeeper,但是是master是负责更新的如果涉及到表的创建,修改,删除等操作,master宕机了就没法做,但是数据的插入和查询还是可以继续做

RegionServer:

1、RegionServer维护Master分配给它的Region,处理对这些Region的IO请求

2、负责和底层的文件系统HDFS的交互,存储数据到HDFS,每个regionserver内部都有一个客户端(datnaode的代理)。 负责把数据写入到HDFS

3、负责Store中的HFile的合并Compact工作 + split工作

4、RegionServer负责Split在运行过程中变得过大的Region,负责Compact操作,SplitPolicy 分割策略:有三个默认的策略

接下来我们就来看看,源码是怎么实现的

1. Hbase的寻址机制

这个时候我们,首先需要准备一个我们的源码,这个我已经准备好了,版本是2.3.1,那么我们想要看寻址,那么寻址发生在那个地方我们应该知道,写数据的时候和读数据的时候,当然还有其他的,但是我们主要就看这两个 一个是Put一个是Get,那么我们就随意在源码中编写一个测试案例类,然后点进去看一看。

Hbase2.x源码分析_第3张图片

我们根据API就可以看出来有几个步骤

1、获取配置文件

2、获取连接

3、获取表

4、写入数据

那么我们先看看获取配置文件

1.1 获取配置文件

当我们点进去的时候我们发现了这段代码

Hbase2.x源码分析_第4张图片

这段代码的含义是什么呢?就是去加载我们的配置文件,然后校验我们的配置文件的版本,没什么好看的,我们现在退回去。

1.2 创建连接

Hbase2.x源码分析_第5张图片

我们发现,他这里获取了一个类名,我们接着往下看

Hbase2.x源码分析_第6张图片

这里们就发现了端倪,他是通过反射创建对象ConnectionImplementation,那么返回的类就应该是ConnectionImplementation

1.3 获取表

我们点进去发现这个,他返回的就是HTable这里我们记住就好了。

Hbase2.x源码分析_第7张图片

我们这个时候发现了,他把ConnectionImplementation 作为了一个参数来进行

1.4 最重要的put方法

Hbase2.x源码分析_第8张图片

我们发现 这里做了这几件事情

1、校验put不能超过10M

2、获取一个callable对象,并且实现了一个匿名对象

3、最后调用了一个callWithRetries 一个可重试的调用,因为在网络编程中,网络中断和阻塞是很正常的现象

接下来,我们看看callWithRetries这个方法

Hbase2.x源码分析_第9张图片

然后我们发现prepare这个方法,我们见名知意,他的意思我认为就是前置操作的,然后 调用了一个拦截器,这个拦截器默认是空的实现,我们不用管他,那么我们接下来看看prepare的方法。

Hbase2.x源码分析_第10张图片

这个方法,前面做了一个判断

1、不能是重试的状态

2、tablename 不能是空的

3、table表不能是meta表

4、table不能是disable的状态

我们再来看看getRegionLocation方法

Hbase2.x源码分析_第11张图片

这里我们发现他有两个分支,一个就是 走 if 一个就是走else,那么我们想一下,这个时候我们并不是获取meta表啊,因为我们传进来的表名啊,

那么我们看看 else的实现

Hbase2.x源码分析_第12张图片

我们发现上来就去缓存中去拿元数据,但是我们缓冲区并没有数据,这个时候,他会进行重试,这个时候 relocateMeta 就为true了

image-20200920215524556

我们发现他又来到了这个位置

Hbase2.x源码分析_第13张图片

先从缓存中找,没有的话就往下走

Hbase2.x源码分析_第14张图片

我们发现这里就直接开始扫描了,但是我们并没有拿到meta表呢,那么我们点进去看看

Hbase2.x源码分析_第15张图片

Hbase2.x源码分析_第16张图片

这里就把我们的缓存数据拿到了

Hbase2.x源码分析_第17张图片

这个时候就把我们的表元数据进行缓存了,然后把locations返回了

1.5 总结

我们现在就发现了他的流程是这样的

1、首先获取meta表

2、根据meta表获取对应的偏移量所在的region是哪个region

3、然后根据region拿到servername这样就可以去访问,写入数据了。

Hbase2.x源码分析_第18张图片

未完待续。

你可能感兴趣的:(hbase)