数据结构论坛

首页 » 分类 » 定义 » HBaseWAL写入模型解析
TUhjnbcbe - 2025/5/3 16:39:00
北京中科白癜风医院圆梦征程 http://www.yunweituan.com/m/

01写在前面

wal在hbase中是为了持久化memstore中未flush到hfile的数据,以防rs宕机或异常退出导致数据的丢失。

wal实现的一头是多个handler线程处理put请求,另一头是针对hdfs写这种费时间的操作。并且需要实现两件事情:一是在写hdfs时不能出现混乱,二是写完hdfs之后需要有个机制通知到在等待hdfs写返回的处理写请求的线程。

本文将从宏观流程和微观流程两个维度,从源码抽象出来更易于大家理解的相关原理,帮助大家理解HBase中WAL相关原理。

02WAL宏观流程解析

在宏观流程里面,我们主要理清楚WAL的数据结构以及这些数据是如何准备就绪并发送到FSHLog的。

wal写入请求宏观处理时序图

上图为HBase在server端以行原子性处理写入请求前的时序图,整体上是每次将写入请求的数据首先准备好WALEdit和WALKey,然后组装成WALEntry发送到FSHLog,其中第9处是真正开始写入WAL日志的入口位置,此处已经将WALKey和WALEdit都准备好,这里有几个关键的地方需要注意,我们分别阐述。

一、文件结构

wal文件结构

每个RegionServer拥有一个或者多个HLog(默认只有一个,1.1版本后可以开启MultiWAL功能,允许多个HLog),每个HLog是多个Region共享。HLog中包含有n多个HLogKey和WALEdit组成的日志数据,对应格式解析如下:

HLogKey比较简单,主要包括region名称、HBase表名称、MVCC信息、是否主从复制等信息。

WALEdit相对复杂些,包括以下相关信息:

WALEdit在HBase的事务日志(WAL)中使用,它用来记录单个事务相对应的编辑集合,即KeyValue对象集合。这个类实现了Writable接口,用于序列化/反序列化一组KeyValue对象集合。每个WALEdit对应包装了一个transaction中所有的操作,这个WALEdit要么包装成功,要么包装失败(一旦有一个操作包装失败,那么整个包装就会失败,对应的WALEdit就不会写进log,然后transaction失败),从而保证行级别更新的原子性。WALEdit有两个版本,新、旧版本在记录日志形式上有较大的区别,主要体现如下:旧的WALEdit是每一个修改写一条日志记录:假如有一个transaction,对1个rowR的column:c1,c2,c3进行了修改操作,那么WALEdit会将这三个操作包成如下模式:logseq1-for-edit1:KeyValue-for-edit-c1logseq2-for-edit2:KeyValue-for-edit-c2logseq3-for-edit3:KeyValue-for-edit-c3这种方式无法保证事务在行级别的原子性。因为对于同一个事务中的多个修改记录,在写了部分日志后我们机器故障了,那么恢复的时候就只能恢复这次事务中的部分修改内容,这不是我们希望看到的行级别原子性的表现。在新的WALEdit中,同一个事务的所有修改内容会被处理成一条记录写入log,比如对于上面说的修改:-1,3,Keyvalue-for-edit-c1,KeyValue-for-edit-c2,KeyValue-for-edit-c3-1可以理解为一个兼容新旧版本的标志位,3代表本次修改涉及的kv实例总数,后面紧跟着是三个修改的具体kv内容。二、文件存储

HBase中所有的数据都存储在HDFS的指定目录下,WAL也不例外,可以通过hadoop命令查看hbase-root目录下与WAL有关的子目录。

wal文件在hdfs上的默认存储目录

其中/hbase/WALs存放还未过期的日志;/hbase/oldWALs存放已经过期的日志。可以进一步查看/hbase/WALs目录下的文件:

wal子目录

可以看到/hbase/WALs下会有多个子目录,每个子目录代表一个RegionServer,比如hostname,,7,其中hostname表示对应RegionServer域名,表示端口号,7则为目录生成时间戳。

每个子目录下存储该RegionServer中对应的所有HLog文件,比如:

-rw-r--r--2hbasehbase-11-:44/hbase/WALs/gh-data-hbase89.gh.sankuai.

1
查看完整版本: HBaseWAL写入模型解析