尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Docker Compose部署Doris存算分离:架构解析与避坑指南

发布时间:2026/9/24 13:13:09

资讯中心
01
ARTICLE

Docker Compose部署Doris存算分离:架构解析与避坑指南

Docker Compose部署Doris存算分离:架构解析与避坑指南
1. 为什么要在Docker里折腾Doris存算分离先把结论摆在前面如果你只是想在本机跑个Doris单机版玩玩SQL那完全没必要碰存算分离FE和BE塞一个容器里就完事了。但只要你开始考虑计算资源和存储资源能不能各自独立扩缩容BE节点挂了数据还在不在多套集群能不能共享同一份底层数据这类问题存算分离就是绕不过去的一道坎。Doris从2.1版本开始正式把存算分离架构推到台前核心思路是把BE原本自己管的本地数据文件下沉到共享存储层对象存储或HDFSBE本身变成无状态的计算节点。这样一来计算节点可以随用随起、用完就删数据始终躺在共享存储里扩容缩容不再需要搬数据。这个变化对部署方式的影响是根本性的——以前你部署一套Doris集群得规划每台机器的磁盘、考虑副本分布现在你只需要保证共享存储可用、计算节点能连上元数据服务就行。那为什么还要用Docker来部署我自己的体会是三个字可复现。存算分离涉及的角色比存算一体多得多——FE、MSMeta Service、BE、共享存储、回收站任何一个组件的版本或配置对不上集群就起不来。用Docker Compose把这一整套编排写进一个YAML文件换台机器docker compose up就能拉起一模一样的环境排查问题时也能快速销毁重建不用在一堆残留配置里挣扎。对于想学习存算分离架构、或者要在测试环境快速验证方案的人来说这是成本最低的路径。这篇文章面向的是有一定Docker基础、想在自己机器或测试服务器上把Doris存算分离跑起来的读者。我会从架构角色拆解讲起然后给出完整的Compose编排、配置细节、启动顺序、验证方法最后重点讲我在实操中踩过的坑——这些坑在官方文档里往往一笔带过但实际部署时几乎必踩。2. 存算分离架构里每个角色到底在干什么在动手写Compose之前必须先把存算分离的角色关系理清楚。很多人部署失败根本原因不是命令敲错了而是没搞明白谁依赖谁、谁必须先起来。存算一体时代只有FE和BE两个角色存算分离之后多了一个MS而且BE的行为模式完全变了。2.1 FE、MS、BE三者的职责边界FEFrontend的角色和存算一体时基本一致负责接收SQL、解析、生成执行计划、管理元数据。它对外暴露9030端口给MySQL客户端8030端口是Web UI。FE本身不存实际数据只存元数据所以它的状态相对轻量。MSMeta Service是存算分离新增的组件这是整个架构的关键。它管的是数据文件放在共享存储的哪个位置这件事——也就是元数据服务。BE写入数据时先向MS申请一个文件路径MS返回一个带版本信息的路径BE把数据写到这个路径上读取时同样先问MS要路径。MS还负责回收站管理、事务日志等。你可以把MS理解成共享存储的目录管理员它自己不存数据但所有数据的位置信息都由它维护。MS默认监听5000端口HTTP和5100端口gRPC。BEBackend在存算分离模式下变成了纯计算节点。它不再把数据存在本地磁盘上而是把数据写到共享存储。BE启动时需要知道两件事MS的地址用来申请文件路径和共享存储的访问凭证。BE的本地磁盘只用来做缓存和临时文件即使整个BE容器被删掉数据也不会丢。2.2 共享存储选型为什么测试环境我推荐MinIO共享存储层是存算分离的基石Doris支持对象存储S3协议兼容的和HDFS两大类。生产环境用云厂商的对象存储或者自建HDFS集群都行但在Docker本地测试环境里我强烈推荐用MinIO。原因很直接MinIO是S3协议兼容的Doris对S3协议的支持最成熟配置项最少MinIO本身也能用Docker一键拉起和Doris容器在同一个Compose网络里不用配跨主机访问而且MinIO自带Web控制台你能直观看到Doris到底往存储里写了哪些文件排查问题时这个可视化能力太重要了。用HDFS的话你还得额外起NameNode和DataNode配置复杂度直接翻倍对学习存算分离架构本身没有额外帮助。提示MinIO的S3 API端口是9000控制台端口是9001。Doris配置里填的endpoint是9000那个别填错。2.3 容器网络与端口规划Docker Compose默认会创建一个bridge网络所有服务在同一个网络里可以用服务名互相访问。这一点对Doris存算分离特别重要因为BE配置里要填MS的地址FE配置里要填BE的地址如果用IP就得写死容器重建后IP变了配置就失效。用服务名比如ms、be、minio就稳定得多。端口规划上我建议把关键端口都映射到宿主机方便调试服务容器内端口宿主机端口用途FE80308030Web UIFE90309030MySQL协议MS50005000HTTPMS51005100gRPCBE80408040Web UIBE90609060ThriftMinIO90009000S3 APIMinIO90019001控制台这里有个容易忽略的点BE在存算分离模式下除了9060这个Thrift端口还需要一个额外的端口用于和MS通信以及数据传输具体端口号在BE配置里指定。如果端口没映射或者被防火墙挡了BE会一直卡在启动阶段日志里报连接超时。3. 从零编写一套可用的Docker Compose编排这一节是全文的核心我会把完整的Compose文件拆开讲每一段配置为什么这么写、哪个参数改了会出什么问题都交代清楚。你可以直接抄但建议看完解释再抄不然出了问题不知道怎么调。3.1 镜像选择与版本对齐Doris的官方镜像在Docker Hub上有apache/doris这个仓库标签格式是fe-version、be-version、ms-version。这里第一个大坑就是FE、BE、MS三个镜像的版本必须完全一致。我见过有人FE用了2.1.0BE用了2.1.3结果BE死活注册不上FE日志里报协议不兼容。存算分离的元数据格式在版本间可能有变化混用版本是自找麻烦。我实测下来比较稳的是2.1.x系列比如2.1.4。这个版本存算分离功能已经比较完善社区文档也全。不建议一上来就用最新的3.x新版本配置项有调整网上能搜到的教程大多是2.1的照着抄容易对不上。services: fe: image: apache/doris:fe-2.1.4 container_name: doris-fe hostname: fe environment: - FE_SERVERSfe:9010 - FE_ID1 ports: - 8030:8030 - 9030:9030 volumes: - fe-meta:/opt/apache-doris/fe/doris-meta - fe-log:/opt/apache-doris/fe/log networks: - doris-netFE的环境变量里FE_SERVERS指定的是FE自己的地址和编辑日志端口9010FE_ID在多FE集群里用来区分节点单FE填1就行。这两个变量是官方镜像的启动脚本读取的不填的话容器起不来。3.2 MS容器的配置要点MS的配置相对简单它主要依赖一个本地元数据目录。注意MS的元数据和生产数据是两回事——MS存的是文件路径映射关系这个数据量不大但极其关键一旦丢失整个集群的数据就找不回来了。所以MS的volume一定要持久化。ms: image: apache/doris:ms-2.1.4 container_name: doris-ms hostname: ms ports: - 5000:5000 - 5100:5100 volumes: - ms-meta:/opt/apache-doris/ms/doris-meta - ms-log:/opt/apache-doris/ms/log networks: - doris-netMS启动后你可以访问http://localhost:5000/看它的健康状态。如果返回一个JSON格式的状态信息说明MS起来了。这一步建议在启动BE之前先确认因为BE强依赖MS。3.3 BE容器的关键环境变量BE是配置最复杂的角色因为它要同时连MS和共享存储。官方镜像通过环境变量来注入这些配置但环境变量的名字和实际配置项的对应关系文档里写得比较散我整理一下。be: image: apache/doris:be-2.1.4 container_name: doris-be hostname: be environment: - FE_SERVERSfe:9010 - BE_ADDRbe:9060 - MS_SERVERSms:5100 - STORAGE_TYPES3 - S3_ENDPOINThttp://minio:9000 - S3_ACCESS_KEYminioadmin - S3_SECRET_KEYminioadmin - S3_BUCKETdoris-data - S3_REGIONus-east-1 ports: - 8040:8040 - 9060:9060 volumes: - be-storage:/opt/apache-doris/be/storage - be-log:/opt/apache-doris/be/log depends_on: - ms - minio networks: - doris-net这里几个参数值得展开说。MS_SERVERS填的是MS的gRPC端口5100不是HTTP的5000填错了BE连不上MS。STORAGE_TYPE填S3这是Doris对S3协议兼容存储的统一叫法MinIO也走这个。S3_ENDPOINT里用的是服务名minio加端口9000因为BE容器和MinIO容器在同一个Docker网络里能直接通过服务名解析。S3_REGION虽然MinIO不校验但Doris的S3客户端要求必须填随便填个us-east-1就行。注意S3_ACCESS_KEY和S3_SECRET_KEY必须和MinIO容器启动时设置的一致。MinIO默认的minioadmin/minioadmin只在没显式设置时才生效如果你在MinIO那边改了BE这边也要同步改。3.4 MinIO与网络定义MinIO的配置很标准关键是启动命令里要指定控制台端口和数据目录。minio: image: minio/minio:latest container_name: doris-minio hostname: minio command: server /data --console-address :9001 environment: - MINIO_ROOT_USERminioadmin - MINIO_ROOT_PASSWORDminioadmin ports: - 9000:9000 - 9001:9001 volumes: - minio-data:/data networks: - doris-net networks: doris-net: driver: bridge volumes: fe-meta: fe-log: ms-meta: ms-log: be-storage: be-log: minio-data:所有volume都显式声明这样docker compose down不会误删数据只有加-v参数才会清空。这一点在调试阶段特别重要——你可能需要反复重启容器但不想每次重建都重新初始化整个集群。4. 启动顺序与集群初始化的完整链路Compose文件写好了不代表up一下就能用。Doris存算分离的组件之间有严格的依赖顺序顺序错了就得推倒重来。我按实际操作顺序讲一遍。4.1 先起MinIO并创建BucketMinIO必须先于BE就绪因为BE启动时会去连S3 endpoint。但光起MinIO还不够doris-data这个bucket得先存在否则BE写入时会报bucket不存在。启动MinIOdocker compose up -d minio然后进MinIO控制台http://localhost:9001用minioadmin/minioadmin登录手动创建一个名为doris-data的bucket。或者用mc客户端命令行创建docker exec doris-minio mc alias set local http://localhost:9000 minioadmin minioadmin docker exec doris-minio mc mb local/doris-data我建议用命令行因为可脚本化重建环境时不用再点一遍控制台。4.2 启动MS并确认健康状态docker compose up -d ms docker logs doris-ms看日志里有没有Meta Service started successfully之类的字样。然后访问http://localhost:5000/正常应该返回类似{status:OK}的响应。如果MS起不来先别急着起BEMS的问题不解决BE一定失败。4.3 启动FE并等待元数据初始化docker compose up -d fe docker logs -f doris-feFE首次启动会初始化元数据这个过程大概需要十几秒到半分钟。日志里出现FE started successfully或者你能访问http://localhost:8030看到Web UI就说明FE好了。FE的默认登录账号是root密码为空。4.4 启动BE并验证注册BE是最后起的因为它依赖FE和MS都已就绪。docker compose up -d be docker logs -f doris-beBE启动后会自动向FE注册。你可以在FE的Web UI里进System-Backends页面看BE是否出现在列表里状态是不是Alive。也可以用MySQL客户端连FE查mysql -h 127.0.0.1 -P 9030 -uroot -e SHOW BACKENDS\G如果BE状态是Alive恭喜你集群起来了。如果是Dead或者压根没出现往下看排查章节。4.5 建表验证存算分离是否真正生效集群起来只是第一步得验证数据真的写到MinIO里了。建一张测试表CREATE DATABASE test_db; USE test_db; CREATE TABLE test_table ( id INT, name VARCHAR(50) ) DISTRIBUTED BY HASH(id) BUCKETS 1 PROPERTIES (replication_num 1);注意存算分离模式下副本数建议设为1因为数据本身在共享存储里已经有冗余保障BE再存多副本意义不大反而浪费计算节点的本地空间。插入几条数据INSERT INTO test_table VALUES (1, alice), (2, bob);然后去MinIO控制台看doris-data这个bucket应该能看到Doris写入的数据文件路径大概长这样doris-data/1/data/...。如果你能看到这些文件说明存算分离链路完全打通了——BE确实把数据写到了共享存储而不是本地磁盘。再做个更狠的验证把BE容器删掉重建数据还在不在。docker compose rm -sf be docker compose up -d be等BE重新注册后再查SELECT * FROM test_table;数据应该还在。这就是存算分离的核心价值——计算节点无状态删了重建数据不丢。5. 部署过程中最容易踩的五个坑这一节是我踩坑踩出来的经验官方文档不会告诉你这些但实际部署时几乎必遇到。5.1 BE启动卡住MS地址填了HTTP端口最常见的错误。BE配置里MS_SERVERS必须填MS的gRPC端口5100但很多人看到MS暴露了5000和5100两个端口随手填了5000。结果BE日志里一直刷连接超时或者报failed to connect to meta service。排查方法进BE容器用telnet ms 5100测试连通性。如果5100通、5000不通或者反过来就说明端口填错了。改Compose里的环境变量重建BE容器即可。5.2 S3 endpoint用了localhost在BE容器里localhost指的是BE容器自己不是宿主机。所以S3_ENDPOINT绝对不能填http://localhost:9000必须填MinIO的服务名http://minio:9000。同理如果你把MinIO部署在宿主机上不在Compose网络里那得填宿主机的实际IP不能用localhost。这个坑的隐蔽性在于你在宿主机上用浏览器能访问http://localhost:9001看到MinIO控制台就以为BE也能用localhost连实际上容器网络和宿主机网络是隔离的。5.3 Bucket没提前创建导致BE写入失败BE启动本身不报错但一旦你建表插数据就报S3 bucket does not exist。因为BE启动时只校验endpoint连通性不校验bucket是否存在。所以务必在起BE之前把bucket建好。5.4 版本不一致导致BE注册失败前面提过FE、BE、MS三个镜像版本必须一致。如果你从不同来源拉了镜像或者Compose里写错了tagBE注册时会报协议错误。检查方法docker exec doris-fe cat /opt/apache-doris/fe/version docker exec doris-be cat /opt/apache-doris/be/version docker exec doris-ms cat /opt/apache-doris/ms/version三个版本号必须完全一样。5.5 磁盘空间不足导致BE启动失败BE虽然不存实际数据但它的本地storage目录还是要用来做缓存和临时文件的。Docker默认的volume存储位置如果磁盘空间紧张BE启动时会报no space left on device。检查docker system df看volume占了多少空间必要时清理无用的镜像和volume。6. 存算分离集群的日常运维与调优思路集群跑起来只是开始日常用起来还有几个点要注意。6.1 计算节点扩缩容的正确姿势存算分离最大的好处就是扩缩容简单。要加一个BE节点只需要在Compose里复制一份be服务改一下BE_ADDR的端口避免和现有BE冲突然后up起来。新BE会自动向FE注册数据不需要迁移因为它读的是共享存储里的同一份数据。缩容更简单直接docker compose rm -sf be2把BE容器删掉然后在FE里执行ALTER SYSTEM DROP BACKEND be2:9060把它从集群里摘除。数据不受影响。6.2 缓存配置对查询性能的影响BE的本地storage目录在存算分离模式下充当缓存。默认配置下缓存可能比较小查询频繁访问的数据如果缓存命中率低每次都要从MinIO拉延迟会明显上升。可以在BE的配置里调大缓存空间具体参数在BE的be.conf里通过Compose的volume挂载自定义配置文件来覆盖默认值。我实测下来对于测试环境把缓存调到几个GB就能明显改善重复查询的响应速度。生产环境要根据查询模式和数据热度来调。6.3 慢查询排查的切入点存算分离模式下慢查询的原因和存算一体不太一样。存算一体主要看BE本地磁盘IO存算分离则要重点看两件事一是BE到共享存储的网络延迟二是缓存命中率。如果发现某类查询特别慢先去BE的Web UI8040端口看查询profile重点看S3相关的耗时占比。如果S3读取耗时占比很高说明缓存没命中得考虑调大缓存或者优化查询让数据更集中。另外存算分离下小文件过多会显著拖慢查询因为每次读都要向MS申请路径、向S3发请求。如果发现某张表查询慢可以查一下它的数据文件数量必要时做compaction合并小文件。6.4 元数据备份不能只靠volumeMS的元数据是整个集群的命根子。虽然我们用Docker volume做了持久化但volume本身也可能损坏。建议定期把MS的元数据目录导出备份docker run --rm -v doris_ms-meta:/data -v $(pwd):/backup alpine tar czf /backup/ms-meta-backup.tar.gz -C /data .这个备份文件要存到别的地方别和Docker volume放在同一块磁盘上。真出问题的时候这份备份能救命。7. 我个人的几点实操体会折腾Doris存算分离Docker部署这段时间最大的感受是这套架构的复杂度确实比存算一体高但复杂度都集中在配置正确性上一旦配通了后续运维反而比存算一体省心。存算一体你要操心每台BE的磁盘、副本分布、数据均衡存算分离这些都不用管计算节点就是无状态的坏了就换。另一个体会是Docker Compose虽然方便但它适合的是单机测试和学习场景。真要在生产用存算分离还是得上K8s因为生产环境需要的是自动扩缩容、故障自愈、滚动升级这些能力Compose给不了。但反过来说如果你连Compose这套都跑不通直接上K8s只会更懵。所以我的建议是先在Compose里把架构跑通、把每个角色的职责搞清楚再去碰K8s。最后分享一个小技巧调试阶段把FE、BE、MS的日志都挂到宿主机上用tail -f同时盯着。存算分离启动时组件间的交互比较多单看一个组件的日志往往看不出问题三个日志对着看很容易定位到是哪个环节卡住了。比如BE注册失败FE日志里会显示收到了注册请求但校验没过BE日志里会显示发送了注册请求但没收到确认两边一对问题就清楚了。
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。