HBase WAL(Write-Ahead-Log)学习

来源:互联网 发布:花椒网络主播怎么注册 编辑:程序博客网 时间:2024/05/16 10:22

概述

客户端向RegionServer端提交数据的时候,会写WAL日志,只是当WAL日志写成功以后,客户端才会被告诉提交数据成功,如果写WAL失败会告知客户端提交失败,换句话说这其实是一个数据落地的过程。在一个RegionServer上的所有的Region都共享一个HLog,一次数据的提交是先写WAL,再写memstore,示意图如下:

这里写图片描述

HLog Class

    WAL的实现类是HLog,当一个Region被初始化的时候,一个HLog的实例会作为构造函数的参数传进去。    当Region在处理Put、Delete等更新操作,可以直接使用该共享的Hlog的append方法来落地数据。    Put、Delete在客户端上可以通过setWriteToWAL(false)方法来关闭该操作的日志,这么做虽然可    以提升入库速度,但最好别这么做,因为有数据丢失的风险存在。    HLog的另一个重要功能是跟踪变化,这个通过sequence number来实现。sequence number作为    HFile里的一个元数据字段,它用来跟踪哪些日志是已经持久化了的,哪些还在内存中。

这里写图片描述

这个图表明同一个Regionserver上的三个Region共享一个Hlog,因此当他们写数据时,是把<HLogKey ,WALEdit>这个的kv对按顺序混合的写到Hlog上的,以获得最好的写入速度。

HLogKey Class

WAL现在是通过Hadoop的SequenceFile来存储key/value集合。value简单的存储了来自客户端的数据如rowkey,column family,column qualifier,timestamp,type,and value;而HLogKey则存储了the region and table name、还有更新时间,sequence number和cluster ID,cluster ID用于将日志复制到集群里的其他机器上。

WALEdit Class

自客户端的更新数据的请求被封装到WALEdit类上。这个类把对row数据的修改原子化

LogSyncer Class

Table在创建的时候,有一个参数可以设置,是否每次写Log日志都需要往集群里的其他机器同步一次,默认是每次都同步,同步的开销是比较大的,但不及时同步又可能因为机器宕而丢日志。

Pipeline 和n-Way Writes

同步的操作现在是通过Pipeline的方式来实现的,Pipeline是指datanode接收数据后,再传给另外一台datanode,是一种串行的方式;n-Way Writes是指多datanode同时接收数据,最慢的一台结束就是整个结束。差别在于一个延迟大,一个并发高,hdfs现在正在开发中,以便可以选择是按Pipeline还是n-Way Writes来实现写操作。 Table如果设置每次不同步,则写操作会被RegionServer缓存,并启动一个LogSyncer线程来定时同步日志,定时时间默认是一秒也可由hbase.regionserver.optionallogflushinterval设置 

HLog的几个特点

WAL(Write-Ahead-Log)是HBase的RegionServer在处理数据茶如何删除的过程中用来记录操作内容的一种日志。在每次Put、Delete、等一条记录时,首先将其数据封装,append到RegionServer对应的Hlog文件的过程。它有几个重要的特点:    1、RegionServer上所有的Region共享Hlog文件;也就是RegionServer的个数与HLog是一一对应的,为什么不选择每个Table对应一个HLog的原因是,通过RegionServer的个数可以衡量分布式系统的规模,这是

系统运维可以控制的因素,而Table的个数和大小完全是由应用层来决定。极端情况下,我们的Hbase集群
可能只有一张大表(每天10亿规模的读写),而可能需要上百个节点搭建Hbase集群,在这种秦光霞,按
照RegionServer记录一个HLog的意义就凸显出来了。同样的道理可以解释,为什么要把所有的Region的
log都插入同一个文件。

这里写图片描述

2.HLog也是记录在HDFS上;这一个众所周知的问题,这里提出来的原因在于,在大多数情况下它成为了影响了HBase写操作吞吐的重要原因。在进行批量删除数据时,每次操作时不写HLog比写HLog,性能要好大概10~20倍。而且正是由于写HDFS原因,可以看到大概有些点的性能偏离平均值2倍以上的性能,而这些点大部分属于写HDFS响应的时间的异常点。在HBase-0.92版本中,使用的append操作在hdfs底层其实就是一种write操作,而这种操作在遇到超过block预设大小时,会有一次和NameNode的操作,另外在高负载的HDFS集群上,写速度波浪式的,不会持续保持稳定,而这种不稳定对于像append遮掩的操作,最终在反复测试时,就会表现出偏离平均值2倍以上的1%现象。相比而言,没有写WAL的话,可以看到它不仅平均性能上表现更好,也在稳定性上更胜一筹,它的抖动出现在MemStore向HDFS刷数据的时间点上。显然,在MemeStore足够大的情况下,这种波动是可以预期的,甚至也是很多应用可以容忍的。写WAL还是不写WAL,在一定程度上确实会给系统性能产生了很大影响,根据Hbase内部设计,WAL是一种规避数据丢失风险的一种补偿机制,如果应用可以容忍一定的数据丢失风险,可以尝试在更新数据时,关闭写WAL。3.HLog是系统稳定的重要依据。在一个HRegionServer的存活周期内,可能因为长时间的Stop-The-World GC,或者因为它所依赖的HDFS或者zookeeper,出现下线的情况,对于一个高负载的HBase生产集群而言,这是一个非常普遍的现象。对于RegionServer的下线,往往通过jps监控进程存活和nc -z来监控关键服务端口的存活状态来验证服务的状态,保证让下线的RegionServer尽快恢复,保证原HBase集群的整体负载的吞吐。在RegionServer下线这个过程中,是Hbase内部最核心部件工作的关键时期,简单总结一下RegionServer下线后内核处理流程如下:(1)HMaster从Zookeeper捕获到对应RegionServer的znode被删除,将其放入ServerManager的DeadServers列表中。(2)启动ServerShutdownHandler,进入该handler的处理流程中(3)SplitLogManager对原RegionServer的HLog文件夹内的HLog文件提交到zookeeper的splitlog路径下(注意,HLog存在Roll操作,造成了HLog文件夹内可能存在多个hlog文件)(4)SplitLogManager等待RegionServer上的SplitLogWorker认领任务,并在任务完成之后,进入Region Assign流程。每个SplitLogWorker都会经历将HLog上出现的所有Region分别以文件的形式存储,在hbase所在hdfs根目录下splitlog文件夹内,会以RegionServer认领一个某个下线的RegionServer的HLog为文件夹名,包含按照Region分散开来的HLog文件集(5)HMaster的AssignmentManager从.META.以及当前出于InTranscation状态的集合中,计算出需要Assign的Region,然后通过getRegionPlan获得将该Region迁移的目的地址,并修改Region状态从offline变成OPENING。然后AssignmentManager就进入了状态机的处理流程中。(6)被选中目的地的Region,Master 通过RPC让其执行openRegion操作,RegionServer使用HRegion.openRegion,会首先经历一次replayRecoveredEditsIfAny,将那些散落在splitlog下各个worker处理过的Region的HLog信息加载过来,并执行replay。(7)所有相关的Region处理完毕,这样一个RegionServer下线的影响就结束了。在这段时间内,相应Region的读写操作全部暂停。你如果客户端写的比较友好,Region上线足够快的话,对于客户端而言,相当于一次服务都懂,只是这个抖动有点大。从这个流程中可以看出,虽然HLog采用了Distributed Split来加快切分,但是这里HLog的稳定仍然是服务稳定性重要因素。因此,有一项比较又去的事情是,我们完全可以做一个备用的RegionServer来轮询是否有RegionServer出于下线状态,一旦出于下线状态,就按照制度的方式来加载相应的Region,这样至少可以保证在RegionServer下线情况下数据服务的一定的可用性。
阅读全文
0 0
原创粉丝点击