当前位置: 首页 > news >正文

Doris集群启停脚本设计与实践指南

1. Doris集群启停脚本设计基础

第一次接触Doris集群运维时,我被复杂的组件依赖关系搞得手忙脚乱。记得有次半夜处理故障,因为没按正确顺序启停服务,导致元数据损坏花了三小时恢复。这个惨痛教训让我意识到:规范的启停脚本不是可选项,而是生产环境的必需品

Doris集群包含三类核心组件,它们的启动顺序就像盖房子:

  • FE(Frontend):相当于建筑图纸,必须第一个就位。它管理元数据、协调查询,如果FE没启动,其他组件连"门牌号"都找不到。
  • BE(Backend):相当于施工队,图纸到位后才能开工。负责实际的数据存储和计算,启动后会主动向FE"报到"。
  • Broker:像材料运输车,等主体结构完工后才需要进场。专门处理HDFS/S3等外部存储的读写。
# 正确启动顺序示例(单节点) ./bin/start_fe.sh --daemon # 先启动FE sleep 30 # 等待FE初始化完成 ./bin/start_be.sh --daemon # 再启动BE ./bin/start_broker.sh --daemon # 最后启动Broker

关闭时则要逆向操作,就像拆房子要先清空家具:

./bin/stop_broker.sh # 先停Broker ./bin/stop_be.sh # 再停BE ./bin/stop_fe.sh # 最后停FE

我曾遇到过BE未完全停止就强制杀进程,导致数据文件损坏的情况。后来在脚本中加入状态检查逻辑,问题再没出现过。这印证了一个真理:集群管理没有侥幸,严谨的流程设计才是王道

2. 生产级启停脚本开发实战

去年为某电商设计集群脚本时,他们提出个需求:要在3分钟内完成20个节点的滚动重启。这促使我开发出现在这套经过实战检验的脚本框架,核心思路是**"状态感知+并行控制"**。

2.1 集群角色规划示例

先看一个典型的三节点部署方案:

节点FE角色BEBroker
node1Leader
node2Follower
node3Observer

对应的脚本变量配置:

#!/bin/bash # 集群节点列表 SERVERS="node1 node2 node3" # FE Leader节点(必须配置正确!) MASTER="node1" # Doris安装路径 DORIS_HOME="/opt/doris-2.0.4"

2.2 启动脚本关键逻辑分解

FE启动函数是精髓所在,需要区分Leader和Follower/Observer:

start_fe() { for SERVER in $SERVERS; do echo "启动 $SERVER 上的FE..." if [ "$SERVER" = "$MASTER" ]; then # Leader节点独立启动 ssh $SERVER "$DORIS_HOME/bin/start_fe.sh --daemon" else # 其他节点通过--helper指定Leader地址 ssh $SERVER "$DORIS_HOME/bin/start_fe.sh \ --helper $MASTER:9010 --daemon" fi # 等待10秒确保进程就绪 sleep 10 ssh $SERVER "jps -m | grep PaloFe" || echo "警告:FE进程未启动!" done }

BE启动相对简单,但建议增加进程检查:

start_be() { for SERVER in $SERVERS; do echo "启动 $SERVER 上的BE..." ssh $SERVER "$DORIS_HOME/be/bin/start_be.sh --daemon" # 检查BE进程是否注册成功 ssh $MASTER "mysql -uroot -P9030 -h127.0.0.1 -e \ 'SHOW BACKENDS\G' | grep $SERVER" done }

2.3 关闭脚本的注意事项

关闭Broker时最容易忽略连接检查:

stop_broker() { for SERVER in $SERVERS; do echo "关闭 $SERVER 上的Broker..." # 先检查是否有活跃连接 conn_count=$(ssh $MASTER "mysql -uroot -P9030 -h127.0.0.1 -Nse \ 'SHOW PROC "/brokers"\G' | grep -A 1 $SERVER | grep 'Active'") [ "$conn_count" -gt 0 ] && echo "存在活跃连接,请先处理!" && exit 1 ssh $SERVER "$DORIS_HOME/apache_hdfs_broker/bin/stop_broker.sh" done }

完整脚本应该包含超时控制重试机制。比如BE停止时如果30秒内未退出,就强制kill:

stop_be() { for SERVER in $SERVERS; do echo "关闭 $SERVER 上的BE..." ssh $SERVER "$DORIS_HOME/be/bin/stop_be.sh" # 等待优雅退出 timeout=30 while [ $timeout -gt 0 ]; do if ! ssh $SERVER "pgrep -f palo_be"; then break fi sleep 1 ((timeout--)) done # 强制终止 [ $timeout -eq 0 ] && \ ssh $SERVER "pkill -9 -f palo_be" && \ echo "已强制终止BE进程" done }

3. 高级功能与避坑指南

3.1 状态检查增强版

基础的jps检查有时会漏报,我改良后的检查方案包含三层验证:

  1. 进程是否存在
  2. 端口是否监听
  3. 集群状态是否健康
check_fe_status() { local fe_ip=$1 local fe_query_port=$2 # 第一层:进程检查 if ! ssh $fe_ip "jps -m | grep -q PaloFe"; then return 1 fi # 第二层:端口检查 if ! ssh $fe_ip "netstat -tlnp | grep -q :$fe_query_port"; then return 2 fi # 第三层:元数据健康检查 local status=$(ssh $fe_ip \ "mysql -uroot -P$fe_query_port -h127.0.0.1 -Nse \ 'SHOW FRONTENDS\G' | grep 'Alive' | awk '{print \$2}'") [ "$status" = "true" ] && return 0 || return 3 }

3.2 版本兼容性处理

升级Doris版本时,遇到过旧脚本不兼容的问题。现在我的脚本会自动识别版本并调整参数:

# 获取Doris版本 DORIS_VERSION=$(grep 'version' $DORIS_HOME/fe/fe.conf | cut -d'=' -f2) # 版本特定逻辑 case $DORIS_VERSION in 1.*) BE_START_CMD="$DORIS_HOME/be/bin/start_be.sh --daemon" ;; 2.*) BE_START_CMD="$DORIS_HOME/be/bin/start_be.sh --daemon --with-broker" ;; *) echo "不支持的版本: $DORIS_VERSION" exit 1 ;; esac

3.3 日志收集与告警

生产环境必须要有完善的监控,这个日志收集函数帮我定位过无数问题:

collect_logs() { local log_dir="/tmp/doris_logs_$(date +%Y%m%d_%H%M%S)" mkdir -p $log_dir for SERVER in $SERVERS; do echo "收集 $SERVER 日志..." ssh $SERVER "tar czf - \ $DORIS_HOME/fe/log/* \ $DORIS_HOME/be/log/* \ 2>/dev/null" > "$log_dir/${SERVER}_logs.tar.gz" # 提取关键错误信息 ssh $SERVER "grep -E 'ERROR|WARN|FATAL' \ $DORIS_HOME/fe/log/fe.log \ $DORIS_HOME/be/log/be.INFO" > "$log_dir/${SERVER}_errors.log" done # 发送邮件告警(需配置mailx) [ -s "$log_dir/*_errors.log" ] && \ mailx -s "Doris集群异常告警" admin@example.com < \ "$log_dir/error_summary.log" }

4. 典型问题排查手册

4.1 FE启动失败常见原因

案例:某次扩容后FE无法启动,日志显示"元数据损坏"

  • 根因:磁盘写满导致元数据文件不完整
  • 解决方案
    1. 清理磁盘空间
    2. 使用--metadata_failure_recovery=true参数启动
    3. 从健康节点拷贝元数据备份

预防措施

# 在crontab中添加磁盘检查 */5 * * * * df -h | awk '$5 > 90 {print "警报:磁盘使用超过90%"}'

4.2 BE注册失败处理流程

当BE无法注册到FE时,按这个顺序检查:

  1. 网络连通性(ping/telnet)
  2. FE的9030端口是否开放
  3. BE的heartbeat_service_port配置是否正确
  4. FE日志中是否有拒绝注册的记录

我常用的诊断命令:

# 检查BE与FE网络 telnet $FE_IP 9030 # 查看BE配置 grep 'heartbeat_service_port' $DORIS_HOME/be/conf/be.conf # 实时监控FE日志 tail -f $DORIS_HOME/fe/log/fe.log | grep 'register'

4.3 Broker连接外部存储超时

典型报错:"failed to access hdfs://namenode:8020"

  • 排查步骤
    1. 手动执行hdfs命令测试连通性
    2. 检查core-site.xml配置是否正确
    3. 验证Kerberos认证(如果启用)

诊断脚本片段

check_hdfs_connection() { local hdfs_path=$1 ssh $SERVER "$DORIS_HOME/apache_hdfs_broker/bin/hdfs dfs \ -ls $hdfs_path >/dev/null 2>&1" if [ $? -ne 0 ]; then echo "HDFS连接测试失败!" echo "请检查:" echo "1. 网络防火墙设置" echo "2. $DORIS_HOME/apache_hdfs_broker/conf/core-site.xml" echo "3. Kerberos keytab文件" return 1 fi return 0 }

5. 性能优化实践

5.1 并行启动优化

默认串行启动在大型集群中效率低下,这个改进方案将启动时间从15分钟缩短到2分钟:

parallel_start() { local workers=5 # 并发度控制 # 启动所有FE for SERVER in $SERVERS; do ((i=i%workers)); ((i++==0)) && wait start_single_fe $SERVER & done wait # 启动所有BE(类似实现) ... } start_single_fe() { local server=$1 # 具体启动逻辑 ssh $server "$DORIS_HOME/fe/bin/start_fe.sh --daemon" }

5.2 资源预热技巧

冷启动后立即执行查询会导致性能下降,我的解决方案是在脚本最后添加预热逻辑:

warm_up() { echo "执行集群预热..." ssh $MASTER "mysql -uroot -P9030 -h127.0.0.1 -e ' SELECT COUNT(*) FROM system_metrics.schema_meta; SELECT COUNT(*) FROM information_schema.tables; SELECT * FROM backends() ORDER BY last_heartbeat DESC;'" }

5.3 自适应等待策略

固定sleep时间在不同硬件环境下表现不稳定,改用动态检测更可靠:

wait_fe_ready() { local fe_ip=$1 local max_retry=30 for ((i=1; i<=$max_retry; i++)); do if ssh $fe_ip "curl -s http://localhost:8030/api/bootstrap" | \ grep -q "OK"; then echo "FE已就绪" return 0 fi sleep 2 done echo "等待FE启动超时!" return 1 }

在金融级生产环境运行三年多来,这套脚本体系经历了数十次版本迭代。最关键的体会是:好的运维工具不仅要正确执行操作,更要能预防问题、快速定位故障。建议每次遇到异常情况后,都把解决方案沉淀到脚本中,久而久之就会形成强大的自动化运维体系。

http://www.jsqmd.com/news/628470/

相关文章:

  • Local SDXL-Turbo 环境配置与快速启动,5分钟搞定一切
  • 从特斯拉AEB误触发事件看SOTIF标准:如何避免自动驾驶系统‘过度反应‘?
  • 3步打造抖音批量下载神器:从零到精通的高效自动化采集方案
  • 终极指南:如何免费解锁Cursor Pro完整功能,告别AI编程限制
  • 未来已来:WiFi信号如何通过AI实现无接触人体感知的三大突破
  • Proteus与Keil联调实战:从安装到调试的完整指南
  • 深入解析字节序与比特序:大小端原理及网络编程实战
  • SDXL-Turbo避坑指南:为什么提示词太长图就崩了?一文讲清
  • 基于Phi-4-mini-reasoning的智能数据分析:实现类VLOOKUP的跨表信息匹配
  • 5分钟终极指南:TegraRcmGUI让你轻松玩转Switch注入
  • GD32F303新手避坑指南:MDK工程创建与时钟配置全流程(Keil5实测)
  • 通义千问1.5-1.8B-Chat-GPTQ-Int4 Java面试备战:八股文解析与模拟面试
  • AIGlasses_for_navigation内容生成:AIGC技术辅助创作导航解说与报告
  • FPGA与高速ADC的JESD204B接口实战:从配置到数据采集
  • 企业级报表工具润乾报表的安全审计:从dataSphereServlet接口看文件上传风险
  • 3分钟掌握MouseJiggler:高效解决Windows屏幕锁定的专业方案
  • Bidili Generator实操手册:生成图EXIF信息嵌入+版权水印自动添加方案
  • SteamAutoCrack:3步实现Steam游戏离线自由运行的终极指南
  • Pixel Script Temple 从零开始学AI绘画:人工智能原理与像素生成入门
  • GLM-4-9B-Chat-1M一键部署教程:基于vLLM的高效推理实践
  • 基于STM32的张大头闭环步进电机控制实战指南
  • 智能社交关系管理:WechatRealFriends微信好友检测技术解析
  • ViGEmBus:打破游戏控制器兼容壁垒的Windows内核级解决方案
  • ConvNeXt 系列改进:添加门控通道变换(GCT),轻量化涨点(仅增加 0.1M 参数)
  • Cogito-V1-Preview-Llama-3B Anaconda虚拟环境配置与模型开发隔离
  • Figma中文插件终极指南:3分钟让Figma界面变中文的完整教程
  • EEManager:嵌入式EEPROM磨损抑制与延迟写入管理库
  • 如何用一套键鼠控制多台电脑?Lan Mouse跨设备共享终极指南
  • Translumo:打破语言障碍的实时屏幕翻译神器,三步开启无障碍游戏与观影体验
  • 深入解析AD/DA转换与运放电路:从原理到实战应用