一个线上集群出现莫名奇妙不能写入数据的bug,log中不断打印如下信息:

引用
2011-11-09 07:35:45,911 INFO org.apache.hadoop.hbase.regionserver.HRegion: Blocking updates for 'IPC Server handler 32 on 60020' on

region xxx,333-2395000000032117,1320773734010.9a7ae39b5a42ccfa1fa6118aa8f79195.: memstore size 128.0m is >= than blocking 128.0m size

我们知道每次put时会检查当前的memstore大小,当大于flush值的一个系数时(系数默认为2倍),就会block住这次写请求,并提交一个flush任务。但是很奇怪的是,用户此时再也不能往这个region写数据了,并在大约10多个小时以后又神奇地自然恢复了。

    原因是什么呢?

    经过一番检查,发现了hbase的一个bug,我们准备修改后提交到社区,不过因为实在太有趣了,体现了分布式事务的很有趣特征,所以先在此分享一下原因吧。

    这个问题是由以下四个事件共同组成的,我把代码简单化后作如下整理:

1 put:

  1. put{
  2. checkResources{
  3. while (this.memstoreSize.get() > this.blockingMemStoreSize) {
  4. if(flushRequested==true)
  5. continue;
  6. flushRequested = true;
  7. flushQueue.add(this);
  8. }
  9. ...
  10. }
  11. ...
  12. }

2 memstoreFlusher:

  1. while(!serverstop){
  2. task = flushQueue.poll();
  3. if(task == null)
  4. continue;
  5. if(closing)
  6. continue;
  7. try{
  8. if(closed)
  9. continue;
  10. if(flush(task))
  11. continue;
  12. else
  13. break;
  14. }finally{
  15. flushRequested = false;
  16. }
  17. }

3 split:

  1. ...
  2. closing = true;
  3. closed = true;
  4. ...

4 rollback:

  1. ...
  2. closing = false;
  3. closed = false;
  4. ...

故障还原:当该region执行一次flush时,flushRequested被put线程置为了true,并push一个flush任务。然后memstoreFlusher检查到该任务时,刚好split开始进行,进行到了CLOSED_PARENT_REGION那一步,处于closing状态,于是memstoreflusher跳过任务,但在这里,memstoreflusher仍然报告该任务完成了,于是flush队列被清空。

    但split在执行splitStoreFiles时,因为hdfs的问题失败了(具体原因是namenode在close一个文件的时候失败,不停地retry并超时),此时split开始执行回滚,即该region恢复到split之前的状态,于是我们发现该region又重新onlined。



    虽然split在rollback的时候会将closing和closed状态置回来,但因为flush队列己然被清空了,于是陷入以下循环:

  • put数据的线程,发现需要flush,但flushRequested为true,说明还有flush任务没完成,于是继续等待,并不会提交flush任务
  • memstoreFlush的线程,每次取flushQueue都为空,于是循环等待put线程提交flush任务,因此写数据就被block住了

以上悲催的情况将一直持续,直到迎来cleanOldLogs任务。因为cleanOldLogs会每小时执行一次,它会将最早的.logs目录下的文件移到.oldlogs目录下,但移之前先检查该文件中所有的数据是否己经flush到磁盘了,如果还没有就将该region执行一次flush。所以在经过n小时以后,.logs终于滚动到了用户之前卡住的那一段,这时就强制执行flush任务,因此flushQueue队列就不为空了,死循环被打破。系统也就自愈了。

HBase写被block的分析的更多相关文章

  1. 原 iOS深入学习(Block全面分析)http://my.oschina.net/leejan97/blog/268536

    原 iOS深入学习(Block全面分析) 发表于1年前(2014-05-24 16:45)   阅读(26949) | 评论(14) 39人收藏此文章, 我要收藏 赞21 12月12日北京OSC源创会 ...

  2. MongoDB、Hbase、Redis等NoSQL分析

    NoSQL的四大种类 NoSQL数据库在整个数据库领域的江湖地位已经不言而喻.在大数据时代,虽然RDBMS很优秀,但是面对快速增长的数据规模和日渐复杂的数据模型,RDBMS渐渐力不从心,无法应对很多数 ...

  3. HBase写过程详解

    1首次读写流程图 2 首次写基本流程 (1)客户端发起PUT请求,Zookeeper返回hbase:meta所在的region server (2)去(1)返回的server上,根据rowkey去hb ...

  4. Hbase写数据,存数据,读数据的详细过程

    Client写入 -> 存入MemStore,一直到MemStore满 -> Flush成一个StoreFile,直至增长到一定阈值 -> 出发Compact合并操作 -> 多 ...

  5. HBase写请求分析

    HBase作为分布式NoSQL数据库系统,不单支持宽列表.而且对于随机读写来说也具有较高的性能.在高性能的随机读写事务的同一时候.HBase也能保持事务的一致性. 眼下HBase仅仅支持行级别的事务一 ...

  6. 【hbase】——HBase 写优化之 BulkLoad 实现数据快速入库

    1.为何要 BulkLoad 导入?传统的 HTableOutputFormat 写 HBase 有什么问题? 我们先看下 HBase 的写流程: 通常 MapReduce 在写HBase时使用的是 ...

  7. Hbase写入hdfs源码分析

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

  8. 提高HBase写性能

    以下为使用hbase一段时间的三个思考,由于在内存充足的情况下hbase能提供比较满意的读性能,因此写性能是思考的重点.希望读者提出不同意见讨论 1 autoflush=false的影响 无论是官方还 ...

  9. HBase 写优化之 BulkLoad 实现数据快速入库

    在第一次建立Hbase表的时候,我们可能需要往里面一次性导入大量的初始化数据.我们很自然地想到将数据一条条插入到Hbase中,或者通过MR方式等.但是这些方式不是慢就是在导入的过程的占用Region资 ...

随机推荐

  1. ROS连接ABB机械臂调试详细教程-ROS(indigo)和ABB RobotStudio 6.03.02-

    在ROS industrial介绍中,给出了ROS和常用机械臂的连接方式.具体信息可以参考:http://wiki.ros.org/Industrial ROS连接ABB机械臂调试详细教程-ROS(i ...

  2. iOS日历中给一个事件添加多个提醒

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) iOS自带的日历应用中,我们最多只能给一个事件设置2个提醒,但 ...

  3. 简单搭建iOS开发项目框架

    今天我们来谈谈如何搭建框架,框架需要做一些什么. 第一步:找到我们的目标我们的目标是让其他开发人员拿到手后即可写页面,不再需要考虑其他的问题. 第二步:我们需要做哪些东西各位跟着我一步一步来进行. 假 ...

  4. linux中查看现在使用的shell是ksh还是bash?以及怎样修改?

    查看系统支持的shell: cat  /etc/shells 查看现在使用的shell:  修改默认shell: 另外,修改了系统默认shell之后不会立即生效,之后再次登录系统修改的shell才会生 ...

  5. hive的strict模式;where,group by,having,order by同时使用的执行顺序

    主要限制三种情况 (1) 有partition的表查询需要加上where子句,筛选部分数据实现分区裁剪,即不允许全表全分区扫描,防止数据过大 (2) order by 执行时只产生一个reduce,必 ...

  6. RecyclerView嵌套RecyclerView

    ListView嵌套GridView http://blog.csdn.net/baiyuliang2013/article/details/42646289 RecyclerView下拉刷新上拉加载 ...

  7. linux 定时任务详解 按秒设定

    实现linux定时任务有:cron.anacron.at等,这里主要介绍cron服务. 名词解释: cron是服务名称,crond是后台进程,crontab则是定制好的计划任务表. 软件包安装: 要使 ...

  8. listview下拉刷新上拉加载扩展(三)-仿最新版美团外卖

    本篇是基于上篇listview下拉刷新上拉加载扩展(二)-仿美团外卖改造而来,主要调整了headview的布局,并加了两个背景动画,看似高大上,其实很简单: as源码地址:http://downloa ...

  9. [GitHub]第三讲:简单分支操作

    Git 最核心的操作对象是版本( commit ),最核心的操作技巧就是分支. 什么是分支? 仓库创建后,一旦有了新 commit,默认就会放到一个分支上,名字叫 master.前面咱们一直看到的多个 ...

  10. javascript之DOM编程通过html元素的标签属性找节点

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...