最近在集群上发现hbase写入性能受到较大下降,测试环境下没有该问题产生。而生产环境和测试环境的区别之一是生产环境的region数量远远多于测试环境,单台regionserver服务了约3500个region。

    通过jstack工具检查到大半写入线程BLOCKED状态在"public synchronized void reclaimMemStoreMemory() {"这一行,这是在put之前的一个检查过程。

    hbase在每次put以前,需要检查当前regionserver上的memstore是否超过总memstore阀值,如果超过,需要block住当前的写入,防止OOM,代码片段见下:

  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()的代码如下:

  1. private boolean isAboveHighWaterMark() {
  2. return server.getGlobalMemStoreSize() >= globalMemStoreLimit;
  3. }

getGlobalMemStoreSize()里面的操作是遍历所有region,拿到每个region的memstore大小:

  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较多的场景下写性能得到较大提升。

    参照https://issues.apache.org/jira/browse/HBASE-3694,可以以此patch为参考生成相应的0.90.x版本的patch

多Region下HBase写入问题的更多相关文章

  1. Hbase写入量大导致region过大无法split问题

    最近在线上往hbase导数据,因为hbase写入能力比较强,没有太在意写的问题.让业务方进行历史数据的导入操作,中间发现一个问题,写入速度太快,并且业务数据集中到其中一个region,这个region ...

  2. HBase写入性能改造(续)--MemStore、flush、compact参数调优及压缩卡的使用【转】

    首先续上篇测试:   经过上一篇文章中对代码及参数的修改,Hbase的写入性能在不开Hlog的情况下从3~4万提高到了11万左右. 本篇主要介绍参数调整的方法,在HDFS上加上压缩卡,最后能达到的写入 ...

  3. 如何避免HBase写入过快引起的各种问题

    首先我们简单回顾下整个写入流程 client api ==> RPC ==> server IPC ==> RPC queue ==> RPC handler ==> w ...

  4. 8.hbase写入流程和读取流程

    1 hbase写入流程 hbase中无论是新增数据还是修改已有行,其内部流程都是一样的,hbase执行写入时会写到两个地方,write-ahead log 简称wal 也叫hlog 预写式日志 和 M ...

  5. HBase写入性能及改造——multi-thread flush and compaction(续:详细测试数据)[转]

    转载:http://blog.csdn.net/kalaamong/article/details/7290192 接上文啊: 测试机性能 CPU 16* Intel(R) Xeon(R) CPU   ...

  6. HBase写入操作卡住长时间不返回的原因分析

    本文出处:http://blog.csdn.net/chaijunkun/article/details/44238163,转载请注明. 由于本人不定期会整理相关博文,会对相应内容作出完好.因此强烈建 ...

  7. HBase写入异常RejectedExecutionException

    HBase在大数据量并发写入时,写一段时间后HBase监控界面出现告警,写入程序日志里频繁出现异常java.util.concurrent.RejectedExecutionException: 从异 ...

  8. Hbase写入hdfs源码分析

    版权声明:本文由熊训德原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/258 来源:腾云阁 https://www.qclo ...

  9. Linux下HBase和Maven的环境搭建

    Maven环境部署如下: maven下载并进行环变量配置 export MAVEN_HOME=/home/hadoop/app/apache-maven-3.3.9export PATH=$MAVEN ...

随机推荐

  1. 1.2、Android Studio为新设备创建一个模块

    模块为你的应用的源码.资源文件和app level设置(比如AndroidManifest.xml)提供了一个容器.每个模块可以独立的构建.测试和调试. 通过使用模块,Android Studio可以 ...

  2. Android游戏开发之SurfaceView的使用-android学习之旅(五)

    SurfaceView和View的区别 View是在ui主线程中,直接响应用户的操作,以及任务的分发,但是任务比较复杂会出现阻塞. SurfaceView则不会出现这种问题,以为它直接从内存等取得图像 ...

  3. Oracle使用游标查询指定数据表的所有字段名称组合而成的字符串

    应用场合:参考网上查询数据表的所有字段名代码,使用游标生成指定单个表的所有字段名跟逗号组成的用于select  逗号隔开的字段名列表 from字符串等场合. 查询结果输出如下: 当前数据表TB_UD_ ...

  4. 开源项目——小Q聊天机器人V1.1

    小Q聊天机器人V1.0 http://blog.csdn.net/baiyuliang2013/article/details/51386281 小Q聊天机器人V1.1 http://blog.csd ...

  5. ajax核心技术1---XMLHttpRequset对象的使用

    AJAX即"Asynchronous Javascript And XML"(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术.AJAX = 异步 Ja ...

  6. 【一天一道LeetCode】#349. Intersection of Two Arrays

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given t ...

  7. Redefine:Change in the Changing World

    EMC World 2014的主题就是REDEFINE.的确,现在科技的发展在重新定义了技术,影响了生活,改变了你我. 对于一个有数万员工,甚至数十万员工的企业来说,Redefine无疑更加具有挑战, ...

  8. GrabCut in One Cut(基于图割算法grabcut的一次快速图像分割的OpenCV实现)----目前效果最好的图割

     One cut in grabcut(grabcut算法的非迭代实现?) 本文针对交互式图像分割中的图割算法,主要想翻译一篇英文文献.不足之处请大家指正. 这是博主近期看到的效果最好,实现最简单 ...

  9. MBR和GPT概要学习

    MBR和GPT概要学习 1.     MBR和GPT 大家所最为熟知的分区方式同时也是最主流的主要有两种:MBR(Master Boot Record)和GPT(GUID Partition Tabl ...

  10. Oracle生成查询包含指定字段名对应的所有数据表记录语句

    应用场合:已知字段名字,查询数据库中所有数据表中包含该字段名的所有数据表 操作办法:指定字段名,数据库表用户,执行下面查询语句即可 --Oracle生成查询包含指定字段名对应的所有数据表记录语句 de ...