<div class="blogpost-body" id="cnblogs_post_body">
<h3>HLog概述</h3>
<p>hbase在写入数据之前会先写入MemStore,成功了再写入HLog,当MemStore的数据丢失的时候,还可以用HLog的数据来进行恢复,下面先看看HLog的图。</p>
<p><img alt="" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-41e5f734d6b73ff81db1f5527e2e4cc3.jpg"></p>
<p>旧版的HLog是实际上是一个SequceneFile,0.96的已经使用Protobuf来进行序列化了。从Writer和Reader上来看HLog的都是Entry的,换句话说就是,它的每一条记录就是一个Entry。</p>
<div class="cnblogs_code">
<pre class="blockcode"><span style="color:#0000ff;">class</span> Entry <span style="color:#0000ff;">implements</span><span style="color:#000000;"> Writable {
</span><span style="color:#0000ff;">private</span><span style="color:#000000;"> WALEdit edit;
</span><span style="color:#0000ff;">private</span><span style="color:#000000;"> HLogKey key;
}</span></pre>
</div>
<p>所以上面那个图已经不准确了,HLogKey没变,但是Value缺不是KeyValue,而是WALEdit。</p>
<p>下面我们看看HLogKey的五要素,region、tableName、log的顺序、写入时间戳、集群id。</p>
<div class="cnblogs_code">
<pre class="blockcode"><span style="color:#0000ff;">public</span> HLogKey(<span style="color:#0000ff;">final</span> <span style="color:#0000ff;">byte</span> [] encodedRegionName, <span style="color:#0000ff;">final</span><span style="color:#000000;"> TableName tablename,
</span><span style="color:#0000ff;">long</span> logSeqNum, <span style="color:#0000ff;">final</span> <span style="color:#0000ff;">long</span> now, List<UUID><span style="color:#000000;"> clusterIds){
init(encodedRegionName, tablename, logSeqNum, now, clusterIds);
}
</span><span style="color:#0000ff;">protected</span> <span style="color:#0000ff;">void</span> init(<span style="color:#0000ff;">final</span> <span style="color:#0000ff;">byte</span> [] encodedRegionName, <span style="color:#0000ff;">final</span><span style="color:#000000;"> TableName tablename,
</span><span style="color:#0000ff;">long</span> logSeqNum, <span style="color:#0000ff;">final</span> <span style="color:#0000ff;">long</span> now, List<UUID><span style="color:#000000;"> clusterIds) {
</span><span style="color:#0000ff;">this</span>.logSeqNum =<span style="color:#000000;"> logSeqNum;
</span><span style="color:#0000ff;">this</span>.writeTime =<span style="color:#000000;"> now;
</span><span style="color:#0000ff;">this</span>.clusterIds =<span style="color:#000000;"> clusterIds;
</span><span style="color:#0000ff;">this</span>.encodedRegionName =<span style="color:#000000;"> encodedRegionName;
</span><span style="color:#0000ff;">this</span>.tablename =<span style="color:#000000;"> tablename;
}</span></pre>
</div>
<p>下面看看WALEdit的属性, 这里只列出来一个重要的,它是内部持有的一群KeyValue。。</p>
<div class="cnblogs_code">
<pre class="blockcode"><span style="color:#0000ff;">public</span> <span style="color:#0000ff;">class</span> WALEdit <span style="color:#0000ff;">implements</span><span style="color:#000000;"> Writable, HeapSize {
......</span><span style="color:#0000ff;">private</span> <span style="color:#0000ff;">final</span> ArrayList<KeyValue> kvs = <span style="color:#0000ff;">new</span> ArrayList<KeyValue>();</pre>
</div>
<p>HLog的具体实现类是FSHLog,一个Region Server有两个FSHLog,一个负责RS上面所有的用户region的日志,一个负责RS上面的META表的region的日志。</p>
<p>对于日志来说,我们关心的是它如何保证一致性和准确性,在需要它的时候可以发挥救命作用。</p>
<h3>HLog同步</h3>
<p>对于meta region的HLog写入之后,它会立即同步到硬盘,非meta表的region,它会先把Entry添加到一个队列里面等待同步。</p>
<div class="cnblogs_code">
<pre class="blockcode"><span style="color:#0000ff;">while</span>(!<span style="color:#0000ff;">this</span>.isInterrupted() && !<span style="color:#000000;">closeLogSyncer.get()) {
</span><span style="color:#0000ff;">try</span><span style="color:#000000;"> {
</span><span style="color:#0000ff;">if</span> (unflushedEntries.get() <=<span style="color:#000000;"> syncedTillHere) {
</span><span style="color:#0000ff;">synchronized</span><span style="color:#000000;"> (closeLogSyncer) {
closeLogSyncer.wait(</span><span style="color:#0000ff;">this</span><span style="color:#000000;">.optionalFlushInterval);
}
}</span><span style="color:#008000;">//</span><span style="color:#008000;"> 同步已经添加的entry<br></span><span style="color:#000000;"> sync();
} </span><span style="color:#0000ff;">catch</span><span style="color:#000000;"> (IOException e) {
LOG.error(</span>"Error while syncing, requesting close of hlog "<span style="color:#000000;">, e);
requestLogRoll();
Threads.sleep(</span><span style="color:#0000ff;">this</span><span style="color:#000000;">.optionalFlushInterval);
}
}</span></pre>
</div>
<p> </p>
<p><span style="color:#000000;">它这里是有 |
|