遇到和修复的一些HBase的coredump问题

本文详细讨论了在HBase中遇到的几个导致coredump的问题,包括UI引用已释放内存、RPC monitor生命周期管理、checkAndMutate操作中的数据释放时机、RPC结束时的资源释放问题以及与大请求相关的coredump。针对这些问题,提出了相应的修复方案,并分享了在社区中跟踪的issue链接,帮助提升HBase集群的稳定性。

HBase coredump问题和修复

  1. UI展示RPC call参数时,引用了被释放的内存。
    UI造成coredump的原因有两个:
    RPC monitor的生命周期没有控制在call的生命周期之内;
    RPC monitor返回给http call克隆对象时,状态变量的克隆与数据变量的克隆不匹配。状态变量类似常量拷贝,而数据变量是浅拷贝。
    提交到社区的issue:
    https://issues.apache.org/jira/browse/HBASE-25981
    https://issues.apache.org/jira/browse/HBASE-26087
    这个bug的触发与运维脚本频繁抓取JMX的内容有关,特别是抓取RPC的处理状态信息。修复前全部集群特别是访问压力大的集群,会间隔几天因这个问题RS coredump重启。

  2. checkAndMutate在check阶段获取的数据被过早释放。
    问题的原因是checkAndMutate在check阶段会scan一部分数据。这部分数据用来做检查。但是scan出数据后,检查之前,scanner就被close,从而数据所在的堆外内存就被释放和复用。
    在读数据内容做check的时候,会因为读取数据内存地址的数据不符合预期而产生错误的判断或是coredump,而错误的判断会导致用户本应写入的数据写入失败。
    这个问题可以用UT稳定复现。解决方案也比较明确,即数据在使用之后释放。
    提到社区的issue:https://issues.apache.org/jira/browse/HBASE-26036
    这个bug主要影响的业务,他们存储的数据有正排属性,比如价格,库存等,所以几乎所有相关的表都会采用CAS写入的方式。

  3. RPC结束close scanner时,发现资源已被释放。
    问题的原因:
    table block进入bucket cache缓存后,block中记录的next block size如果发生变化,会由新的block替换原先缓存的block。
    而这个过程为了避免原先的block发生内存泄漏,替换前会将原block的内存直接释放,释放时并未考虑原block是否有rpc引用。
    提到社区的issue:https://issues.apache.org/jira/browse/HBASE-26155

  4. 与too big request同时出现的coredump问题。
    但是coredump时调用栈的位置每次都指在WrongRowIOException message的kv.toString()的位置,
    public Put add(Cell kv) throws IOException{
    byte [] family = CellUtil.cloneFamily(kv);
    List list = getCellList(family);
    //Checking that the row of the kv is the same as the put
    if (!CellUtil.matchingRow(kv, this.row)) {
    throw new WrongRowIOException("The row in " + kv.toString() +
    " doesn’t match the original one " + Bytes.toStringBinary(this.row));
    }
    list.add(kv);
    familyMap.put(family, list);
    return this;
    }
    没找到根本原因,改为如下代码,coredump就不复现了
    if (!CellUtil.matchingRow(kv, this.row)) {
    String errMsg = "The row in the put kv doesn’t match the original one " +
    Bytes.toStringBinary(this.row);
    LOG.error(errMsg);
    throw new WrongRowIOException(errMsg);
    }

  5. 文件损坏引起的coredump问题。
    经过日志分析发现多台RS因coredump重启,线程崩溃在解压包的位置。并且最终定位到崩溃与具体的2个region有关,这2个region只要开始做compaction,就会引起RS崩溃。
    整个集群300多台机器,2个region分别坏了1个文件,然后只要compaction选中损坏文件,就会引起region在的RS coredump重启,然后region移动到其他RS,短时间内又回coredump。也就是2个文件损坏,引起了全部RS的轮番重启!
    于是先更新代码将疑似有问题的region全部隔离,禁用疑似问题region的compact,保证服务的可用性。再经过PR检查,代码检查,文件检查。。。最终定位是与2个文件有关,这2个文件有数据损坏/异常,只要调用lzo native lib解压就必定会引起进程崩溃。
    使用HBase提供的shell工具读对应hfile的stat信息时,就会崩溃,确认了这个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值