Hlog 简介
Hlog是Hbase实现WAL(Write ahead log )方式产生的日志信息 , 内部是一个简单的顺序日志。每个RegionServer对应1个Hlog(备注:1.X版本的可以开启MultiWAL功能,允许对应多个Hlog),所有对于该RegionServer的写入都会被记录到Hlog中。Hlog实现的功能就是我们前面讲到的保证数据安全。当RegionServer出现问题的时候,能跟进Hlog来做数据恢复。此外为了保证恢复的效率,Hbase会限制最大保存的Hlog的数量,如果达到Hlog的最大个数的时候,就会触发强制刷盘操作。对于已经刷盘的数据,其对应的Hlog会有一个过期的概念,Hlog过期后,会被监控线程启动到 .oldlogs,然后会被自动删除掉。
Hlog结构
- 多个Region 共享一个Hlog文件。
- 单个Region在Hlog中是按照时间排序顺序存储的。
- 但是多个Region可能并不是完全按照时间顺序存储的.
每个Hlog最小单元由HlogKey和WALEdit 两部分组成 。
HlogKey由sequenceid (Region级别的自增序号)、timestamp(时间戳)、cluster ids(集群id) 、regionname(当前地区名) 以及 tablename(表名) 等组成,
WALEdit是由一系列的keyValue组成,对一行上所有列(即所有KeyValue)的更新操作,都包含在同一个WALEdit对象中,这主要是为了实现写入一行过个列时的原子性。
Hlog 的内部内容
一、 HlogKey
1. sequenceid : 一个store级别的自增序列号 , region的数据恢复和Hlog过期清楚都要依赖于这个信息
2. timestamp
3. cluster ids
4. regionname
5. tablename
二、 WAALEids
1. n 个 KeyValue
三、
sequenceid 的相关逻辑 : MemStore 达到一定的条件会触发刷盘的操作,刷盘的时候会获取刷盘到最新的一个 sequenceid 的下一个 sequenceid , 并将新的 sequenceid 赋值给 oldestUnflushedSequenceId , 并刷到 Hfile中。
Hlog文件对应所有Region 的 store 中最大的 sequenceid 如果已经刷盘,就认为Hlog 文件已经过期 , 就会移动到 .oldlogs , 等待被移除。
当RegionServer 出现故障的时候 ,需要对 Hlog 进行回收来恢复数据。回放的时候会读取Hfile 的 oldestUnflushedSequenceId 中的 sequenceid 和 Hlog 中的 sequenceid 进行比较 ,小于 的就直接忽略 , 但大于或者等于的就进行重做。回放完成后,就完成了数据的恢复工作。
Hlog 的生命周期
产生
所有涉及到数据的变更都会先写到Hlog ,除非是关闭了Hlog。
滚动
Hlog 的大小通过参数 hbase.regionserver.logroll.period 控制 , 默认是1小时,时间达到hbase.regionserver.logroll.period 设置的时间,Hbase会创建一个新的Hlog文件。这就实现了 Hlog 滚动的目的 。Hbase 通过hbase.regionserver.maxlog参数控制Hlog的个数。滚动的目的,为了控制单个Hlog文件过大的情况,方便后续的过期和删除。
过期
Hlog 的过期判断依赖于 sequenceid。Hbase 会将 Hlog 的 sequenceid 和 Hfile 最大的 sequenceid 进行比较 , 如果该 Hlog 文件中的 sequenceid 比刷新的最新的位置的 sequenceid 都要小,那么这个Hlog 就过期了 , 过期以后,对应的Hlog 会被移动到 .oldlogs目录。
删除
如果Hbase 开启了 replication(复制) , 当 replication执行完一个Hlog 的时候,会删除 Zookeeper 上对应Hlog 节点。 在 Hlog 被移动到 .oldlogs目录下的所有Hlog,确认对应的Zookeeper 的 Hlog 节点是否被删除,如果Zookeeper 上不存在对应的 Hlog 节点 ,那么就直接删除对应的Hlog.
hbase.master.logcleaner.ttl (默认10分钟)这个参数设置 Hlog 在 .oldlogs 目录保留的最长时间。
RegionServer的故障恢复
我们知道,RegionServer 的相关信息保存在 ZK 中,在 RegionServer 启动的时候,会在Zookeeper 中创建对应的临时节点。 RegionServer 通过 Socket 和 Zookeeper 建立 session 会话,RegionServer 会周期性的向Zookeeper 发送Ping 消息包 , 以此说明自己还处于存活的状态。 而Zookeeper 收到 ping 包后,则更新对应 session的超时时间。
当Zookeeper 超过session 超时时间还没有收到 RegionServer 的 ping 包,则Zookeeper 会认为该 RegionServer 出现故障 , ZK会将该RegionServer 对应的临时节点删除,并通知Master, Master 收到 RegionServer 挂掉的信息后就会启动数据恢复的流程。