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 查询方式#
-
全表查询:
scan tableName
-
基于 rowkey 的单行查询:
get tableName,'1'
-
基于 rowkey 的范围扫描:
scan tableName, {STARTROW=>'1',STOPROW=>'2'}
setCache () 和 setBatch () 方法
Cache 设置了服务器一次返回的行数,而 Batch 设置了服务器一次返回的列数