记录HBase手动删除Hadoop备份(archive)文件后,引发Hbase写入数据出错等一系列问题处理

网友投稿 1071 2022-05-28

由于需要规范HBase数据表命名,对测试环境的数据进行了重命名操作。

停掉所有服务后执行下面改名操作

# 禁用活跃用户表 disable 'DC_XXL:ACTIVE_USERS' # 创建快照 snapshot 'DC_XXL:ACTIVE_USERS', 'tony_snapshot' # 克隆快照为新的表(使用新名称) clone_snapshot 'tony_snapshot', 'DC_XXL:ACTIVE_USERS_LOG' # 按命名空间查看克隆的表是否存在 list_namespace_tables 'DC_XXL' # 查看快照 list_snapshots # 删除快照 delete_snapshot 'tony_snapshot' # 查看旧表详情 desc 'DC_XXL:ACTIVE_USERS'  # 查看新表详情,比较两个表是否一致 desc 'DC_XXL:ACTIVE_USERS_LOG' # 禁用旧表 disable "DC_XXL:ACTIVE_USERS" # 删除旧表 drop 'DC_XXL:ACTIVE_USERS'

然后重新启动测试服务。

操作完后发现测试服务器的存储空间不足,想要删除一些数据占用,使用df -h查看各服务器的磁盘空间占用情况,发现Hadoop存储目录已占用了90%以上的空间,所以顺便使用命令查看一下Hadoop的空间使用情况

# 查看hadoop根目录各文件夹占用空间 hadoop dfs -du -h /# 查看hbase占用空间 hadoop dfs -du -h /hbase

通过命令一层层查看,可以发现主要是hbase占用了存储,而刚刚执行前面的命令操作后,在hbase目录下面发现主要存储空间占用的目录有:data(项目数据表存储目录)与 archive(存档目录),而archive目录一般存储的是备份用的,理论上来说是可以直接删除,所以网上查了一些资料说没问题后,就直接使用 rmr(hadoop dfs -rmr /hbase/archive/data/DC_XXL/ACTIVE_USERS)命令将里面的存档文件删除了,没想到引发了一系列的故障......

记录HBase手动删除Hadoop备份(archive)文件后,引发Hbase写入数据出错等一系列问题处理

过了一会继续查看磁盘空间占用,发现磁盘使用在持续快速增长,很快有的服务器已达到100%

使用 hadoop dfs -du -h /hbase 查看发现,MasterProcWALs 目录突然间多了几十G,经查询这是HBase状态日志目录,进去将它们全部删除,发现磁盘占用还是100%没有变化

继续排查,使用 hadoop dfs -du -h / 发现,原来直接使用rmr删除后,hadoop会将文件移动到 /user/root/.Trash/Current/hbase/ 这个垃圾站目录下面

而这时在查看服务运行日志时,也发现了大量的IO异常

Hbase_thrift.IOError: IOError(message=b'org.apache.hadoop.hbase.client.RetriesExhaustedException: Failed after attempts=16, exceptions: Mon Jul 06 20:01:52 CST 2020, RpcRetryingCaller{globalStartTime=1594036912662, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.NotServingRegionException: org.apache.hadoop.hbase.NotServingRegionException: DC_XXL:ACTIVE_USERS_LOG,4,1593765189585.73133efd2d876b7f7edabc3ab6709cae. is not online on slave2,16020,1594035938293     at org.apache.hadoop.hbase.regionserver.HRegionServer.getRegionByEncodedName(HRegionServer.java:3249)     at org.apache.hadoop.hbase.regionserver.HRegionServer.getRegion(HRegionServer.java:3226)     at org.apache.hadoop.hbase.regionserver.RSRpcServices.getRegion(RSRpcServices.java:1414)     at org.apache.hadoop.hbase.regionserver.RSRpcServices.get(RSRpcServices.java:2429) ......

从日志中可以看到,是由于写入数据时,所要写入的region下线所引发的IO异常,在浏览器中进入HBase web管理器(http://master:16010),可以看到所有节点都是在线的,拉到 Tables 位置,查看对应的数据表状态,会发现该表的Other Regions标识了出现问题的数量。

经过查找资料与思考分析,执行快照操作,HBase会在HDFS中创建一个和unix硬链接相同的存储文件,而执行镜像克隆操作时,实际上新表与旧表共用相同的数据块,新表只在data目录创建新表文件,但并不会复制region,只是通过linkfile定位旧表文件地址。当删除旧表以后,HBase应该会将旧表数据移动到 archive 目录下面,只有在新数据写入并提交compact时,才会数据迁移到新表文件中。所以执行快照和克隆操作是秒级,几百G的数据执行命令后立马结果就出来了。

而我直接删除了备份文件,数据并没有迁移完,导致某些region直接丢失了。

随后将回收站的文件重新移动到 archive 目录下面,使用 hbck 命令修复,发现修复失败,由于是测试数据只需要从kafka中生成最近一周的就可以了,且旧数据占用太多空间需要清理,所以没有继续研究修复,直接将它清除,决定创建新表运行相关服务批量重新生成测试数据。

进入hbase shell中,执行命令

disable 'DC_XXL:ACTIVE_USERS_LOG'

发现命令卡死,直到超时才退出,发现数据表禁用不了也删除不了。

登录 zookeeper ,删除对应的数据

# 连接zookeeper服务/usr/local/zookeeper/bin/zkCli.sh -server master:2181# 查看hbase数据表ls /hbase/table # 删除数据表 rmr /hbase/table/DC_XXL:ACTIVE_USERS_LOG

删除Hadoop存储的数据

# 查看hadoop的dfs文件 hadoop dfs -du -h /hbase/data/DC_XXL # 删除文件 hadoop dfs -rmr /hbase/data/DC_XXL/ACTIVE_USERS_LOG # 清除垃圾站文件 hadoop dfs -rmr /user/root/.Trash/Current/hbase/data/DC_XXL/ACTIVE_USERS_LOG

再次进入hbase shell,输入list已查看不到数据表了,输入命令创建新表

create 'DC_XXL:ACTIVE_USERS_LOG',{NAME=>'c',COMPRESSION=>'lz4',VERSIONS=>1},SPLITS=>['2','4','6','9']

这时直接提示:ERROR: Table already exists 异常信息,经过排查发现原来meta表还存储了数据表以及对应的region信息,需要一一清除干净才行

# 扫描meta表,查找当前数据表相关记录 scan 'hbase:meta',{STARTROW=>'DC_XXL:ACTIVE_USERS_LOG',ENDROW=>'DC_XXL:ACTIVE_USERS_LO~'}# 删除表记录命令(这一条命令必须在shell执行,脚本可能删不干净) deleteall 'hbase:meta','DC_XXL:ACTIVE_USERS_LOG'# 记录量少的话可以手动一条条删除 ......

批量删除 hbase:meta表数据表相关记录脚本

import happybase connect = happybase.Connection(host='master', port=9090, timeout=300000, autoconnect=True, compat='0.98', transport='buffered', protocol='binary') def scan(table, row_prefix=None, columns=None):     t = happybase.Table(table, connect)     scan = t.scan(row_prefix=row_prefix, columns=columns)     data = []     for key, value in scan:         result = {row.decode().replace('c:', '').lower(): value[row].decode() for row in value}         result['pk'] = key.decode()         data.append(result)     return data def delete(table, rowkey):     t = happybase.Table(table, connect)     t.delete(rowkey) if __name__ == '__main__':     columns = ['info:server']     row_prefix = 'DC_XXL:ACTIVE_USERS_LOG'.encode()     result = scan('hbase:meta', row_prefix, columns=columns)     print(len(result))     for row in result:         pk = row.get('pk')         print(pk)         delete('hbase:meta', pk)

脚本执行成功后,需要在shell中执行前面的scan语句检查一次,看看是否全部都删除干净

然后重启hbase服务,进入shell中执行创建数据表语句,这次就可以执行成功了(不重启hbase服务,可能会影响数据表状态,然后产生大量的异常状态记录占用存储空间)

在这次事件中出现了几次错误操作,导致本次故障。由于之前也试过多次改名,并没有出现问题,导致本次操作时过于轻心。没有深入了解快照和克隆快照的底层原理,而网上查到的 archive 相关文章在不了解其背景的情况下,就以为可以直接删除文件,导致异常的发生。当存储空间不足时,没有全面排查了解存储空间丢失原因,就进行一些处理,导致直接恢复删除文件并没有修复问题。而对hbase一些命令的底层运行原理不了解,也造成一些操作上的误判。好在这只是测试环境,数据丢失影响不大,接下来需要深入研究hbase各方面的运行机制,避免这种低级问题的发生。

hbase 大数据

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:化鲲为鹏,我有话说*基于鲲鹏弹性云服务器搭whoami
下一篇:Python 系统资源信息获取工具,你用过没?
相关文章