Apache Doris 凭借强大的性能与高效的处理能力,成为众多企业数据处理的得力助手。然而,即使是性能卓越的数据库,也难免会遇到问题。其中,BE 节点宕机便是让不少 Doris 使用者头疼的难题。BE 一旦因程序 Bug(如内存越界、非法地址访问)或 Out Of Memory(OOM)等问题导致进程挂掉,将会对整个系统的稳定运行产生影响。今天,我们就深入探讨 Doris 的 BE 宕机问题定位与解决方法,让你在面对宕机时更加游刃有余!
当 BE 进程出现内存越界、非法地址访问等程序 Bug 时,进程会异常退出。此时,BE 进程会将当前的错误堆栈打印到be.out文件中(注意:不是be.INFO或be.WARNING)。通过仔细查看be.out中的错误堆栈,我们通常能够大致确定程序出错的位置。
(1)提取堆栈中的 Query ID
打开 BE 节点的日志文件 be.out(注意:非 be.INFO 或 be.WARNING),在崩溃堆栈信息中找到类似 58a4a56ad38f4f57-b958cc1374948c85 的字符串,这就是触发崩溃的查询 ID(Query ID)。示例:堆栈中可能出现 Query: 58a4a56ad38f4f57-b958cc1374948c85 这样的标记。
(2)检索 FE 审计日志定位问题 SQL
BE Core 通常由具体的 SQL 语句触发,需通过 Query ID 反向查找对应的 SQL:
fe/log/fe.audit.log 中搜索该 Query ID:grep "58a4a56ad38f4f57-b958cc1374948c85" fe/log/fe.audit.log
(3)临时处理与信息收集
找到问题 SQL 后,可先采取临时措施减少影响:
be.out 日志(含core堆栈);DESCRIBE 表名 或者 SHOW CREATE TABLE table_name 获取);(4)获取 Core Dump 文件辅助
当问题难以复现或堆栈信息不足时,需要通过 Core Dump 文件(进程core时的内存快照)深入分析。以下是生成和获取 Core Dump 的完整流程:
执行 ulimit -a 命令,查看 core file size 配置,若显示 core file size (blocks, -c) 0,表示未开启 Core Dump,需手动启用。
在启动 BE 时,通过 ulimit 命令设置无限大的 Core 文件大小:
# 临时生效:开启 Core Dump 并启动 BE
ulimit -c unlimited -n 65536 && sh start_be.sh --daemon
启动后,通过以下命令验证配置是否生效({be_pid} 替换为 BE 进程 ID):
cat /proc/{be_pid}/limits | grep "core file size"
若输出 core file size unlimited,表示配置成功。
BE 崩溃后,Core 文件的默认路径由系统配置决定:执行 cat /proc/sys/kernel/core_pattern 查看路径规则,例如输出 /tmp/core_%t_%e_%p,表示文件生成在 /tmp 目录,命名格式为 core_时间_进程名_进程ID。进入对应目录,找到以 core 开头且包含 doris_be 的文件,即为所需的 Core Dump 文件。
Core 文件通常较大,建议压缩后上传至对象存储(如 S3、OSS),并将下载链接提供给社区。压缩命令示例:
# 压缩 Core 文件(保留原始权限)
tar -zcvf core_doris_be.tar.gz /tmp/core_xxxx_doris_be_xxxx
不过,这类问题一般较为复杂,可能难以自行解决。一旦在be.out中发现错误堆栈,建议及时前往微信群、github discussion 或 社区论坛寻求帮助,并附上对应的错误堆栈,以便社区人员快速排查问题。
如果be.out中没有堆栈信息,那么大概率是因为 OOM 被系统强制 kill 掉了。这时,我们可以使用dmesg -T命令查看 linux 系统日志。如果日志中出现类似Memory cgroup out of memory: Kill process 7187 (doris_be) score 1007 or sacrifice child的记录,就说明是 OOM 导致 BE 进程被 kill。内存问题的原因可能是多方面的,比如大查询、导入、compaction 等操作都可能引发 OOM。或者可以看下是否有FE和BE的混合部署,或者有其他的程序和BE混合部署,导致的资源争抢。
升级后启动 be 时,如果出现Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/doris/udf/JniUtil ,并由java.lang.ClassNotFoundException: org/apache/doris/udf/JniUtil 引起,这是因为缺少 Java UDF 函数依赖包。此时,需要从官网下载apache-doris-java-udf-jar-with-dependencies-1.2.0的 Java UDF 函数依赖包,将其放到 BE 安装目录下的 lib 目录,然后重新启动 BE,问题即可解决。(很老的版本了,不推荐使用,方式仅供参考)
★推荐使用当前最新稳定版本,有很多问题已经修复了
当升级后启动 BE 出现Failed to initialize JNI: Failed to find the library ``libjvm.so错误时,原因是系统未设置 JAVA_HOME 环境变量。解决方法很简单,在be.conf中设置 JAVA_HOME 环境变量,或者在start_be.sh启动脚本第一行添加export JAVA_HOME=your_java_home_path(推荐还是在be.conf里面设置JAVA_HOME),随后重新启动 BE 节点,就能顺利解决问题。 (很老的版本了,不推荐使用,方式仅供参考)
★推荐使用当前最新稳定版本,有很多问题已经修复了
在 1.1.2 版本中 (很老的版本了,不推荐使用,方式仅供参考),由于向量化的特性,相对以前版本内存使用量增加。如果遇到 BE 内存飙升的问题,可以适当修改 BE 的以下几个参数,减少缓存的使用:
chunk_reserved_bytes_limit=2%buffer_pool_limit=2%storage_page_cache_limit=4%max_base_compaction_threads=2通过合理调整这些参数,能够有效控制内存使用,避免因内存飙升导致的宕机问题。
★推荐使用当前最新稳定版本,有很多问题已经修复了
如果 BE 重启后无法启动,首先可以使用free -h命令查看内存情况,判断是否是因为内存不足导致的启动失败。根据内存状况,采取相应的措施,如释放内存或增加内存资源等。
当从 1.2.6 升级到 2.0.0 后,BE 和 FE 都无法启动,报错ulimit -n 65536 ,此时查看ulimit -n如果是 65535 ,将其改成 65536 即可解决问题。 (很老的版本了,不推荐使用,方式仅供参考)
★推荐使用当前最新稳定版本,有很多问题已经修复了
对于新加入的节点 BE 无法启动的已知问题,可以尝试升级到 2.0.0/2.0.1 版本。 (很老的版本了,不推荐使用,方式仅供参考)
若问题仍未解决,可以执行echo 1 > /proc/sys/vm/overcommit_memory ,或许能让 BE 顺利启动。
★推荐使用当前最新稳定版本,有很多问题已经修复了
为了减小 BE 宕机问题对线上业务造成的影响,我们可以采取一些预防措施:
面对 Doris 的 BE 节点宕机问题,虽然情况复杂多样,但只要我们掌握了正确的定位方法和解决思路,结合社区的帮助,就能够快速解决问题。希望这篇文章能成为你在 Doris 使用过程中的得力助手,让你的数据处理之路更加顺畅!如果你在实际操作中遇到任何问题,欢迎在留言区交流分享,也别忘了转发给其他有需要的小伙伴哦!