大家好,我是向光。
在上一篇文章里,我们一起聊了排查FE问题的基本思路,并准备好了我们的"应急工具箱"(SOP清单)。
今天,咱们就不多说理论了,直接上干货:实战演练。
我从社区和日常支持中,整理了几个最高频的FE故障场景。你可以把这篇文章收藏起来,当成一份应急恢复手册。你可以先按顺序浏览下面的场景,看看是否符合你的问题;如果找不到完全匹配的,也别着急,可以直接跳到文末,那里有"终极解决方案"可以尝试。
希望这份手册能帮你做到"心中有数,手上有招"。
场景一:磁盘空间不足
这是一个很典型的"基础设施"问题,但确实经常遇到。
-
你会看到什么现象?
fe.log
里可能会出现com.sleepycat.je.DiskLimitException
这样的报错。je.info.0
日志里也可能会有Disk limit violation
(磁盘超限)的字样。
-
为什么会这样?
- 很简单,FE的元数据存储引擎(BDBJE)为了保护自己,设置了磁盘使用率的"警戒线"。当它发现磁盘空间快要用完时,就会禁止所有写入操作,避免把磁盘彻底写满导致更严重的问题。
-
怎么恢复?
- 这个最直接:清理磁盘。登录到FE所在的服务器,看看是哪些文件占用了大量空间,把不需要的文件删掉,腾出空间后FE通常会自动恢复。
场景二:集群时钟不同步
-
你会看到什么现象?
fe.log
里出现Clock delta ... exceeds max permissible delta
(时钟偏差超出最大允许值)的错误。
-
为什么会这样?
- 为了保证数据的一致性,FE集群的"决策小组"(所有Follower)要求成员之间的时间要基本一致,手表不能差太多。默认的容忍误差是5秒,如果哪个节点的系统时间跟"大部队"差得远了,它就会被认为是一个"不合群"的节点,从而主动退出。
-
怎么恢复?
- 强烈建议(一劳永逸的办法):给所有服务器配置NTP服务,让它们自动对时。
- 临时手动处理 :登录到出问题的服务器,用
date
命令手动把时间校准。
场景三:选举失败------无法达成多数派
-
你会看到什么现象?
fe.log
里可能会报Commit policy: SIMPLE_MAJORITY
相关的错误,抱怨没有足够多的节点响应。je.info.0
日志里,你可能会看到current group size
(当前组内成员数)比你预期的Follower数量要少。
-
为什么会这样?
- 就像我们上篇聊过的,Master的选举和元数据的写入,都需要超过一半的Follower节点投票同意。如果你有3个Follower,却只启动了1个,那么投票就无法正常进行了。
-
怎么恢复?
- 把足够多的Follower节点启动起来。比如3个Follower的集群,请确保至少启动了2个。
场景四:被操作系统"误杀"------OOM Killer
有时候,你会发现FE进程莫名其妙就消失了,但fe.log
里干干净净,没有任何错误。这时候,凶手可能不是FE自己,而是操作系统。
-
怎么排查?
- 登录到FE服务器,执行
dmesg -T | grep -i java
命令,查看操作系统日志。如果看到Out of Memory
或者Kill process
相关的字样,基本就可以断定,是操作系统的OOM Killer机制"出手"了。
- 登录到FE服务器,执行
-
为什么会这样?
- 当服务器的整体物理内存严重不足时,操作系统为了自保,会强制杀死内存占用最大的进程。不幸的是,作为Java进程的FE常常会成为这个"倒霉蛋"。
-
建议做法:
- 检查内存占用:看看服务器上是不是有其他"内存大户"抢占了资源。
- 避免混合部署:尽量不要将FE和BE部署在同一台机器上,避免资源竞争。
- 增加物理内存:如果资源确实紧张,这才是最终的解决方案。
场景五:内存"假性"过高
这个场景非常隐蔽,经常表现为FE Master毫无征兆地切换,甚至挂掉,然后新的Master很快又重蹈覆辙。
-
你会看到什么现象?
-
在监控图上,你会看到FE的堆内存使用量呈现非常典型的"锯齿状" 。内存会涨得很高,然后突然断崖式下跌(Full GC后),周而复始。
-
cite_start\]这种情况在**高频导入**的场景下尤其常见 \[cite: 1\]。
-
cite_start\]这其实不是典型的内存泄漏,而是垃圾回收器(GC)"干活太慢"了。Doris老版本默认使用的CMS回收器,在处理高频导入产生的大量临时对象(如LoadJob和事务信息)时,回收不够及时 \[cite: 1\]。
-
-
怎么恢复?
-
方案1(治标):配置Label保留参数
通过缩短已完成任务的标签保留时长,可以有效减少内存中的临时对象。在
fe.conf
中调整:ini[cite_start]label_keep_max_second = 21600 # 保留6小时 [cite: 1] [cite_start]streaming_label_keep_max_second = 21600 # 保留6小时 [cite: 1]
-
方案2(治本):修改GC算法为G1
G1回收器在控制GC暂停时间上比CMS更优秀,在新版本的Doris中也已成为默认。这是更推荐的优化方案。在
fe.conf
中修改JAVA_OPTS
:bash# [cite_start]这是一个示例,请将-Xmx8g调整为你环境的实际最大堆内存 [cite: 1] [cite_start]JAVA_OPTS="-Djavax.security.auth.useSubjectCredsOnly=false -Xmx8g -XX:+UnlockExperimentalVMOptions -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -XX:+PrintGCDateStamps -XX:+PrintGCDetails -Xloggc:$LOG_DIR/log/fe.gc.log.$DATE -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=50M -Dlog4j2.formatMsgNoLookups=true" [cite: 1]
提醒 :修改后,记得通过
jmap -heap <pid>
确认垃圾回收器已经成功变为G1。
-
场景六:启动卡在 "wait catalog to be ready"
这也是个高频问题,通常有两个原因:
-
原因1:IP地址"漂移"了
- FE启动时会识别本机的IP地址。如果你的机器上有多个网卡(比如同时有内网和外网IP),而你又没有在
fe.conf
里通过priority_network
配置项明确告诉Doris该用哪个,它就可能"选错"IP。这个错误的IP和它在集群里注册的IP不一致,导致它无法加入集群。 - 恢复方案 :检查并正确配置
priority_network
,然后重启FE。
- FE启动时会识别本机的IP地址。如果你的机器上有多个网卡(比如同时有内网和外网IP),而你又没有在
-
原因2:Follower"人数不够"
- 和场景三一样,集群无法选举出Master,新启动的FE节点不知道该听谁的,只能一直等待。
- 恢复方案:确保集群中多数Follower节点已经成功启动。
终极解决方案
⚠️ 警告 :以下操作涉及元数据的手动恢复,风险较高。在执行任何一步之前,请务必、务必、务必备份好你的
doris-meta
目录!
方案A:从健康的"兄弟"节点同步(集群里还有正常的FE时)
这是首选的恢复方案,安全又简单。前提是你的集群里至少还有一个健康的FE节点(Master或Follower)。
-
在出问题的FE节点 上,先停掉进程:
sh bin/stop_fe.sh
。 -
备份一下旧的元数据目录,以防万一:
mv doris-meta doris-meta_bak
。 -
新建一个空的元数据目录:
mkdir doris-meta
。 -
以
--helper
模式启动,让它像个新兵一样,从健康的老兵那里把所有数据同步过来:bashsh bin/start_fe.sh --helper <健康FE的IP>:<fe_edit_log_port> --daemon
方案B:手动指定Master进行恢复(所有FE都挂了)
这是最坏的情况,需要我们像做"心脏复苏"一样,手动救活一个节点,再由它来救活整个集群。
-
停止所有FE进程,如果配置了自动拉起,记得先关掉。
-
找到"希望的种子" :在所有FE节点的
doris-meta/image/
目录下,找到那个image.xxxxx
后缀数字最大的文件所在的节点。这个节点保存了最新的元数据快照,我们就选它作为恢复的"种子选手"。 -
以元数据恢复模式启动要恢复的节点" (慎用!可能会导致脑裂):
-
Doris 2.0.2及以上版本 :
bashsh bin/start_fe.sh --metadata_failure_recovery --daemon
-
Doris 2.0.2以下版本 : 先在
fe.conf
里加上metadata_failure_recovery=true
,再正常启动。
-
-
验证恢复 :启动成功后,连接上这个FE,执行
show frontends;
,你应该能看到自己是Master。简单查询几个表,确认数据是否正常。 -
"清理门户" :确认恢复成功后,将其他(已损坏的)FE节点从集群中剔除,避免它们捣乱:
sqlALTER SYSTEM DROP FOLLOWER "follower_host:edit_log_port";
-
回归正常模式(非常重要!) :
- 先停掉这个刚恢复的FE。
- 务必去掉恢复模式的配置 (删除
--metadata_failure_recovery
参数或注释掉metadata_failure_recovery=true
配置)。 - 正常启动它:
sh bin/start_fe.sh --daemon
。
-
重建集群 :现在你有了一个健康的Master节点,对于其他节点,就可以用方案A (
--helper
模式)的方式,让它们一个个地"归队"了。
如果这些方案还是没能解决你的问题,请不要再进行更多的冒险尝试。把上一篇文章SOP清单里收集到的所有信息,整理好,随时来社区里发帖提问。
别担心,我们一直都在。