hbase DroppedSnapshotException

hbase夯机问题:

 FATAL org.apache.hadoop.hbase.regionserver.HRegionServer: ABORTING region server : Replay of WAL required. Forcing server shutdown?
 Caused by: org.apache.hadoop.hbase.exceptions.TimeoutIOException: Failed to get sync result after  ms for ringBufferSequence=, WAL system stuck?

解决思路:

一:Memstore Flush触发条件

HBase会在如下几种情况下触发flush操作,需要注意的是MemStore的最小flush单元是HRegion而不是单个MemStore。可想而知,如果一个HRegion中Memstore过多,每次flush的开销必然会很大,因此我们也建议在进行表设计的时候尽量减少ColumnFamily的个数。

Memstore级别限制:当Region中任意一个MemStore的大小达到了上限(hbase.hregion.memstore.flush.size,默认128MB),会触发Memstore刷新。

Region级别限制:当Region中所有Memstore的大小总和达到了上限(hbase.hregion.memstore.block.multiplier * hbase.hregion.memstore.flush.size,默认 2* 128M = 256M),会触发memstore刷新。

Region Server级别限制:当一个Region Server中所有Memstore的大小总和达到了上限(hbase.regionserver.global.memstore.upperLimit * hbase_heapsize,默认 40%的JVM内存使用量),会触发部分Memstore刷新。Flush顺序是按照Memstore由大到小执行,先Flush Memstore最大的Region,再执行次大的,直至总体Memstore内存使用量低于阈值(hbase.regionserver.global.memstore.lowerLimit * hbase_heapsize,默认 38%的JVM内存使用量)。

当一个Region Server中HLog数量达到上限(可通过参数hbase.regionserver.maxlogs配置)时,系统会选取最早的一个 HLog对应的一个或多个Region进行flush

HBase定期刷新Memstore:默认周期为1小时,确保Memstore不会长时间没有持久化。为避免所有的MemStore在同一时间都进行flush导致的问题,定期的flush操作有20000左右的随机延时。

手动执行flush:用户可以通过shell命令 flush ‘tablename’或者flush ‘region name’分别对一个表或者一个Region进行flush。

二:hbase源码;

> /**
>    * Flush a region.
>    * @param region Region to flush.
>    * @param emergencyFlush Set if we are being force flushed. If true the region
>    * needs to be removed from the flush queue. If false, when we were called
>    * from the main flusher run loop and we got the entry to flush by calling
>    * poll on the flush queue (which removed it).
>    * @param forceFlushAllStores whether we want to flush all store.
>    * @return true if the region was successfully flushed, false otherwise. If
>    * false, there will be accompanying log messages explaining why the region
was
>    * not flushed.
>    */
>   private boolean flushRegion(HRegion region, boolean emergencyFlush, boolean forceFlushAllStores,
>       FlushLifeCycleTracker tracker) {
>     synchronized (this.regionsInQueue) {
>       FlushRegionEntry fqe = this.regionsInQueue.remove(region);
>       // Use the start time of the FlushRegionEntry if available
>       if (fqe != null && emergencyFlush) {
>         // Need to remove from region from delay queue. When NOT an
>         // emergencyFlush, then item was removed via a flushQueue.poll.
>         flushQueue.remove(fqe);
>       }
>     }
>     tracker.beforeExecution();
>     lock.readLock().lock();
>     try {
>       notifyFlushRequest(region, emergencyFlush);
>       FlushResult flushResult = region.flushcache(forceFlushAllStores, false, tracker);
>       boolean shouldCompact = flushResult.isCompactionNeeded();
>       // We just want to check the size
>       boolean shouldSplit = region.checkSplit() != null;
>       if (shouldSplit) {
>         this.server.compactSplitThread.requestSplit(region);
>       } else if (shouldCompact) {
>         server.compactSplitThread.requestSystemCompaction(region, Thread.currentThread().getName());
>       }
>     } catch (DroppedSnapshotException ex) {
>       // Cache flush can fail in a few places. If it fails in a critical
>       // section, we get a DroppedSnapshotException and a replay of wal
>       // is required. Currently the only way to do this is a restart of
>       // the server. Abort because hdfs is probably bad (HBASE-644 is a case
>       // where hdfs was bad but passed the hdfs check).
>       server.abort("Replay of WAL required. Forcing server shutdown", ex);
>       return false;
>     } catch (IOException ex) {
>       ex = ex instanceof RemoteException ? ((RemoteException) ex).unwrapRemoteException() : ex;
>       LOG.error(
>         "Cache flush failed"
>             + (region != null ? (" for region " +
>                 Bytes.toStringBinary(region.getRegionInfo().getRegionName()))
>               : ""), ex);
>       if (!server.checkFileSystem()) {
>         return false;
>       }
>     } finally {
>       lock.readLock().unlock();
>       wakeUpIfBlocking();
>       tracker.afterExecution();
>     }
>     return true;
>   }
>

三:其中失败代码:

catch (DroppedSnapshotException ex) {

       // Cache flush can fail in a few places. If it fails in a critical
       // section, we get a DroppedSnapshotException and a replay of wal
      // is required. Currently the only way to do this is a restart of
      // the server. Abort because hdfs is probably bad (HBASE-644 is a case
       // where hdfs was bad but passed the hdfs check).
       server.abort("Replay of WAL required. Forcing server shutdown", ex);
      return false;
    }

四:解决方案:

1.设置memstore大小;HloG数量设置;

2.check hdfs 并且修复

3.重启server。

    原文作者:奈文摩尔ST
    原文地址: https://www.jianshu.com/p/95bfa9e9bd71
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞