分享

HBase 底层的IO详解:WAL的原理

问题导读

1.WAL的持久化的级别有哪些?
2.WAL写入中的有哪几个主要类?
3.WAL的作用是什么?


WAL(Write-Ahead-Log)预写日志是Hbase的RegionServer在处理数据插入和删除的过程中用来记录操作内容的一种日志。在每次Put、Delete等一条记录时,首先将其数据写入到RegionServer对应的HLog文件中去。

客户端向RegionServer端提交数据的时候,会先写入WAL日志,只有当WAL日志写入成功的时候,客户端才会被告诉提交数据成功。如果写WAL失败会告知客户端提交失败,这其实就是数据落地的过程。

在一个RegionServer上的所有Region都共享一个HLog,一次数据的提交先写入WAL,写入成功后,再写入menstore之中。当menstore的值达到一定的时候,就会形成一个个StoreFile。

WAL的持久化的级别有如下几种:
SKIP_WAL:不写wal日志,这种可以较大提高写入的性能,但是会存在数据丢失的危险,只有在大批量写入的时候才使用(出错了可以重新运行),其他情况不建议使用。
ASYNC_WAL:异步写入
SYNC_WAL:同步写入wal日志文件,保证数据写入了DataNode节点。
FSYNC_WAL: 目前不支持了,表现是与SYNC_WAL是一致的
USE_DEFAULT: 如果没有指定持久化级别,则默认为USE_DEFAULT, 这个为使用Hbase全局默认级别(SYNC_WAL)wal写入

先看看wal写入中的几个主要的类
1. WALKey:wal日志的key,包括regionName:日志所属的region
tablename:日志所属的表,writeTime:日志写入时间,clusterIds:cluster的id,在数据复制的时候会用到。
2.WALEdit:在Hbase的事务日志中记录一系列的修改的一条事务日志。另外WALEdit实现了Writable接口,可用于序列化处理。
3. FSHLog: WAL的实现类,负责将数据写入文件系统

在每个wal的写入这里使用的是多生产者单消费者的模式,这里使用到了disruptor框架,将WALKey和WALEdit信息封装为FSWALEntry,然后通过RingBufferTruck放入RingBuffer中。接下来看hlog的写入流程,分为以下3步:

  • 日志写入缓存:由rpcHandler将日志信息写入缓存ringBuffer.
  • 缓存数据写入文件系统:每个FSHLog有一个线程负责将数据写入文件系统(HDFS)
  • 数据同步:如果操作的持久化级别为(SYNC_WAL或者USE_DEFAULT 则需进行数据同步处理



客户端往RegionServer端提交数据的时候,会写WAL日志,只有当WAL日志写成功以后,客户端才会被告诉提交数据成功,如果写WAL失败会告知客户端提交失败,换句话说这其实是一个数据落地的过程。在一个RegionServer上的所有的Region都共享一个HLog,一次数据的提交是先写WAL,再写memstore;
1.jpg
1 客户端对数据执行一个修改操作,如put(),delete(),incr()等。
2 每一个修改被封装到一个KeyValue对象实例,并通过RPC调用发送出来。
3 上述调用成批地发送给含有匹配region的HRegionServer。
4 数据先被写入到WAL,然后被放放到实际拥有记录的存储文件的MemStore中。
5 当MemStore达到一定的大小或经历一个特定时间之后,数据会异步地连续写入到文件系统中。


Write-Ahead-Log(WAL)保证数据的高可用性。
如果没有 WAL,当RegionServer宕掉的时候,MemStore 还没有写入到HFile,或者StoreFile还没有保存,数据就会丢失。
HBase中的HLog机制是WAL的一种实现,每个RegionServer中都会有一个HLog的实例,RegionServer会将更新操作(如 Put,Delete)先记录到 WAL(也就是HLog)中,然后将其写入到Store的MemStore,最终MemStore会将数据写入到持久化的HFile中(MemStore 到达配置的内存阀值)。这样就保证了HBase的高可用性。



HLog类
实现了WAL的类叫做HLog,当hregion被实例化时,HLog实例会被当做一个参数传到HRegion的构造器中,当一个Region接收到一个更新操作时,它可以直接把数据保存到一个共享的WAL实例中去
1.jpg


HLogKey类

1、当前的WAL使用的是hadoop的sequencefile格式,其key是HLogKey实例。HLogKey中记录了写入数据的归属信息,,除了table和region名字外,同时还包括sequence number和timestamp,timestamp是“写入时间“,sequence number的起始值为0,或者是最近一次存入文件系统中sequence number

2、HLog sequence File的value是HBase的KeyValue对象,即对应HFile中的KeyValue

WALEdit类

1、客户端发送的每个修改都会封装成WALEdit类,一个WALEdit类包含了多个更新操作,可以说一个WALEdit就是一个原子操作,包含若干个操作的集合

LogSyncer类

1、Table在创建的时候,有一个参数可以设置,是否每次写Log日志都需要往集群的其他机器同步一次,默认是每次都同步,同步的开销是比较大的,但不及时同步又可能因为机器宕而丢日志。同步的操作现在是通过pipeline的方式来实现的,pipeline是指datanode接收数据后,再传给另外一台datanode,是一种串行的方式,n-Way writes是指多datanode同时接收数据,最慢的一台结束就是整个结束,差别在于一个延迟大,一个开发高,hdfs现在正在开发中,以便可以选择是按pipeline还是n-way writes来实现写操作

2、Table如果设置每次不同步,则写操作会被RegionServer缓存,并启动一个LogSyncer线程来定时同步日志,定时时间默认是一秒也可由hbase.regionserver.optionallogflushinterval设置

LogRoller类

1、日志写入的大小是有限制的,LogRoller类会作为一个后台线程运行,在特定的时间间隔内滚动日志,通过hbase.regionserver.logroll.period属性控制,默认1小时


相关文章:HBase数据量过大变慢原因必知:Compaction的原理
https://www.aboutyun.com/forum.php?mod=viewthread&tid=28055

HBase 底层的IO详解:Flush的工作原理
https://www.aboutyun.com/forum.php?mod=viewthread&tid=28047


HBase 底层的IO详解:Region的split工作原理
https://www.aboutyun.com/forum.php?mod=viewthread&tid=28065


HBase 底层的IO详解:WAL的原理
https://www.aboutyun.com/forum.php?mod=viewthread&tid=28083

最新经典文章,欢迎关注公众号

————————————————
原文链接:https://blog.csdn.net/qq_42316200/article/details/103210837









没找到任何评论,期待你打破沉寂

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条