赞
踩
目前社区已经发布了 HBase 的 2.0 版本,很多公司都希望去尝试新版本上的新功能,但是不得不面对的问题就是当集群出了问题应该如何解决。在之前的 HBase 版本中,我们可以依赖 hbck 来帮助检查问题和修复问题,在新的版本上我们应该如何去处理呢?HBASE-19121[1]给了我们答案——HBCK2。HBCK2 目前发布了 1.0 版本,还在一直开发中,感兴趣的同学看看这个 issue
由于之前的 hbck(hbck-1)是会直接去向 region server 或者 hdfs 发送请求进行修复,而在 HBase 2.0 版本上集群内部操作全部都被挪到了 procedure v2(下文都称为 procedure)上进行处理。
因为所有的命令都是经过 master 来协调处理,所以在修复时也需要通过 master 进行修复。否则反而可能导致更严重的不一致问题。所以 hbck-1 在 HBase-2.x 版本是不适用的。
除此以外,很多 hbck-1 需要处理的问题对于使用 procedure 的 HBase-2.x 已经不再是问题了,所以相比起 hbck-1 来说也精简了很多功能。
社区希望把 HBase 相关的外围工具抽离出 HBase 项目,所以在 github 上建了一个 project hbase-operator-tools: hbase-operator-tools[2],HBCK2 也在其中
git clone https://github.com/apache/hbase-operator-tools.git
修改 pom 中依赖的 HBase 版本 ,实际使用的 HBase 版本.version>
mvn clean package
cd 到 HBase 目录下,执行命令:
mvn clean package
编译出的 hbck2_jar 包地址
./bin/hbase org.apache.hbase.HBCK2 <命令>
或者也可以:
./bin/hbase hbck -j <jar 包地址> <命令>
由于目前几乎所有的集群操作都是通过 procedure 进行的,所以 HBCK2 的工作实际就是修复各种不正常的 procedure。所以在这里有必要对 procedure 进行一个简单的介绍。
一个 procedure 是由一系列的操作组成的,一旦完成后,要么成功,要么失败(ROLL BACK), 不存在中间状态,所以 procedure 是支持事务的。procedure 执行的每一步都会以 log 的形式持久化在 HBase 的 MasterProcWals 目录下,这样
master 在重启时也能通过日志来恢复之前的状态并且继续执行。对于运维而言最重要的一点就是 procedure 在执行过程中会拿好几把锁, 这个在处理问题时是很重要的,因为一旦锁没有释放,再做任何操作也只能是卡住等锁。
举例来说,假设我 assign 一个 region,那么 procedure 在执行的时候就需要对这个 region 进行加锁,这样如果有别的人想要 unassign 这个 region,或者 drop 这个 region 所在的 table,都需要等最早的 assignment 结束后释放锁了才能执行。这样防止有不一致的情况出现。
HBCK2 的核心功能,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。例如我们 bypass 一个对 table schema 修改的 procedure, 就需要加上-r 参数,才能把这个操作的所有子 procedure 都 bypass 掉。在 bypass 一个 procedure 时也会将这个 procedure 的所有子 procedure 进行递
-w, --lockWait
上文提到的等待 IdLock 的超时时间配置,默认为 1ms
将一个或多个 region 再次随机 assign 到别的机器上,返回值是创建的 pid 则为成功,-1 则为失败。
参数解析:
-o,--override
这里的 override 跟 bypass 的 override 不同,因为 assign 本身就会创建一个新的procedure, 所以肯定是不涉及到拿 IdLock 的,但是这里涉及到资源锁的问题。因为之前卡住的资源锁即使在 bypass 后也不会释放(用于 fence, 防止更多未知的错误操作),所以需要加一个-o 去手动释放这个资源锁。
将一个或多个 region unassign,返回值是创建的 pid 则为成功,-1 则为失败。参数解析:
-o,--override,与 assigns 的一致
可能的 table 状态, ENABLED, DISABLED, DISABLING, ENABLING
在 table 的状态和所有的 region 状态不一致时可以用这个命令进行修复。
手动 schedule 一个或多个 serverCrashProcedure, 如果有 serverCrashProcedure 没有执行成功,但是 procedure log 已经丢失了,那么可以利用这个命令进行修复。返回值为创建的 pid 则为成功,-1 则为失败。
patch 在 HBASE-21393[3],目前这个功能在 release 版本还没有。
所有的武器我们都有了,再回顾一下之前提到的问题,我们应该怎么处理呢?在Case 解决中我们会详细阐述应该怎么处理,这里大家可以先思考一下。
这个章节我们会介绍怎么去发现目前集群可能存在的问题。
模拟用户的读写请求,去访问集群上的表。当我们需要检查集群 meta 上记录的region assignment 跟实际 region server 上打开的 region 是否一致时,可以使用这个命令去检查:
hbase canary -f false -t 6000000
这个命令会向 meta 上的记录的每个 region 发送一个 get 请求,将-f 设为 false 是为了不在遇到第一个错误时退出,-t 则是这个命令的超时时间,我们设成了6000 秒。在执行完成以后可以通过 grep ERROR 来找到那些有问题的 region。
需要注意的是因为是模拟客户端发送的 get 请求,最好将 HBase 的客户端超时时间和超时次数配的小一些,否则会很慢。
PS: canary 本身也很适合用来作为集群可用性的监控,有兴趣的同学可以去了解一下。
其实大部分的信息都会在 master 的页面上展示出来,我们来详细的介绍一下:
Procedures & Locks:
可以检查当前所有没有执行完的 procedure 以及所有资源锁,当我们想要 assign 或者 unassign 一个 region 时,需要先去检查下是由有别的 procedure 已经占有了这个资源锁,如果是的话需要现将那个 procedure bypass 掉,或者等待那个
procedure 释放锁。
以看到 EXCLUSIVE 的 lock 只有 region 级别的,图中红框圈出来的就是占有这个锁的 procedure id 以及它的 parent procedure id, 由此我们知道如果想要重新assign/unassign 这个 region,那么一定要 bypass 这个 procedure。
同理,当 Locks 这块没有任何 EXLUSIVE 锁时,我们可以放心的去执行操作而不用担心被卡住。
branch-2.0 上最容易出现的问题就是 region 卡在了 OPENNING/CLOSING 状态, 一般处于这两种状态的 region 都会在 rit 的队列中,可以通过点击页面上的链接拿到所有的 region 以及对应的 procedure id。
可以看到现在有 17 个 region 处在 transition 中,我们可以点击红框圈住的这个链接,会展示所有的 region。
因为我们最后是希望通过 HBCK2 来进行处理,那么最好是可以复制粘贴需要处理的 region 或者 procedure, 所以可以点击圈出的这两个按钮,会以 text 形式展示所有 region 或者所有 procedure。
stuck 的 region 会打印以下日志:
WARN [ProcExecTimeout] org.apache.hadoop.hbase.master.assignment.Assignment Manager: STUCK Region-In-Transition rit=OPENING, location=c4-hadoop-tst-st99.bj,42900,1542148656901, table=test_modify, region=8d81f74b324d0503c3fc87f34e9a17cb
首先找到这些 region 对应的 pid, 然后执行 bypass, 检查是否锁都释放了,如果释放了就再 assign 一遍,如果需要 close,就再 unassign 一次
找到这个修改的 root procedure, bypass -or 来 bypass 所有相关的 procedure, 利用 table unset 来重置 meta,因为 bypass 之后资源锁还是没有释放,所以需要手动加上 override 参数再去全部 assigns 一遍
日志里一般会有这个:
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手动去 assign 一下 meta 表即可,hbase:meta 表的 encoded name 是一个时间
另外 hbase:namespace 表没有 online 也会造成这个问题,同样需要我们去手动assign 一下
因为要求是所有 region 都 disabled, 那么解决办法可以是手动把没有 closed 的region 根据 case1 来解决。如果所有 region 都已经是 closed 状态了,那么我可以利用 setTableState 手动将表的状态设为 DISABLED。之后再 drop 都是安全的了。
其实 HBase-2.x 版本的运维思路很简单,因为使用了 procedure,集群出现 meta 跟 regionserver 不一致的状态是很少的,一般都是有 procedure 出问题了。那么我们主要就是看怎么解决这个有问题的 procedure。
如果是 table/namespace 级别的修改,因为设计到很多 region 的锁,如果需要 bypass 的话需要找到 root procedure 然后使用 bypass -or.
如果只是 region 级别的问题,则 bypass -o 即可。
bypass 之后检查 locks 的页面,看看是不是锁都释放了,如果没有锁了则根据需求进行 assign 或者 unassign,或者对 table 的属性进行还原。
参考链接:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。