HBase系列-HBase读写流程

HBase 系列 - HBase 读写流程

内容整理自:

HBase － 数据写入流程解析

HBase 原理－数据读取流程解析

写数据流程

客户端写流程

用户提交 put 请求后，HBase 客户端会根据设置autoflush=true/false(默认为true)判断是否直接提交给服务器进行处理，如果为false则会将请求添加到本地buffer, 超过一定阈值（默认为 2M，可以通过配置文件配置）之后才会提交。这样可以提高写入性能，但会存在因为客户端崩溃导致请求丢失的情况

在提交之前，HBase 会在元数据表.meta.中根据 rowkey 找到它们归属的 region server，这个定位的过程是通过HConnection的locateRegion方法获得的。如果是批量请求的话还会把这些 rowkey 按照HRegionLocation分组，每个分组可以对应一次 RPC 请求

HBase 会为每个 HRegionLocation 构造一个远程 RPC 请求MultiServerCallable<Row>，然后通过rpcCallerFactory.<MultiResponse> newCaller()执行调用，忽略掉失败重新提交和错误处理，客户端的提交操作到此结束

服务器端写流程

服务器端 Region Server 接收到客户端的写入请求后，首先会反序列化为Put对象, 然后检查region是否是只读、memstore大小是否超过blockingMemstoreSize等检查操作，然后执行以下核心操作:

获取行锁、Region更新共享锁： HBase 中使用行锁保证对同一行数据的更新都是互斥操作，用以保证更新的原子性，要么更新成功，要么失败。

开始写事务：获取 write number，用于实现 MVCC，实现数据的非锁定读，在保证读写一致性的前提下提高读取性能。

写缓存memstore：HBase 中每列族都会对应一个 store，用来存储该列数据。每个 store 都会有个写缓存 memstore，用于缓存写入数据。HBase 并不会直接将数据落盘，而是先写入缓存，等缓存满足一定大小之后再一起落盘。

Append HLog：HBase使用 WAL 机制保证数据可靠性，即首先写日志再写缓存，即使发生宕机，也可以通过恢复 HLog 还原出原始数据。该步骤就是将数据构造为 WALEdit 对象，然后顺序写入 HLog 中，此时不需要执行 sync 操作。0.98 版本采用了新的写线程模式实现 HLog 日志的写入，可以使得整个数据更新性能得到极大提升。

释放行锁以及共享锁

Sync HLog：HLog 真正 sync 到 HDFS，在释放行锁之后执行 sync 操作是为了尽量减少持锁时间，提升写性能。如果 Sync 失败，执行回滚操作将 memstore 中已经写入的数据移除。

结束写事务：此时该线程的更新操作才会对其他读请求可见，更新才实际生效。

flush memstore：当写缓存满 64M 之后，会启动 flush 线程将数据刷新到硬盘。当 HBase 中的 memstore 数据 flush 到磁盘的时候，就会形成一个 storefile，当 storefile 的数量达到一定程度的时候，就需要将 storefile 文件进行compaction操作，Compact 作用：合并文件、清除过期，多余版本数据、提高读写效率

WAL 持久化等级

SKIP_WAL: 只写缓存，不写 HLog，因为只用内存，性能很好，但容易丢失数据，不推荐

ASYNC_WAL: 异步将数据写入 HLog 日志中

SYNC_WAL: 同步将数据写入日志文件中，需要注意的是数据只是被写入文件系统中，并没有真正落盘

FSYNC_WAL: 同步将数据写入日志文件并强制落盘。最严格的日志写入等级，可以保证数据不会丢失，但是性能相对比较差

USER_DEFALUT: 默认如果用户没有指定持久化等级，HBase 使用 SYNC_WAL 等级持久化数据

用户可以通过客户端设置 WAL 持久化等级，代码：put.setDurability(Durability. SYNC_WAL );

读流程

客户端首次读写 HBase 上数据的流程：

客户端从 Zookeeper 获取 META 表所在的 Region Server；

客户端访问 META 表所在的 Region Server，从 META 表中查询到访问行键所在的 Region Server，之后客户端将缓存这些信息以及 META 表的位置；

客户端从行键所在的 Region Server 上获取数据。

如果再次读取，客户端将从缓存中获取行键所在的 Region Server。这样客户端就不需要再次查询 META 表，除非 Region 移动导致缓存失效，这样的话，则将会重新查询并更新缓存。

注：META 表是 HBase 中一张特殊的表，它保存了所有 Region 的位置信息，META 表自己的位置信息则存储在 ZooKeeper 上。

更为详细读取数据流程参考：

HBase 原理－数据读取流程解析

HBase 原理－迟到的‘数据读取流程部分细节

HBase 查询方式

全表查询：scan tableName

基于 rowkey 的单行查询：get tableName，'1'

基于 rowkey 的范围扫描：scan tableName， {STARTROW=>'1'，STOPROW=>'2'}

setCache () 和 setBatch () 方法
Cache 设置了服务器一次返回的行数，而 Batch 设置了服务器一次返回的列数