1. 扩容与缩容的本质:先想清楚你要解决什么问题
在聊Doris集群扩缩容之前,我先把话说在前面:这两件事很多人当成"加机器/减机器"的纯运维操作,实际上远没那么简单。扩缩容的背后,是存储容量、查询性能、副本分布、数据均衡、故障域设计这几件事的联动调整。如果不理解底层逻辑,直接照着文档敲命令,大概率会在扩容后遇到查询变慢、磁盘倾斜、副本长期不均衡甚至数据迁移卡死的问题。
Doris的架构大家应该不陌生:前端FE节点负责元数据管理和查询解析,后端BE节点负责数据存储和查询执行。任何一个做过Doris生产运维的人都会告诉你,增删BE节点是家常便饭,而增删FE节点则相对低频,但两者的操作思路完全不同。扩容BE节点时,新节点加入集群后会自动从其他BE节点拉取数据副本,这个过程由Doris内部的负载均衡机制驱动;缩容BE节点时,需要先把该节点上的数据副本迁移到其他节点,才能安全下线。
这套机制听起来挺简单,但实际落地时需要考虑的点非常多。你扩多少个节点、什么规格、加完什么时候数据均衡完、均衡期间查询有没有影响、缩容的时候哪个节点先退、退完磁盘够不够放迁过来的数据,这些不提前规划好,后面全是坑。
所以我这篇不是把官方文档翻译一遍,而是把我自己在生产环境里反复操练过的扩容和缩容经验完整梳理出来,把每一步为什么要这么做的原因讲清楚,让看完的人能直接复现。
2. 动手前必须做的盘点:节点角色、副本数与容量规划
2.1 先搞清楚集群当前的健康状态
不管你打算扩容还是缩容,第一步永远不是执行命令,而是把集群的底数摸清楚。我自己习惯先执行一组信息收集操作,把当前状态存档,这样后面无论是做对比还是排查问题,都有据可依。
需要收集的信息至少包括以下几类:
-- 查看当前集群所有BE节点状态 SHOW BACKENDS\G; -- 查看当前FE节点状态 SHOW FRONTENDS\G; -- 查看当前所有数据库表的副本分布情况 SHOW TABLET FROM 你的数据库表名\G;在看BE节点状态时,重点看几个字段:Alive是否为true,TabletNum是否分布均匀,DataUsedCapacity是否合理。如果某个BE节点的TabletNum比其他节点高出非常多,说明集群此前可能经历过不完整的缩容或扩容,数据均衡状态本身就不好,这时候直接再加节点,均衡压力会更大。
还要确认当前集群的副本数。Doris默认副本数为3,副本数决定了集群最多能容忍几台BE节点同时宕机。如果副本数是1,扩容和缩容时要格外谨慎,任何一次误操作都可能直接丢数据。查看副本数可以通过下面这条SQL:
-- 查看某张表的副本数设置 SHOW CREATE TABLE 你的表名\G;最省事的方法是在Doris的网页控制台或者用SHOW BACKENDS看出每个BE的存活和负载,但我的习惯是先用SQL把全量状态拉一遍,存成文本文件备查。这个习惯在缩容时尤其重要——缩容后如果有什么异常,你有完整的操作前快照可以回看。
2.2 容量与资源评估的几个硬指标
扩容前,先算一笔账。很多人觉得磁盘不够了就加机器,这是最朴素也最容易出问题的思路。扩容的评估逻辑应该是这样一条链路:数据增量速度预测剩余可用时间 -> 新数据膨胀系数(加上副本和压缩率) -> 新节点需要承担的容量目标 -> 新节点规格与数量。
举个例子。我的某个集群当前总数据量约20TB(原始数据大小),副本数为2,实际物理占用约40TB。每天新增原始数据约200GB,加上副本后每天新增物理占用约400GB。按照当前磁盘总量60TB算,剩余可用空间约20TB,按当前增速还能跑50天左右。理论上如果我只想撑半年,我至少需要扩充约50TB的物理容量。如果新采购的每台BE节点挂载8块2TB盘,单机可用容量约16TB,那至少需要新增3~4台BE节点才能满足半年的增长需求。
这里必须提醒一个容易忽略的点:扩容时新增容量要按冗余来算,不能贴着上限买。Doris的副本均衡机制要求在迁移数据时,目标节点有足够空间接收整份副本。如果新节点磁盘都快满了才扩容,后续任何一个数据均衡任务都可能因为空间不足而失败。我个人的安全线是:集群整体磁盘使用率尽量控制在70%以下,超过80%就要拉响警报并着手扩容。
2.3 缩容前的反向评估:被迁数据要去哪
缩容不是"删掉一台机器"这么简单,而是"把一台机器上的数据副本全部迁到其他机器上,然后再摘除这台机器"。所以缩容前最关键的问题不是"要下掉谁",而是"剩下的机器接不接得住"。我见过一个真实案例:有人缩容一台BE,没有提前看其他BE的剩余空间,结果DECOMMISSION执行到一半,所有BE磁盘全部打满,整个集群的写入直接阻塞,最终只能紧急扩容才恢复。
缩容前,建议先把待下线BE上的Tablet数量和数据量统计出来,估算出总的迁移数据量,然后看剩余BE节点的可用空间总和是否大于这个值。如果需要迁移的数据量太大,但剩余节点空间不够,要先做一轮集群内的数据整理(比如删除冷数据、清理垃圾文件),或者先扩容新BE,再缩容旧BE,这就是所谓的"先扩后缩"方案。
可以说,扩缩容在容量规划层面是同源的,两者都需要对"数据要往哪里去"这个问题有清晰认知。
3. 集群扩容:从部署新BE到数据均衡完毕的全流程
3.1 新节点的部署前检查清单
如果你准备新加一台物理机或虚拟机作为Doris的BE节点,不要直接解压安装包就启动,先过一遍环境检查的清单。
先说端口。BE节点默认通信端口是be_port(默认9060),webserver_port是8040,heartbeat_service_port是9050。这三个端口必须对FE节点和客户端开放,且不能被防火墙或安全组拦截。很多扩容失败的案例都是端口不通导致的——BE进程起不来,或者起来了但FE收不到心跳,节点状态一直显示false。
然后是系统参数。这里我直接把我的核对项列出来:
# 1. 查看操作系统版本,确认与现有BE节点一致或兼容 cat /etc/os-release # 2. 查看JDK版本,Doris BE节点也需要JDK,建议与FE保持同一大版本 java -version # 3. 关闭防火墙或放行Doris相关端口 systemctl stop firewalld systemctl disable firewalld # 4. 调整文件句柄数 ulimit -n 65536 # 5. 查看磁盘挂载和剩余空间 df -h # 6. 确认CPU架构,x86和ARM的Doris安装包不通用 uname -m文件句柄数这里多说一句。很多人在部署时容易忽略,但BE节点在高并发写入时会打开大量文件句柄,如果系统限制不够,磁盘读写会异常报错。建议在/etc/security/limits.conf中配置doris用户的nofile为65536及以上。
还有一个经常被忽略的问题:新BE节点的机器名和IP需要在FE所在机器上能互相解析。虽然Doris支持IP直连,但如果你部署环境中配置了主机名,最好把新节点的主机名加到每台FE的/etc/hosts里,否则心跳注册可能出现奇怪的超时。
3.2 BE节点实际添加步骤:命令背后的含义
环境准备好后,开始正式的BE节点添加。第一步是把新BE的安装目录准备好。我会先在一台现有BE节点上打包一份Doris BE目录,然后把整个目录传到新机器上解压。这样做的好处是配置风格和现有集群完全一致,不会出现参数遗漏。
需要重点修改的配置文件是be.conf。几个核心参数逐个过一遍:
# be.conf中的关键配置 # BE节点在集群内的唯一标识,默认等于机器IP,一般不需要改 be_port = 9060 # BE节点的心跳上报端口 heartbeat_service_port = 9050 # BE节点的HTTP服务端口,用于页面查看BE状态 webserver_port = 8040 # 数据存储目录。多目录用分号分隔,每块盘一个目录 storage_root_path = /data01/doris/storage,/data02/doris/storage # BE节点内存上限,建议不超过物理内存的80% mem_limit = 80%storage_root_path是重中之重。如果新节点挂了多块数据盘,强烈建议每块盘对应一个独立的storage_root_path目录,多个目录之间用英文分号分隔。这样数据会相对均匀地分布到不同磁盘,避免出现一块盘写满、其他盘大量空闲的"磁盘倾斜"问题。
配置完成后,用doris用户启动BE,然后确认进程日志里没有异常:
# 启动BE节点 sh bin/start_be.sh --daemon # 查看BE日志 tail -100 log/be.INFO首次启动后不要急着把节点加入集群,先确认BE进程和端口都正常了。我习惯用ss命令快速检查端口监听状态:
ss -lntp | grep -E '9060|9050|8040'确认三个端口都在监听后,再回到FE节点上执行添加操作。Doris提供了两种方式,一种是老牌的curl命令调API,一种是新版支持的SQL命令。这里我展示一下curl方式的完整用法,因为这个方法在离线环境和脚本化操作时更通用:
# 在FE节点上执行,添加BE节点到集群 curl -X POST http://FE_IP:8030/api/add_backend -d "host_ports=新BE_IP:9050"注意这个命令有几个细节。首先,8030是FE的HTTP端口,这个端口是FE用于管理操作的统一入口。其次,命令里的9050是BE的heartbeat_service_port,不是be_port(9060),很多人在这个地方搞混,导致添加之后FE一直收不到BE心跳。最后,如果你用的是带认证的Doris集群,还需要在curl命令中加入用户名和密码参数,以实际环境为准。
如果你用的是Doris 1.2及以上版本,也可以直接用SQL方式操作,更直观:
ALTER SYSTEM ADD BACKEND "新BE_IP:9050";两种方式效果一样,选一种用就行。添加成功后,可以再次执行SHOW BACKENDS验证新节点是否出现在列表中。如果新节点的Alive字段很快变为了true,说明BE注册和心跳都正常。
3.3 添加完BE后的数据自动均衡机制
新BE加进来之后,大多数人以为事情就结束了,其实真正耗时的过程才刚刚开始:数据均衡。Doris的BE节点之间会定期做一次tablet均衡调度。新加入的BE节点TabletNum为0,集群的均衡逻辑会逐步把其他BE上的部分tablet副本迁移过来,直到所有BE的tablet数量接近一致。
这个"定期调度"由FE控制,有一个比较长的周期(默认是300秒,即5分钟触发一次均衡检查),每次调度迁移的tablet数量也是有限的,所以大批量数据均衡往往需要以小时甚至天为单位计算。我遇到过TB级数据量的集群,扩3个新BE后,数据均衡花了将近两天时间。这期间查询性能会有一定下降,因为数据迁移会占用磁盘IO和网络带宽。
你可以通过下面这条SQL来看当前集群的tablet迁移进度:
SHOW PROC "/cluster_balance";这个Proc接口会返回较多的信息,包括当前待均衡的tablet数量、正在迁移的tablet、均衡完成的tablet等。重点看BackendId对应的"Balance"相关指标是否逐渐趋向0。
同时建议观察BE的磁盘空间变化。新BE的磁盘空间会逐步增加,其他BE的磁盘空间会逐步下降,这是数据在迁移的直接表现。如果过了很长时间新BE的磁盘占用还是几乎没变,可能是均衡被某些异常任务阻塞了,需要进一步排查,后面第6节我会专门说这个问题。
3.4 扩容BE时是否要动FE:按场景判断
说到扩容,还有一个场景区分不能回避:只加BE节点,和同时加FE节点,是两种完全不同的操作。如果你扩容只是因为数据量和查询压力大,目标是用更多的BE节点来分担存储和计算压力,那FE节点数量不需要变化。但如果你的集群整体请求量涨幅很大,FE经常出现CPU飙升或内存紧张,那就需要考虑扩容FE。
FE节点的扩容方式和BE节点不太一样。FE有Follower和Observer两种角色。Follower参与选举,Observer只同步元数据不参与选举,主要用于扩展读能力。集群中Follower的奇数个(通常1个或3个)保证选主正常,Observer可以根据需要加多台。
添加FE节点的操作我放到第5节单独展开。这里只需要记住一个判断原则:扩容方向是存储计算资源,加BE;扩容方向是元数据服务或高并发查询解析能力,加Observer类型的FE。不要一上来就给FE集群加Follower节点,Follower数量过多会拖慢元数据写入的同步效率,反而得不偿失。
4. 集群缩容:优雅下线一个BE节点的完整流程
4.1 为什么推荐DECOMMISSION而不是直接DROP
缩容BE节点,Doris提供两个核心命令:DECOMMISSION和DROP BACKEND。这两个命令的差别非常大。
-- 推荐方式:先让数据自动迁移,再下线节点 ALTER SYSTEM DECOMMISSION BACKEND "要下线BE_IP:9050"; -- 慎用方式:直接从集群中删除节点,不保证数据迁移 ALTER SYSTEM DROP BACKEND "要下线BE_IP:9050";DECOMMISSION的意思是:"请把这个BE节点上的数据副本全部迁移到集群内其他BE节点上,迁移完成后自动将节点从集群中移除。" 这是一个类似"优雅退出"的过程,数据迁移完成后,该BE节点会被自动标记为不可用。
DROP BACKEND则简单粗暴很多。执行后Doris会直接把BE节点从元数据中删除,节点上的tablet副本会被集群视为丢失,然后系统会尝试在其他存活BE上重新补副本。如果原节点上存的是单副本数据,直接DROP等于丢数据。
所以哪怕你急着下线一台机器,也强烈建议走DECOMMISSION流程。只有一种情况可以考虑跳过:这台BE节点本身已经损坏,数据无法迁移,且所有表都有至少2个以上副本,此时DROP掉它后系统会自动用剩余副本补齐副本数。
DECOMMISSION命令执行后,不会立即生效。FE会开始将待下线BE上的tablet调度迁移到其他节点。迁移过程是分批进行的,每批迁移哪些tablet、迁移速度如何,由FE的调度策略控制。这个过程耗时长短,取决于待下线BE节点的数据量、目标BE的剩余空间和当前集群IO负载。
4.2 缩容期间必须盯紧的几个关键指标
DECOMMISSION执行期间,你不可能等着它自动跑完,一定要主动监控。我最常看的指标有三个:待下线BE上的tablet数量变化、目标BE节点的磁盘空间变化、整个集群的副本健康状态。
tablet数量变化可以通过下面这个SQL反复查看:
SHOW BACKENDS\G;观察待下线BE节点的TabletNum字段,如果DECOMMISSION生效了,这个数字会逐渐下降。下降速度基本可以反映迁移速度。如果这个数字长时间不变,说明迁移没在跑,要去看后面要说的常见问题。
磁盘空间方面,需要重点盯那些"接收方"BE节点。因为数据是一批批迁过去的,接收方BE的磁盘使用率会逐渐上升。要提前算好接收方BE还有多少空间余量,别让某个BE被灌满。
副本健康状态可以用这条SQL看:
SHOW PROC "/cluster_health/tablet_health";如果出现多个副本状态异常,比如REPLICA_MISSING或REPLICA_RELOCATING,而且数量持续增加,这就是缩容过程出问题的信号,要及时介入。
DECOMMISSION完成后,待下线BE的Alive状态会自动变为false,同时节点状态会标记为"System Decommissioned"。这时候再从SHOW BACKENDS中确认这个节点已经不再提供服务。注意一点:DECOMMISSION完成不等于节点进程停止了。BE进程还活着,但Doris已经不再向它分配新的查询和写入任务。这时候你可以正常shutdown这个BE进程,然后从物理机上卸载它。
4.3 实际缩容一次BE的完整过程记录
我拿之前一次做得比较顺利的缩容来复盘,把时间节点和数据变化列出来,给大家一个直观的感知。
那台待下线BE节点上当时有大约38000个tablet,总数据量约3.2TB,集群还有其他6台BE节点,每台剩余可用空间都在3TB以上,总剩余容量充足,满足数据迁移要求。执行DECOMMISSION后的变化大约是:前2个小时迁移速度比较快,迁走了约9000个tablet;之后速度略有下降,因为FE调度器会控制并发,避免对在线业务产生太大影响;到第14个小时左右,38000个tablet全部迁移完成,BE节点自动从集群中下线。
从这次经验里可以总结出几点:
- 迁移速度不是恒定的,FE会自动做限速。所以不要因为一开始慢就频繁干预。
- 3TB左右的数据量,14个小时完成,这个速度供你们参考。如果数据量更大,要提前预留好时间窗口。
- 迁移期间集群若有大量写入任务,迁移速度会进一步变慢,因为FE调度器会优先保证线上服务的稳定性。所以缩容操作最好安排在业务低峰期执行。
- 千万不要中途反复执行DECOMMISSION和取消DECOMMISSION,每次切换都可能打断正在进行的调度任务,反而拖慢整体进度。
还有一个操作上的注意点:DECOMMISSION之后,如果发现这台BE节点又要保留,可以执行取消操作恢复正常状态:
CANCEL DECOMMISSION BACKEND "待下线BE_IP:9050";取消后,Doris会停止迁移任务,但已经迁走的tablet不会自动迁回,而是由均衡调度器在后台慢慢重新调整。所以别频繁切换状态,操作一次要想清楚。
4.4 非对称缩容与混合缩容:一次处理多台BE
如果你需要一次下掉多台BE,事情会比较复杂,但核心原则和单台缩容相同。不要同时对所有目标节点执行DECOMMISSION,建议每次只处理一台。等第一台的tablet迁完、节点成功下线后,再处理第二台。
原因很简单:如果同时DECOMMISSION了3台BE,那这3台节点上的所有副本都要迁移到剩余的节点上,数据迁移总量是3台之和。剩余节点同时还要承受在线业务写入,磁盘和网络压力会迅速攀升,甚至因为空间不足导致部分迁移失败。一台一台来,是对集群稳定性最负责任的做法。
有一种情况可以适当放宽并发,那就是"先扩后缩"的操作计划:先增加若干台新BE,等新BE的tablet数追平老BE,再逐台DECOMMISSION老BE。这种操作模式下,集群整体容量是先增后减的,任何时刻都不会出现容量低谷,风险最小。如果你计划大规模替换老机器,一定要采用这个节奏。
5. 元数据层的扩缩容:FE节点的添加与摘除
5.1 添加Observer节点扩展FE读能力
FE节点是可以横向扩展的。当你发现FE的CPU经常打满,或者并发查询数量较高导致元数据服务响应变慢,最有效的做法是添加Observer类型的FE节点。
Observer FE不参与选主投票,它的作用是同步主FE上的元数据镜像和日志,并对外提供元数据读服务。查询请求中的很多元数据访问可以直接打到Observer上,减轻主FE的压力。
添加Observer的操作分两步。第一步,在已经运行的FE节点上执行:
ALTER SYSTEM ADD OBSERVER "新FE_IP:9010";这里9010是FE节点的edit_log_port,用于FE之间的元数据日志同步。第二步,在已有的FE节点上先把FE安装目录整体拷贝到新机器上,然后启动新的FE进程。
为什么需要拷贝已有FE的数据目录?因为新FE启动时必须有一个元数据的基线。Doris不允许从零开始创建一个Observer,它需要从已有的FE节点上同步元数据。所以在部署新FE时,要确保fe.conf中的meta_dir指向的目录里面已经有老FE拷贝过来的镜像文件。如果目录为空或没有镜像,FE启动时会初始化成一个全新的集群,这会和现有集群产生冲突,导致不可预期的后果。
启动Observer的命令:
sh bin/start_fe.sh --daemon启动后,还是回到FE节点上执行SHOW FRONTENDS确认新节点的状态:
SHOW FRONTENDS\G;如果新FE的Alive字段为true,Role为OBSERVER,说明添加成功。Java进程日志里如果出现类似于"finished to replay journal"的记录,也说明元数据同步正常完成。
5.2 添加Follower节点提升元数据高可用
如果当前集群只有一个FE节点,元数据的可靠性完全依赖单点,这时建议至少再添加一个Follower节点。Follower节点参与leader选举,当主FE宕机时,剩余Follower可以重新选举出新的主FE,保证集群可用。
添加Follower的命令和Observer很相似:
ALTER SYSTEM ADD FOLLOWER "新FE_IP:9010";Follower在启动时和Observer有一点不同:必须指定集群中已有FE的helper地址,才能正确加入现有的元数据组。这里需要一个额外的启动参数:
sh bin/start_fe.sh --helper 已有FE_IP:9010 --daemon很多初次部署Follower的人会漏掉--helper参数,结果新FE自己初始化了一个全新集群,和老集群各玩各的,两个集群的元数据互相不认,这是非常经典的失误。
当有多个Follower节点时,配置里还隐含着一条规则:Follower节点数量建议为奇数。3个Follower相比2个Follower的优势在于,当其中一个节点宕机时,剩余节点可以正常选出主FE(2/3的多数),而2个Follower如果挂掉一个,剩下1个节点无法形成多数派,元数据服务将不可用。Doris内部虽然也支持偶数Follower,但从高可用角度讲,奇数是最优配置。
5.3 FE节点的缩容操作与潜在风险
FE节点的缩容相对少见,但有些场景确实会遇到,比如原本担心高可用配了3个Follower,后来发现集群规模小,3个过于浪费;或者某台机器要下线,上面恰好跑着FE节点。FE的缩容方式同样分为Observer和Follower两类,但操作本质上都是类似的:
ALTER SYSTEM DROP FOLLOWER "待下线FE_IP:9010"; -- 或 ALTER SYSTEM DROP OBSERVER "待下线FE_IP:9010";FE缩容时有个特别容易出问题的地方:必须先确认待下线FE节点的元数据已经不在service中提供服务,再停进程。如果这台FE恰好是当前leader,直接DROP会触发新一轮选举,可能导致短时间内元数据写入失败。所以规范操作是:先停掉该FE的服务,再把它从集群元数据中删除。
具体做法上,不建议直接执行DROP然后立刻杀进程。我个人更推荐先观察这台FE的角色,如果它是leader,需要考虑是否还有其他Follower能接管。如果没有,要先添加一个新的Follower,等状态正常后再下线老节点。如果是非leader节点,可以直接DROP后停进程,然后清理该节点上的FE安装目录。
FE缩容有一个隐藏风险需要特别提醒:FE的元数据目录里保存了整集群的元数据信息,包括所有库表结构、所有tablet的分布等。如果你误删了某个FE节点的meta_dir,而该节点又是集群中唯一存放元数据副本的节点,那后果是灾难性的。所以在缩容FE时,千万不要顺手把数据目录里的文件删掉。如果实在要清理磁盘空间,也建议把meta_dir整个目录打包备份到其他机器上,保留三个月以上再决定是否清理。
6. 常见问题与排查技巧实录
6.1 BE节点状态一直false,加不进集群
这是扩容时最常遇到的问题。新BE启动后,在SHOW BACKENDS中看到Alive字段一直显示false,或者压根看不到新节点。排查思路按照下面的顺序来:
第一步,先确认BE进程是否真的存活。执行ps -ef | grep doris,看BE进程有没有被启动脚本拉起后自动退出。我遇到过进程启动几秒后退出,日志里报初始化存储目录失败的情况。这类问题多半是数据目录的属主不对,或者目录不存在。用chown把数据目录属主改成doris用户即可。
第二步,查看FE的日志。FE日志路径是fe/log/fe.log,搜索新BE的IP,看有没有心跳注册相关的报错。如果是网络不通,日志里会有"cannot receive heartbeat"之类的内容。这时先ping新BE的IP,再用telnet检查端口通不通:
telnet 新BE_IP 9050 telnet 新BE_IP 9060如果端口不通,去目标机器上检查防火墙和安全组。
第三步,判断是不是版本不兼容。FE和BE的版本号差距过大,也可能导致心跳不成功。建议将所有节点的Doris版本统一,特别是大版本必须一致。跨大版本混布通常不被支持,执行扩容前最好先确认版本。
6.2 扩容很久了,新BE节点的tablet数还是远低于其他节点
新BE加入集群后,数据均衡任务迟迟不触发,这是不少人遇到过的困惑。可能的原因有几类:
第一个是最容易被忽略的:你刚加完节点就开始大量写入数据,新写入的tablet会优先分配到新BE上吗?其实不一定。Doris的写入副本分配是取决于当前各BE的tablet数量分布和负载情况的,新BE会逐步获得新写入的tablet,但如果集群均衡调度没有启动,老BE上的存量tablet不会自动流过来。
这时候可以去FE的日志里搜索"balance"相关的关键词,看看调度器有没有在跑。如果没有调度日志,可能是FE的tablet调度功能被关闭了。检查FE配置项tablet_scheduler_disable_balance是否为false。有些团队为了维护方便会把自动均衡关掉,时间久了忘记打开,扩容后就会发生tablet数不均衡的问题。
还有一个常见原因:新BE节点和集群内其他机器的CPU架构或磁盘性能差异太大。比如集群内大部分是SSD,新加的是HDD,性能差距导致调度器每次评估时都认为迁移成本高,迟迟不下发迁移任务。当然,生产环境建议BE节点配置保持基本一致,否则容量规划和负载管理都会变得比较复杂。
如果确认调度器正常,但迁移速度实在慢得让人无法接受,可以在FE配置中适当调高并发度。相关参数包括tablet_scheduler_max_running_task等,但调参之前要评估好磁盘IO和网络带宽的承受能力,调得太激进会影响线上查询。
6.3 DECOMMISSION后数据迁不完,一直卡在中间状态
缩容时最让人头疼的就是DECOMMISSION执行后,tablet迁移任务卡住,待下线节点的tablet数量既不增也不减。通常和数据倾斜有关。如果待下线BE上某些tablet只有一个副本,而其他BE节点空间又不足以接收这些副本,迁移就无法进行。
排查方式是用SHOW PROC看具体的tablet信息,找出那些始终没能迁移成功的tablet,然后确认目标BE是否有足够空间。如果空间不足,就需要先做一轮扩容或者先清理一些数据再继续缩容。
另一种卡住的原因是待下线BE上的某些tablet处于异常状态,比如副本损坏或版本落后。这类tablet在迁移时会被调度器反复重试但一直失败。这种情况下,可以在确认有其他健康副本的前提下,手动修复异常tablet,或者用admin的tablet修复命令强制重置状态。实际操作时一定要小心,先确认至少存在一个健康的副本,否则修复操作可能造成数据丢失。
6.4 扩容/缩容期间的集群performance波动应对
扩缩容期间,因为数据迁移任务占用了大量磁盘IO和网络资源,集群整体的查询性能会有轻微下降,这是正常现象。但如果你发现慢查询明显增多,或者写入延迟升高到不可接受,需要采取一些措施。
最直接的方法是降低迁移并发度。在FE配置中调低tablet调度器的并发任务数,比如把最大同时运行的迁移任务数从默认值调低到原值的一半,这样可以给线上业务让出资源。
另一个方法是为扩缩容操作预留时间窗。尽量把这类操作安排在凌晨或其他低峰时段执行。如果你的集群有业务等级区分,还需要注意不要在数据迁移期间跑大查询或大批量ETL任务,避免资源争抢进一步加剧。
6.5 扩缩容问题排查速查表
我把实际处理过的问题整理成一张速查表,方便后续遇到问题时快速定位:
| 现象 | 可能原因 | 排查方法 | 解决方案 |
|---|---|---|---|
| 新BE状态false | 端口不通/数据目录权限错误 | telnet测试端口,查看FE日志 | 调整防火墙、修改目录属主、检查端口配置 |
| 新BE状态false | FE与BE版本差异过大 | 对比版本号 | 升级统一版本后再扩容 |
| 扩容后tablet不均衡 | 自动均衡调度被关闭 | 检查tablet_scheduler_disable_balance参数 | 开启自动均衡 |
| 扩容后tablet不均衡 | 磁盘性能差异过大 | 查看各BE磁盘类型 | 尽量用同规格硬件 |
| DECOMMISSION一直没完成 | 目标BE空间不足 | SHOW BACKENDS查看磁盘剩余 | 清理数据或先扩容 |
| DECOMMISSION一直没完成 | 该BE上有异常tablet | SHOW PROC "/cluster_balance"定位 | 修复异常副本后再重试 |
| 迁移期间查询变慢 | 数据迁移占用IO | 查看系统IO负载 | 调低调度并发或错峰操作 |
| 缩容后某BE磁盘打满 | 扩容目标规划不足 | 查看各BE磁盘使用率 | 扩容后再重新缩容 |
这张表是我日常排障的基本框架。如果你遇到类似但又不完全相同的问题,我的建议是先别急着改配置,把FE和BE的日志翻一翻,大多数情况下Doris的日志会给出非常明确的报错指引。
7. 从一次误操作看Doris扩缩容的不可逆风险
我在文章最后想分享一次真实的教训。有次我在一个测试集群上做压测,为了验证缩容流程,直接对一台BE执行了DROP BACKEND,而没有用DECOMMISSION。当时那个集群里大部分表都是双副本,我以为DROP掉一台BE后,剩余BE会自动补副本,不会有太大问题。结果因为DROP发生在数据写入高峰期,部分tablet的两个副本恰好都在那台被DROP的BE上(虽然概率不高,但确实存在),那部分数据直接变成了单副本甚至零副本,导致查询时出现数据缺失。
那次经历之后,我给自己立了几条规矩,现在也分享给你们:
第一,生产环境永远不要用DROP BACKEND来下线节点。哪怕你确认所有表都有三个副本,DROP操作也会触发大规模副本修复,产生不必要的集群压力。
第二,任何扩缩容操作前,至少提前一天执行一次全量备份。虽然Doris本身有副本机制,但分布式系统在变更期间的意外谁也说不准,多一道保险多一分安心。
第三,扩缩容操作要写进变更流程,记录操作时间、执行人、操作前后的集群状态截图。出了问题能快速回看,也方便其他同事接手处理。
第四,Doris的扩缩容虽然支持在线执行,但不代表可以在业务高峰期任意操作。凡是涉及大规模数据迁移的动作,都应该像对待核心业务变更一样,走完整的评估和审批流程。
第五,如果你对某个参数或命令的副作用拿不准,先在测试集群上验证一遍,再上生产。这个习惯帮我避开过很多隐性坑。
扩缩容是Doris集群生命周期管理里的常规操作,但每一次操作背后都牵动着数据分布、集群稳定性、资源利用率和业务连续性。理解了机制,做好了规划,控制好节奏,这两件事就能从"高风险变更"变成"日常可控操作"。希望我梳理的这些经验和踩坑记录,能帮你少走一些弯路。