前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HBase运维 | HBase宕机恢复案例一则

HBase运维 | HBase宕机恢复案例一则

作者头像
大数据技术架构
修改2020-06-18 16:52:00
9620
修改2020-06-18 16:52:00
举报

下图为master的日志记录:

从上图可以看到zk中/Hbase/replication/rs的节点信息无法获取,然后我们立马去检查zk日志发现zk已经全部断联而且已经瘫痪,截图如下:

上网一番查找发现java.nio.channels.CancelledKeyException是zk 3.4.10之前版本的bug,笔者使用的正是3.4.8,此bug在3.4.10已修复。

至此,zk宕机原因找到了,将zk节点全部重启然后重启HBase,核心问题来了,遇到了一个老兄弟,java.io.IOException: Packet len6075380 is out of range ! master退出,启动失败。

按照以前的经验,去zkCli.sh修改了-Djute.maxbuffer=41943040的配置,第一次修改直接将值翻倍后重启还是报同样的错误,多次翻倍终无效果;一气之下直接将值多加了两个00,变成了之前的上千倍,数值达到了百亿级别,重启依然无效。然后决定删除zk中的HBase节点,rmr /habse竟然报错了,更巧的是同样的java.io.IOException: Packet len6075380 is out of range ! 好难受啊!!!

折腾了这么半天没有思路了,突然运维的同事提醒我说我改的值应该已经超出zk的限制了,估计都不会生效,听了这么一个提醒,心里窃喜的很啊,马上一番操作下载zk源码看看到底怎么回事。

void readLength() throws IOException {
    int len = incomingBuffer.getInt();
    if (len < 0 || len >= packetLen) {
        throw new IOException("Packet len" + len + " is out of range!");
    }
    incomingBuffer = ByteBuffer.allocate(len);
}

packetLen为配置文件的值,而incomingBuffer为HBase启动报错的值:6075380 > 4194304(默认值),所以抛出上述异常:

private int packetLen = ZKClientConfig.CLIENT_MAX_PACKET_LENGTH_DEFAULT;

查看源码发现zk初始化的时候会去加载配置文件的·jute.maxbuffer·值,如果值的大小不为空就采用此值,如果为空就用默认值,上图红色部分为默认是大小4M=4194304,但还有一个前提就是配置的值必须是int范围内的值,否则Integer.parseInt(value.trim())方法会报错。

    try {
        packetLen = clientConfig.getInt(ZKConfig.JUTE_MAXBUFFER,
                ZKClientConfig.CLIENT_MAX_PACKET_LENGTH_DEFAULT);
        LOG.info("{} value is {} Bytes", ZKConfig.JUTE_MAXBUFFER,
                packetLen);
    } catch (NumberFormatException e) {
        String msg = MessageFormat.format(
                "Configured value {0} for property {1} can not be parsed to int",
                clientConfig.getProperty(ZKConfig.JUTE_MAXBUFFER),
                ZKConfig.JUTE_MAXBUFFER);
        LOG.error(msg);
        throw new IOException(msg);
    }
}

public int getInt(String key, int defaultValue) {
    String value = getProperty(key);
    if (value != null) {
        return Integer.parseInt(value.trim());
    }
    return defaultValue;
}

而笔者最后修改的值为百亿,已然超出了int范围,所以是无效的配置。至此,原因找到了,立马改成了10M的配置重新启动zk并删除/hbase节点成功。

但是,调整此参数始终治标不治本,结合本司集群中的数据量(200亿+)和region数量(10W+)考虑,master重启是一项浩大的工程,因为重启会导致region的状态变更,而变更的中间状态是在zk节点维护,当大量的region需要分配,而分配速度又很慢就会导致zk中/hbase/下的部分节点存储数据量太大从而导致异常。

所以我们需要从两个方面入手: 1、尽量合理的划分region。 2、提高处理region分配的线程数。修改配置项hbase.assignment.threads.max,该配置默认值为30。

<property>
        <name>hbase.assignment.threads.max</name>
        <value>100</value>
</property>

然后重启HBase,顺利启动。

微信扫一扫,关注我
微信扫一扫,关注我
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大数据技术架构 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档