21

HBase修复|HBase2.0的修复工具HBCK2

 3 years ago
source link: http://mp.weixin.qq.com/s?__biz=MzU5OTQ1MDEzMA%3D%3D&%3Bmid=2247487714&%3Bidx=2&%3Bsn=cd54e6e7b70d9a2dd6a822d6e4eaa783
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

1. 背景

在了解HBCK2之前,建议先了解一下啥是HBCK。HBCK是HBase1.x中的命令,到了HBase2.x中,HBCK命令不适用,且它的写功能( -fix )已删除,它虽然还可以报告HBase2.x集群的状态,但是由于它不了解HBase2.x集群内部的工作原理,因此其评估将不准确。因此,如果你正在使用HBase2.x,那么对HBCK2应该需要了解一些,即使你不经常用到。

2. 获取HBCK2

HBCK2已经被剥离出HBase成为了一个单独的项目,如果你想要使用这个工具,需要根据自己HBase的版本,编译源码。其GitHub地址为:https://github.com/apache/hbase-operator-tools.git

默认HBase的版本是 2.1.6 ,可以在父pom.xml文件里修改成你需要的版本,我们线上集群的版本是 cdh-6.3.1-hbase2.1.0 ,与默认版本接近,因此我就使用默认的版本。

项目根目录下运行打包命令:

mvn clean install -DskipTests

编译成功后的截图:

BvyYfqv.png!web image-20200527163300460

Base-hbck2的target目录下可以找到我们最后需要的jar

jAJ7Nz7.png!web image-20200527163419002

把该jar包上传到集群随便一个目录下。

3. 测试命令是否可以正常使用

开始使用HBCK2的命令,最直接的使用方式:

./bin/hbase hbck -j <jar包地址> <命令>

使用HBCK2禁用启用测试表。

运行禁用表命令:

hbase hbck -j hbase-hbck2-1.1.0-SNAPSHOT.jar setTableState leo_test DISABLED
  • hbase hbck -j hbase-hbck2-1.1.0-SNAPSHOT.jar 指定jar包的方式使用HBCK2命令

  • setTableState 改变表状态的命令

  • leo_test 表名

  • DISABLED 禁用状态

看图,表的状态已经被更改为DISABLED

fE3m2mB.png!web image-20200527164346921

运行启用表命令:

hbase hbck -j hbase-hbck2-1.1.0-SNAPSHOT.jar setTableState leo_test ENABLED

看图,表的状态已经被更改为ENABLED

MfyEza6.png!web image-20200527164512826

有个疑问就是,表状态被更改为DISABLED,这张表的region依然是online状态,表依然可以被正常查询。

以上操作顺利执行,就可以证明我们的HBCK2命令被安装成功了。

4. Procedure简介

HBase2集群几乎所有的操作都是通过procedure进行的,因此,HBCK2的工作实际就是修复各种不正常的procedure。

一个procedure是由一系列的操作组成,一旦完成,要么成功,要么失败(ROLL BACK),不存在中间状态,所以,procedure是支持事物的。

procedure执行的每一步都会以log的形式持久化在HBase的MasterProcWals目录下,这样master重启时也能通过日志来恢复之前的状态且继续执行。

对于运维而言最重要的一点就是procedure在执行过程中会拿好几把锁, 这个在处理问题时是很重要的,因为一旦锁没有释放,再做任何操作也只能是卡住等锁。

  • IdLock:procedure级别的锁,保证一个procedure不会被多个线程同时执行。

  • 资源锁:对HBase的内部资源进行加锁,不同的procedure加锁的粒度不同,目前有region/table/namespace/region server级别的锁。

举例来说,假设我assign一个region,那么procedure在执行的时候就需要对这个region进行加锁,这样如果有别的人想要unassign这个region,或者drop这个region所在的table,都需要等最早的assignment结束后释放锁了才能执行。这样防止有不一致的情况出现。

5. HBCK2核心功能介绍

5.1 bypass [OPTIONS] …

bypass可以将一个或多个卡住的procedure进行释放。

原理是,在procedure的类里有一个bypass的flag,每次执行时会检查这个flag是否为true,如果为true则直接返回null,这样procedure就会被认为执行成功。

而bypass就是把这个procedure对象中的这个flag设为true。这样stuck的procedure就能够不再执行,后续的修复才能继续。

返回值为true则是成功,false是失败。

参数解析:

-o,--overide

在执行bypass之前先会尝试去拿idLock,如果procedure还在运行就会超时返回null,但是设置了这个参数,即使拿不到idLock也会去将procedure的bypass flag设为true。

-r, --recursive

在bypass一个procedure时也会将这个procedure的所有子procedure进行递归bypass时。例如我们bypass一个对table schema修改的procedure,就需要加上-r参数,才能把这个操作的所有子procedure都bypass掉。

-w, --lockWait

上面提到的等到idLock的超时时间配置,默认为1ms。

5.2 assigns [OPTIONS]…

将一个或多个region再次随机assign到别的机器上,返回值时创建的pid则为成功,-1则为失败。

参数解析:

-o, --override

这里的override跟bypass的override不同,因为assign本身就会创建一个新的procedure,所以肯定是不涉及到拿idLock的,但是这里涉及到资源锁的问题。因为之前卡住的资源锁即使在bypass后也不会释放(用于fence, 防止更多未知的错误操作),所以需要加一个-o去手动释放这个资源锁。

下面,我们实际运行一下这个命令,感受其作用。

 hbase hbck -j hbase-hbck2-1.1.0-SNAPSHOT.jar assigns -o leo_test,,1588902855503.596a8c918380a9fb55ed64ecf716ecd6.
  • leo_test,,1588902855503.596a8c918380a9fb55ed64ecf716ecd6. 这个是我测试表,leo_test的一个region的encoded_name

命令执行的结果是:

image-20200527174818532

返回值为-1,说明命令运行失败。

十有八九是我的region name指定错了,重新运行如下命令。

hbase hbck -j hbase-hbck2-1.1.0-SNAPSHOT.jar assigns -o 596a8c918380a9fb55ed64ecf716ecd6

命令执行的结果是:

image-20200527175043176

可以看到,成功返回了此次procedure的ID,观察HBase自带的监控界面。

quQ7z2q.png!web image-20200527175200833

HBCK2的命令提交成功后,监控界面会显示此次操作的记录,里面可以查看命令运行的详细状态。

查看表的监控界面,发现我们操作的region依然在72那台机器上,看起来好像没有任何变化。不知道是不是由于我们测试的表只有一个region的缘故,于是,我又测试了一张有17个region的表。

除了master有这样的日志之外,还是没有任何效果。

mai2YjM.png!web image-20200527180214854

暂时实在搞不明白这条命令的具体效果,以后再慢慢研究吧,接着来看下一个核心功能。

5.3 unassigns [OPTIONS]…

将一个或多个region unassign,返回值是创建的pid则为成功,-1则为失败。

参数解析:

-o,--override,与assigns的一致

5.4 setTableState

可能的table状态, ENABLED, DISABLED, DISABLING, ENABLING

在table的状态和所有的region状态不一致时可以用这个命令进行修复

5.5 serverCrashProcedures …

手动schedule一个或多个serverCrashProcedure, 如果有serverCrashProcedure没有执行成功,但是procedure log已经丢失了,那么可以利用这个命令进行修复。返回值为创建的pid则为成功,-1则为失败。

patch在HBASE-21393[3],目前这个功能在release版本还没有。

VRzA73J.png!web image-20200527181148089

看样子应该能用,可现在就是不知道咋用。

6. 利用HBCK2来查找集群的问题

6.1 canary tool

模拟用户的读写请求,去访问集群上的表。当我们需要检查集群meta上记录的region assignment跟实际region server上打开的region是否一致时,可以使用这个命令去检查:

hbase canary -f false -t 6000000

nohup hbase canary -f false -t 6000000 > /data/leo_jie/hbase.log 2>&1 &

这个命令会向meta上的记录的每个region发送一个get请求,将-f设为false是为了不在遇到第一个错误时退出,-t则是这个命令的超时时间,我们设成了6000秒。在执行完成以后可以通过grep ERROR来找到那些有问题的region。

需要注意的是因为是模拟客户端发送的get请求,最好将HBase的客户端超时时间和超时次数配的小一些,否则会很慢。

PS: canary 本身也很适合用来作为集群可用性的监控,有兴趣的同学可以去了解一下。

 cat /data/leo_jie/hbase.log | grep ERROR

grep ERROR 来发现是否有异常信息。

6.2 页面状态

其实大部分的信息都会在master的页面上展示出来,我们来详细的介绍一下:

6vA3UjA.png!web image-20200527181721474

可以检查当前所有没有执行完的procedure以及所有资源锁,当我们想要assign或者unassign一个region时,需要先去检查下是有别的procedure已经占有了这个资源锁,如果是的话需要先将那个procedure bypass掉,或者等待那个procedure释放锁。

zMzA3qb.png!web image

可以看到EXCLUSIVE的lock只有region级别的,图中红框圈出来的就是占有这个锁的procedure id以及它的parent procedure id, 由此我们知道如果想要重新assign/unassign这个region,那么一定要bypass这个procedure。

同理,当Locks这块没有任何EXLUSIVE锁时,我们可以放心的去执行操作而不用担心被卡住。

以上内容节选自,HBase指南 | HBase 2.0之修复工具HBCK2运维指南,因为我在本地测试的时候,没有重现这种锁占用的情况。

6.3 OPENING/CLOSING region的查找

branch-2.0 上最容易出现的问题就是region卡在了OPENNING/CLOSING状态,一般处于这两种状态的region都会在rit的队列中,可以通过点击页面上的链接拿到所有的region以及对应的procedure id。

N7bEZfE.png!web image

可以看到现在有17个region处在transition中,我们可以点击红框圈住的这个链接,会展示所有的region。

nQRZZfZ.png!web image

因为我们最后是希望通过HBCK2来进行处理,那么最好是可以复制粘贴需要处理的region或者procedure, 所以可以点击圈出的这两个按钮,会以text形式展示所有region或者所有procedure。

VzUfiaq.png!web image

以上内容依旧是节选,因为没遇到RIT的情况,同时,我们也不希望遇见。:smile:

6.4 Master的日志

stuck的region会打印以下日志:

WARN [ProcExecTimeout] org.apache.hadoop.hbase.master.assignment.AssignmentManager: STUCK Region-In-Transition rit=OPENING, location=c4-hadoop-tst-st99.bj,42900,1542148656901, table=test_modify, region=8d81f74b324d0503c3fc87f34e9a17cb

7.解决问题

定位到问题之后,我们需要解决问题。

7.1 解决region卡在OPENING/CLOSING 状态

首先找到这些region对应的pid, 然后执行bypass, 检查是否锁都释放了,如果释放了就再assign一遍,如果需要close,就再unassign一次。

7.2 对table的修改有问题如何回退

找到这个修改的root procedure, bypass -or来bypass所有相关的procedure, 利用table unset来重置meta,因为bypass之后资源锁还是没有释放,所以需要手动加上override参数再去全部assigns一遍

7.3 Master起不来

日志里一般会有这个:

WARN org.apache.hadoop.hbase.master.HMaster: hbase:meta,,1.1588230740 is NOT online; state={1588230740 state=CLOSING, ts=1538456302300, server=ve1017.example.org,22101,1538449648131}; ServerCrashProcedures=true. Master startup cannot progress, in holding-pattern until region onlined.

手动去assign一下meta表即可,hbase:meta表的encoded name是一个时间戳,比如上面日志的encoded name就是1588230740

另外hbase:namespace表没有online也会造成这个问题,同样需要我们去手动assign一下

7.4 table卡在disabling状态

因为要求是所有region都disabled, 那么解决办法可以是手动把没有closed的region根据case1来解决。如果所有region都已经是closed状态了,那么我可以利用setTableState手动将表的状态设为DISABLED。之后再drop都是安全的了。

8. 总体的解决思路

其实HBase-2.x版本的运维思路很简单,因为使用了procedure,集群出现meta跟regionserver不一致的状态是很少的,一般都是有procedure出问题了。那么我们主要就是看怎么解决这个有问题的procedure。

如果是table/namespace级别的修改,因为设计到很多region的锁,如果需要bypass的话需要找到root procedure然后使用bypass -or.

如果只是region级别的问题,则bypass -o即可。

bypass之后检查locks的页面,看看是不是锁都释放了,如果没有锁了则根据需求进行assign或者unassign,或者对table的属性进行还原。

9. 参考链接

文中很多解决问题的思路参考了一下博客,后续实践中如果遇到此类问题,将会进行更加详细的分析和总结,然后补充文档。

  • HBase指南 | HBase 2.0之修复工具HBCK2运维指南

ZfABVzj.jpg!web


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK