博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多Region下HBase写入问题
阅读量:4662 次
发布时间:2019-06-09

本文共 1942 字,大约阅读时间需要 6 分钟。

    最近在集群上发现hbase写入性能受到较大下降,测试环境下没有该问题产生。而生产环境和测试环境的区别之一是生产环境的region数量远远多于测试环境,单台regionserver服务了约3500个region。
    通过jstack工具检查到大半写入线程BLOCKED状态在"public synchronized void reclaimMemStoreMemory() {"这一行,这是在put之前的一个检查过程。
    hbase在每次put以前,需要检查当前regionserver上的memstore是否超过总memstore阀值,如果超过,需要block住当前的写入,防止OOM,代码片段见下:
Java代码  
  1. /** 
  2.    * Check if the regionserver's memstore memory usage is greater than the 
  3.    * limit. If so, flush regions with the biggest memstores until we're down 
  4.    * to the lower limit. This method blocks callers until we're down to a safe 
  5.    * amount of memstore consumption. 
  6.    */  
  7.   public synchronized void reclaimMemStoreMemory() {  
  8.     if (isAboveHighWaterMark()) {  
  9.       lock.lock();  
  10.       try {  
  11.         while (isAboveHighWaterMark() && !server.isStopped()) {  
  12.           wakeupFlushThread();  
  13.           try {  
  14.             // we should be able to wait forever, but we've seen a bug where  
  15.             // we miss a notify, so put a 5 second bound on it at least.  
  16.             flushOccurred.await(5, TimeUnit.SECONDS);  
  17.           } catch (InterruptedException ie) {  
  18.             Thread.currentThread().interrupt();  
  19.           }  
  20.         }  
  21.       } finally {  
  22.         lock.unlock();  
  23.       }  
  24.     } else if (isAboveLowWaterMark()) {  
  25.       wakeupFlushThread();  
  26.     }  
  27.   }  
    这是一个同步操作,其中isAboveHighWaterMark()的代码如下:
Java代码  
  1. private boolean isAboveHighWaterMark() {  
  2.   return server.getGlobalMemStoreSize() >= globalMemStoreLimit;  
  3. }  
    getGlobalMemStoreSize()里面的操作是遍历所有region,拿到每个region的memstore大小:
Java代码  
  1. public long getGlobalMemStoreSize() {  
  2.   long total = 0;  
  3.   for (HRegion region : onlineRegions.values()) {  
  4.     total += region.memstoreSize.get();  
  5.   }  
  6.   return total;  
  7. }  
    如果region数量很多就比较杯具了,在单台服务器3500个region的环境下通过btrace跟踪到这一步需要耗时0.4ms,也就是每一个put会block所有线程0.4ms,这样无法发挥出server端并行处理能力,同时可以计算出无论如何配置,写tps无法超过1000/0.4=2500!
    产生这个问题的根本原因是在0.90.x版本中,region无法拿到regionserver的信息,因此只能通过实时计算来得到rs上总的memstore大小。在0.92.0或trunk版本中修改了HRegion的数据结构,让HRegion在初始化时得到regionserver的信息,因此可以实时记录memstore的总大小,并让每个region对象能拿到该值,于是这个isAboveHighWaterMark()就不再block住所有线程了,在region较多的场景下写性能得到较大提升。
    参照,可以以此patch为参考生成相应的0.90.x版本的patch

转载于:https://www.cnblogs.com/cl1024cl/p/6205187.html

你可能感兴趣的文章
线性代数基础
查看>>
【以太坊开发】如何开发一个编译以太坊智能合约并且发布的平台(一)
查看>>
两个矩阵相乘算法
查看>>
go包管理工具glide
查看>>
PHP XML Parser 函数
查看>>
HDU 1166 敌兵布阵(线段树区间求和)
查看>>
12月26 一维数组
查看>>
Android之网络管理
查看>>
Access denied for user 'root'@'localhost' (using password:YES)
查看>>
CXF整合spring
查看>>
使用python selenium webdriver模拟浏览器
查看>>
session 、cookie、token的区别
查看>>
Python-生成器_36
查看>>
mysql慢查询日志分析
查看>>
HTTP从入门到入土(4)——URI、URL和URN
查看>>
photoshop自动切图,导出svg,支持阿里巴巴图标库上传相互转换
查看>>
UI事件 计算器界面
查看>>
lucene简单使用demo
查看>>
实验三
查看>>
敏捷开发
查看>>