Write Ahead Log (WAL)
用于记录所有数据的更改。正常写入流程下,不需要wal,因为数据会通过memstore flush成storefile,但如果在memstore flush时RegionServer崩溃或不可用,WAL此时会确保可以回放整个数据的更改。如果写入WAL失败,则整个数据操作也会失败。
- 正常每个RegionServer只有一个WAL,但存储hbase:meta表的RegionServer不同,该表会有专用的WAL。
- WAL的目录为/hbase/WALs/ ,每个region有子目录
WAL Provider
通过hbase.wal.provider设置
- WAL的实现:
- filesystem:1.x版本的默认实现,使用dfsclient通过pipeline模式写入副本。日志中为FSHLog或FSHLogProvider
- asyncfs:2.x版本的默认实现,AsyncFSWAL。使用dfsclient并发写入到每个副本。
- multiwal:asyncfs或filesystem的多个实例实现
WAL Splitting
按region对wal edits分组被称为log splitting。主要目的是为了regionserver崩溃时恢复数据。
-
因每个RegionServer的所有region共享一个wal file,所以对wal的每次修改都会包含所属region信息。当region打开时,wal中属于该region的edits将会被重放。所以wal file必须按照region分组,以便在重放时恢复特定region的数据。
-
集群启动或regionserver关闭时,由hmaster完成log spliting。为了保证一致性,受影响的region直到恢复之前不可用。
splitting 步骤
- 将regionserver的wal目录重命名为/hbase/WALs/< host >,< port>,< startcode>-splitting
- 对每个日志文件进行spliting,将每个region对应的记录写到/hbase/<table_name>/<region_id>/recovered.edits/.temp文件中,该文件包含wal log中所有的关于该region的记录。log spliting完成之后,.temp文件将会被重命名为第一个写入该文件的sequence ID。
- log spliting完成之后,相关region就可以分配给regionserver。当region处于opend时,会检查recovered.edits目录下是否有文件,如果有则会重放,读取文件并将数据保存到memstore中。当所有的文件重放完成,memstore将数据刷写到磁盘之后,这些文件将会被删除。
Flush
HBase基于LSM-Tree模型,所有数据的更新都经由memstore达成一定大小后刷写到磁盘上。
触发条件
Flush触发的最小的单位是region
- 当某个MemStore的大小达到hbase.hregion.memstore.flush.size,所有属于该region下的MemStore都将被刷写到磁盘。
- 当某个regionserver所有的memstore的大小达到hbase.regionserver.global.memstore.size,该regionserver上所有的memstore将按照使用大小降序来flush,直到所有memstore的大小小于hbase.regionserver.global.memstore.size.lower.limit
- 当regionseverv上的wal log数量超过hbase.regionserver.max.logs,该regionserver上的所有memstore都将flush来减少wal log的数量。会按照时间先后顺序来flush,直到数量小于该参数值。
- 当region中所有的memstore大于hbase.hregion.memstore.block.multiplier*hbase.hregion.memstore.flush.size的值时,此时会阻塞写入并执行flush。
- 手动触发Flush
相关参数
hbase.regionserver.global.memstore.size=heap*0.4
-旧版参数hbase.regionserver.global.memstore.upperLimit
regionserver上所有memstore的最大值,超过该值此regionserver上所有的memstore都将被阻塞更新并强制刷写
hbase.regionserver.global.memstore.size.lower.limit=0.95*heap*0.4
-旧版参数hbase.regionserver.global.memstore.lowerLimit
regionserver上所有memstore大小的水位线,超过该值将会强制此regionserver上所有的memstore强制刷写
hbase.hregion.memstore.flush.size=128M
单个memstore最大大小
hbase.regionserver.max.logs=32
当regionserver的hlog数量达到该值
hbase.hregion.memstore.block.multiplier=4
防止较大的写入导致oom
hbase.hstore.flusher.count=2
flush线程的数量,数量越多,并行越高,会导致hdfs的负载加重、compaction发生的频率增加
hbase.hstore.blockingStoreFiles=16
任何一个store下的StoreFiles超过该值,则memstore的刷新将会被阻塞直到compaction完成或者达到阻塞等待的时间(hbase.hstore.blockingWaitTime)
hbase.hstore.blockingWaitTime=90000