Hbase WAL 详解
简介
HBase 为保证写入高速,先往内存 memstore 写数据,当 memstore 到一定大小时,再批量 flush 到 storefile 中进行持久化,此时如果 rs 宕机 memstore 中没有 flush 的数据将会丢失,为此在写入 memstore 前,先将数据 append 到一个顺序文件中,即WAL(Write Ahead Log)。
WAL 的主要作用就是用来进行 recovery,类似于 Mysql 中的 redo log。为保证 wal 的写不影响写入性能,wal 使用顺序 append 方式。
组织
wal 在 hbase 以 hlog 文件存储于 hdfs 中。
每个 RegionServer 对应一个 Hlog,所有对于该 RegionServer 的写入都记录到 Hlog 中,一旦 region server 宕机,就可以从 log 中进行恢复。
为了保证恢复的效率,Hbase 会限制最大保存的 Hlog 数量,如果达到 Hlog 的最大个数(hase.regionserver.max.logs 参数控制)的时候,就会触发强制刷盘操作。
对于已经刷盘的数据,其对应的 Hlog 会有一个过期的概念,Hlog 过期后,会被监控线程移动到.oldlogs,然后会被自动删除掉。
HLog
HLog 文件就是一个普通的 Hadoop Sequence File;
Sequence File 的 HLogKey 对象,其中记录了写入数据的归属信息,
table
region
sequence number:sequence number 的起始值为 0,或者是最近一次存入文件系统中的 sequence number。
timestamp:timestamp 是写入时间
Sequence File 的 value 是 HBase 的 KeyValue 对象,即对应 HFile 中的 KeyValue。
等级
WAL 的持久化等级分为如下四个等级:
- SKIP_WAL:只写缓存,不写 HLog 日志。这种方式因为只写内存(memstore),因此可以提升写入性能,但是数据有丢失的风险。
- ASYNC_WAL:异步将数据写入 HLog 日志中。
- SYNC_WAL:同步将数据写入日志文件中,有可能只是被写入文件系统中,并没有真正落盘。
- FSYNC_WAL:同步将数据写入日志文件并强制落盘。最严格的日志写入等级,可以保证数据不会丢失,但是性能相对比较差。
- USER_DEFAULT:默认如果用户没有指定持久化等级,HBase 使用 SYNC_WAL 等级持久化数据。
生命周期
生成:写入 memstore 前(同时写入),写入 WAL 到 WALs/对应的 rs 目录中;
滚动:当一个 hlog 文件写入时间达到
hbase.regionserver.logroll.period
(默认:1h)时,滚动生成新的 hlog 文件;阻塞:每个 rs 中的 hlog 文件个数由
hbase.regionserver.maxlogs
(默认: )限制,达到改值后,将阻止对改 rs 的写入;过期:当 memstore 数据 flush 到 storefile 中后,会更新
oldestUnflushedSequenceId
, 如果 Hlog 的最大的 sequenceid 大于等于该值,则表明该 WAL 中的所有数据已落盘,则将该 hlog 文件移动到 oldWALs 目录中;复制:如果开启了 replication,则复制线程将 oldWALs 中的 hlog 复制到 slave 节点中,复制完成后,将其删除;
重放:当 rs 故障时,该 rs 上的 wal 将被重放,已恢复 wal 中的数据;
WAL splitting
当 Master 重启或者 RS down 掉后,会触发 WAL splitting 过程;
wal split 和 replay 比较消耗资源。从 0.92 版开始,hbase 默认启用 distributed log 进行 wal 的并行 split,以提高 wal split 的性能。可由
hbase.master.distributed.log.splitting
选项进行设置;
配置
Hbase-site.xml 配置项:
hbase.wal.hsync: hbase wal 文件同步方式 , 默认:false,先写入 fs 缓存,后 sync 到磁盘。
hbase.wal.provider: