hbase的一次故障恢复经历

使用hbase有一段时间了,期间经历过几次集群下线的情况,因为刚开始接触,对hbase集群的理解也不够深刻,每次宕机都直接把剩余的hbase进程kill掉,然后直接重新启动集群,一直没有注意到集群运行状态和重启的过程。

用了一段时间之后,我发现在master的管理界面上看到有个表的regions数目很多天都没有发生变化,一直都是8192,按照我的理解,每个region的file.maxSize设置的是128M,如果一直向hbase集群中存储数据的话,数据量增大的情况下,regions的数目是应该会增大的。刚开始想着是hbase集群的每个表的最大regions数目就是8192,担心新增加的数据会把原来存储的数据挤掉。

通过查询网上的资料,有些文章推荐把region的file.maxSize设置大一些,这样regions的数目应该会减少。然后我就参考网上的资料,把region的file.maxSize设置为1G,并且对regionserver的jvm的参数调整了一下。调整完成后重启集群之后,也没有观察集群的运行日志,运行不长时间后,集群中regionserver相继下线。查看regionserver的日志发现和zookeeper建立session之后,集群就下线。

2015-03-18 19:58:46,042 INFO [main-SendThread(zk1:2181)]zookeeper.ClientCnxn: Opening socket connection to server zk1:2181. Will not attempt to authenticate using SASL (unknown error) 
2015-03-18 19:58:46,055 INFO [main-SendThread(zk1:2181)] zookeeper.ClientCnxn: Socket connection established to zk1:2181, initiating session 
2015-03-18 19:58:46,084 INFO [main-SendThread(zk1:2181)] zookeeper.ClientCnxn: Session establishment complete on server zk1:2181, sessionid = 0x54b9b890d3c5456, negotiated timeout = 30000 

此时还没有意识到错误的严重性,因为日志里面也没有什么有用的提示,就又把集群重启,但是运行一段时间后,regionserver还是先后宕机,陆续在regionserver的日志里发现

hdfs.DFSClient: Failed to close file /hbase/data/default/table_name/299194d1c75af52afc4a520d46a4ca95/recovered.edits/0000000000000664372.temp
 File /hbase/data/default/table_name/299194d1c75af52afc4a520d46a4ca95/recovered.edits/0000000000000664372.temp could only be replicated to 0 nodes instead of minReplication (=1).  There are 4 datanode(s) running and no node(s) are excluded in this operation.

通过同事的指导和网上资料的查询,发现应该是有些文件已经成为垃圾文件,按照网上的说法运行了:

hbase hbck -fix

但是总是会卡住,提示有一个

some table inconsistent . region has a hole

需要新建一些 .regioninfo文件修复这个问题。由于不知道如果修改,后来有人建议运行

hbase hbck -repair

运行这个命令后,出现错误提示:

some region is still in transaction. region has not deploy

到这里才意识到有可能是有些region在hbase: meta表里面有记录,但是hdfs没有此region的存储路径,但是删除hbase:meta表里相应的数据后,运行

hbase hbck -repair

还是会报错,各种方法试过之后,我抱着重新安装hbase的心态试了最后一种办法。

因为我发现每次重启之后,hbase在hdfs的目录下面的相应的表的recovered.edits文件夹下总是有一些大小为0kb的.temp文件,然后regionserver里面报的错都是这些temp文件不能被关闭之类的错误。我就把所有的recovered.edits文件夹全部删除,然后把hbase的WALs文件夹下包含split的文件夹也都删除,接着把zookeeper的/hbase/splitWals文件夹的内容也都删除。

重启hbase集群后,集群能够正常启动,所有的region都按照hbase:meta中的信息重新assign。集群正常运行,但是有一个表中的部分region还是在in transaction中,没有在意这些数据,晚上的时候,同事跑程序用到这个表的时候告诉我这个表的一些region有些数据不存在。

发现 这些region正好是在master管理界面中发现的transaction的时候failed open的那几个表,应该是这些表的数据都没有了,但是在meta表里已经写了信息导致的错误,把hbase:meta表中相应的region的信息删除之后就会好了。

这次事故的初步认定主要原因是因为在系统运行的时候,改变了hbase的region.file.maxSize的属性,导致表中所以的数据需要重新assign,在此过程出现宕机引起的。在丢失一定数据的情况下,修复了hbase集群,还是值得庆幸的。

以后需要进一步理解hbase的存储结构和系统表的存储信息。理解宕机恢复的过程和一些补救措施。