一个线上集群出现莫名奇妙不能写入数据的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. 在OC代码中创建Swift编写的视图控制器

    背景 近日在和一群朋友做项目,我和另一位同学负责iOS客户端,我是一直使用OC的,而他只会Swift,因此在我们分工协作之后,就需要把代码合在一起,这就牵扯到如何在TabbarController中添 ...

  2. 如何使用分布是缓存Hazelcast

    使用Hazelcast 1.在pom.xml中配置对Hazelcast的依赖 <dependencies> <dependency> <groupId>com.ha ...

  3. 微软在线测试之lucky string,有关斐波那契的题目都在此了

    解决方案: int _tmain(int argc,_TCHAR* argv[]) { size_t fib[] = {1,2,3,5,8,13,21,34}; string str,tempstr; ...

  4. (NO.00005)iOS实现炸弹人游戏(十):游戏主角(三)

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 下面我们来看游戏主角类里面几个播放特殊动画的方法,首先从run ...

  5. Android 实现图片加水印

    加水印代码 public Bitmap addWaterMark(Bitmap src, String water, Context context){ Bitmap tarBitmap = src. ...

  6. android横竖屏切换activity生命周期变化

    1.新建一个Activity,并把各个生命周期打印出来 2.运行Activity,得到如下信息 onCreate--> onStart--> onResume--> 3.按crtl+ ...

  7. 压力测试工具Ab简介

    Apache安装包中自带的压力测试工具 Apache Benchmark(简称ab) 简单易用,这里就采用 ab作为压力测试工具了. 1.独立安装 通过 yum-utils中的yumdownload  ...

  8. HMM:隐马尔科夫模型-维特比算法

    http://blog.csdn.net/pipisorry/article/details/50731584 目标-解决HMM的基本问题之二:给定观察序列O=O1,O2,-OT以及模型λ,如何选择一 ...

  9. Android开机键失灵启动手机的解决办法

    问题描述 Android手机的关机键损坏,无法开机. 解决方法 将手机通过USB线链接电脑,进入命令行,找到adb命令所在目录,运行如下命令: adb reboot 注意:用这种方法的前提是,如果你当 ...

  10. Oracle PL/SQL Articles

    我是搬运工....http://www.oracle-base.com/articles/plsql/articles-plsql.php Oracle 8i Oracle 9i Oracle 10g ...