splitlog期间丢失数据的问题

splitlog是保证在重启或rs挂掉后,恢复hlog的重要手段。master需要将hlog写到各个region目录下的recovered.edits目录中,然后由各台rs自行replay这个目录来恢复数据。这个过程中,master会启动一个读线程和多个写线程,一边读到内存中,一边将内存队列中的数据写到各个目录中去。
当master将.logs下的数据写到recovered.edits后,会把.logs目录下的文件mv到.oldlogs中。如果splitlog期间master挂掉,下次启动时会重复以上过程。但是杯具的是,master并不会等待recovered.edits写完以后再将.logs下的文件mv到.oldlogs中,而是当.logs下的文件读入内存结束以后就执行mv操作。因此如果这些数据在内存还没有写完成recovered.edits时,mv操作又结束时master就挂掉,则数据就丢失了。当然实际情况出现的概率还是比较小的,因为master并不是一次把.logs全部读入内存,而是128MB地读,所以只有当最后一个128MB在内存中时,才会执行mv操作,这时就有丢失数据的风险了。应对以下代码做调整:
Index: src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLogSplitter.java
===================================================================
--- src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLogSplitter.java (revision 99281)
+++ src/main/java/org/apache/hadoop/hbase/regionserver/wal/HLogSplitter.java (working copy)
@@ -289,10 +289,10 @@
"Discovered orphan hlog after split. Maybe the "
+ "HRegionServer was not dead when we started");
}
- archiveLogs(srcDir, corruptedLogs, processedLogs, oldLogDir, fs, conf);
} finally {
LOG.info("Finishing writing output logs and closing down.");
splits = outputSink.finishWritingAndClose();
+ archiveLogs(srcDir, corruptedLogs, processedLogs, oldLogDir, fs, conf);
}
return splits;
}

即将mv操作移动到等所有写线程结束以后再做。这样数据就不会丢失了。带来的副作用是在异常退出而下次启动时有可能在recovered.edits下面重复写log文件(因为上次退出时有可能留下一些文件)。但这最多增加一点重启的时间,总要比丢失数据好。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值