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

Docker部署Doris存算分离集群实战:架构设计与避坑指南

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

资讯中心
01
ARTICLE

Docker部署Doris存算分离集群实战:架构设计与避坑指南

Docker部署Doris存算分离集群实战:架构设计与避坑指南
1. 为什么要在Docker里折腾Doris存算分离第一次接触Doris存算分离架构的时候我脑子里冒出来的第一个念头就是这玩意儿到底跟传统部署有什么区别值不值得花时间折腾。后来在一个日志分析项目里被现实教育了一顿——数据量从每天几十GB猛涨到几百GB原来那套存算一体的集群扩容时数据重平衡慢得让人想砸键盘节点一挂整个查询链路就跟着抖三抖。从那以后我就开始认真研究存算分离这套方案而Docker部署则是我认为最适合中小团队快速验证和落地的方式。先把概念说清楚。Doris的存算分离核心思路是把计算节点Compute Node和存储层拆开。传统存算一体架构里BE节点既管数据存储又管查询计算扩容的时候数据要重新分布节点故障时数据恢复也慢。存算分离之后数据统一放到共享存储上常见的是对象存储或者共享文件系统计算节点变成无状态的可以随时加减查询的时候按需拉取数据。这个变化带来的直接好处就是弹性扩缩容和成本可控——计算资源不够就加计算节点存储不够就扩存储两边互不干扰。那为什么用Docker来部署我自己的体会是三点。第一环境隔离。Doris对操作系统、JDK版本、依赖库都有要求用Docker可以把这些全部封在镜像里不用担心宿主机环境被污染。第二快速复现。一套docker-compose文件就能把FE、BE、共享存储挂载全部描述清楚换台机器照样跑起来团队协作的时候省掉大量“你那边怎么又跑不起来”的扯皮。第三资源限制清晰。Docker可以精确控制每个容器的CPU和内存这对Doris这种吃内存的分布式数据库来说太重要了避免某个节点把宿主机内存吃光导致整机卡死。这篇文章适合谁看如果你是有一定Linux和Docker基础的后端或者数据工程师想在自己的开发机或者测试环境里快速搭一套Doris存算分离集群来验证功能、跑跑压测、做做POC那这篇内容基本可以照着抄。如果你是完全没碰过Docker的新手建议先把docker run、docker-compose这些基础操作过一遍再回来不然中间有些步骤会卡住。我不会讲太多Doris的SQL语法或者查询优化重点放在部署架构设计、Docker编排细节、存算分离的配置要点、以及实际踩过的坑上。2. 部署前的架构设计与资源规划2.1 存算分离的组件拆解与角色分工在动手写docker-compose之前得先把Doris存算分离架构里各个组件的角色理清楚。很多人一上来就急着敲命令结果配置文件里哪个参数对应哪个组件都搞混排查问题的时候一头雾水。Doris存算分离架构主要包含这几个部分FEFrontend负责元数据管理、查询解析、查询规划和调度。FE本身是有状态的元数据存在本地或者外部元数据服务里。生产环境一般部署多个FE做高可用测试环境一个就够。BEBackend在存算一体架构里BE既存数据又算数据但在存算分离模式下BE主要承担计算职责数据从共享存储读取。BE是无状态的可以随意增减。共享存储层这是存算分离的核心。Doris支持多种共享存储后端常见的有S3兼容对象存储、HDFS、以及一些共享文件系统。在Docker环境里做测试我一般用MinIO来模拟S3因为MinIO本身也有官方Docker镜像部署起来非常顺手。Meta Service存算分离模式下Doris引入了一个Meta Service组件负责管理元数据和事务日志。这个组件在存算一体架构里是不存在的很多人第一次部署存算分离的时候会漏掉它导致FE启动报错。注意Meta Service是存算分离架构特有的组件如果你按照存算一体的教程来部署存算分离大概率会在FE启动阶段就卡住。这个坑我踩过排查了半天才发现是漏了Meta Service。2.2 Docker环境下的资源分配计算资源规划这块我见过太多人拍脑袋给配置结果跑起来要么OOM要么性能拉胯。这里给一套我自己常用的计算逻辑你可以根据实际机器配置调整。假设你有一台开发机配置是16核CPU、64GB内存、500GB SSD。我的分配方案是这样的组件CPU分配内存分配磁盘占用说明FE2核8GB10GB元数据查询规划内存需求中等BE6核32GB20GB计算主力内存越大越好Meta Service1核4GB5GB元数据服务资源需求较低MinIO2核4GB剩余空间共享存储磁盘越大越好系统预留5核16GB-宿主机系统和其他进程这个分配的核心逻辑是BE拿大头内存因为Doris的查询执行大量依赖内存做排序、聚合、Join。BE的内存不够查询就会频繁落盘性能断崖式下跌。FE的内存主要消耗在元数据和查询计划缓存上8GB对于测试环境足够。Meta Service相对轻量但也不能给太少否则元数据操作会变慢。磁盘方面BE本身在存算分离模式下不需要存大量数据但查询过程中的临时文件、缓存还是会占空间给20GB比较稳妥。MinIO作为共享存储磁盘越大越好因为所有数据都往它上面放。提示如果你用的是Docker DesktopWindows或Mac资源分配还受限于Docker Desktop本身的资源限制设置。记得在Docker Desktop的Settings里把CPU和内存上限调高否则容器分到的资源会被卡死。2.3 网络模式选择与端口规划Docker网络模式的选择直接影响集群内部通信和外部访问。我试过bridge、host、以及自定义网络三种模式最后在Doris存算分离场景下推荐自定义bridge网络。原因很简单host模式虽然性能好但端口冲突问题很头疼尤其是你机器上已经跑了其他服务的时候。bridge模式默认网络隔离做得不错但容器间通信用容器IP的话重启后IP变化会导致配置失效。自定义bridge网络可以给容器指定固定的网络别名容器之间通过别名通信重启后别名不变配置就不用改。端口规划这块Doris默认端口如下FE HTTP端口8030FE MySQL协议端口9030FE RPC端口9020BE HTTP端口8040BE RPC端口9060Meta Service端口默认不对外暴露内部通信即可MinIO API端口9000MinIO控制台端口9001在docker-compose里我会把这些端口映射到宿主机但注意BE的RPC端口和FE的RPC端口不要映射到宿主机同一个端口否则冲突。我的做法是只映射必要的对外端口FE的8030和9030、MinIO的9000和9001其他RPC端口只在Docker网络内部通信不暴露到宿主机。3. Docker Compose编排文件逐段拆解3.1 基础镜像选择与版本对齐Doris官方提供了Docker镜像但存算分离模式的镜像和存算一体不太一样。我一般用apache/doris官方镜像版本选择上建议用2.1.x及以上因为存算分离在2.0版本才正式GA2.1版本在稳定性和功能上更成熟。镜像标签的选择有个小技巧不要用latest因为Doris版本迭代快latest可能今天和明天拉到的不是同一个版本导致环境不一致。我习惯用具体版本号比如apache/doris:fe-2.1.5和apache/doris:be-2.1.5FE和BE版本必须一致否则会出现协议不兼容的问题。MinIO用minio/minio:latest问题不大但生产环境建议也固定版本。Meta Service在Doris 2.1里是集成在FE镜像里的不需要单独拉镜像启动的时候通过参数指定角色即可。version: 3.8 services: doris-fe: image: apache/doris:fe-2.1.5 container_name: doris-fe hostname: doris-fe networks: doris-net: aliases: - fe ports: - 8030:8030 - 9030:9030 environment: - FE_SERVERSfe:9010 - FE_ID1 volumes: - ./fe/doris-meta:/opt/apache-doris/fe/doris-meta - ./fe/log:/opt/apache-doris/fe/log - ./fe/conf:/opt/apache-doris/fe/conf deploy: resources: limits: cpus: 2 memory: 8G这段配置里几个关键点FE_SERVERS指定了FE的通信地址格式是fe:9010其中fe是网络别名9010是FE的Edit Log端口。FE_ID是FE的唯一标识单节点就写1。volumes把元数据、日志、配置都挂到宿主机这样容器重建的时候数据不会丢。3.2 Meta Service的配置要点Meta Service在Doris 2.1里通过FE镜像启动但需要单独指定启动命令。很多人不知道这一点直接拿FE的默认启动命令去跑Meta Service结果启动的是FE进程然后端口冲突。doris-meta: image: apache/doris:fe-2.1.5 container_name: doris-meta hostname: doris-meta networks: doris-net: aliases: - meta-service command: [bash, -c, /opt/apache-doris/fe/bin/start_meta_service.sh] environment: - META_SERVICE_PORT9010 volumes: - ./meta/doris-meta:/opt/apache-doris/fe/doris-meta - ./meta/log:/opt/apache-doris/fe/log deploy: resources: limits: cpus: 1 memory: 4GMeta Service的端口我习惯用9010和FE的Edit Log端口区分开。这里有个细节Meta Service的元数据目录和FE的元数据目录要分开挂载不要共用同一个宿主机目录否则两个进程同时读写会出问题。注意Meta Service启动后FE的配置里需要指定Meta Service的地址。这个配置在FE的fe.conf里通过meta_service_endpoint参数设置格式是meta-service:9010。如果这个参数没配对FE启动时会报连接Meta Service失败。3.3 BE节点的存算分离配置BE节点是存算分离里配置最复杂的部分因为要指定共享存储的访问信息。我以MinIO为例BE的配置需要在be.conf里设置存储后端类型、访问密钥、Endpoint等信息。doris-be: image: apache/doris:be-2.1.5 container_name: doris-be hostname: doris-be networks: doris-net: aliases: - be environment: - FE_SERVERSfe:9010 - BE_ADDRbe:9060 volumes: - ./be/storage:/opt/apache-doris/be/storage - ./be/log:/opt/apache-doris/be/log - ./be/conf:/opt/apache-doris/be/conf depends_on: - doris-fe - doris-meta - minio deploy: resources: limits: cpus: 6 memory: 32GBE的be.conf里需要额外配置这些参数# 存算分离模式开关 enable_storage_service true # 共享存储类型这里用S3兼容的MinIO storage_backend s3 # MinIO的Endpoint s3_endpoint http://minio:9000 # 访问密钥 s3_access_key minioadmin s3_secret_key minioadmin # 存储桶名称 s3_bucket doris-data # 是否使用路径风格访问MinIO需要开启 s3_use_path_style true这里有个容易踩的坑s3_use_path_style这个参数。AWS S3默认用的是虚拟主机风格bucket.s3.amazonaws.com但MinIO默认只支持路径风格minio:9000/bucket。如果不开启这个参数BE会连不上MinIO报错信息还特别隐晦只说连接失败不告诉你是因为风格不匹配。3.4 MinIO共享存储的部署细节MinIO的部署相对简单但有几个细节要注意。首先是数据目录的挂载MinIO的数据要持久化到宿主机否则容器一删数据就没了。其次是访问密钥测试环境用默认的minioadmin/minioadmin没问题但生产环境一定要改。minio: image: minio/minio:latest container_name: minio hostname: minio networks: doris-net: aliases: - minio ports: - 9000:9000 - 9001:9001 environment: - MINIO_ROOT_USERminioadmin - MINIO_ROOT_PASSWORDminioadmin command: server /data --console-address :9001 volumes: - ./minio/data:/data deploy: resources: limits: cpus: 2 memory: 4GMinIO启动后需要手动创建一个名为doris-data的存储桶。可以通过MinIO控制台http://localhost:9001创建也可以用mc命令行工具创建。我一般用mc因为可以写进初始化脚本里自动化。# 下载mc客户端 wget https://dl.min.io/client/mc/release/linux-amd64/mc chmod x mc # 配置MinIO连接 ./mc alias set myminio http://localhost:9000 minioadmin minioadmin # 创建存储桶 ./mc mb myminio/doris-data # 验证 ./mc ls myminio3.5 完整docker-compose文件与启动顺序把上面的片段拼起来完整的docker-compose文件还需要定义网络和启动顺序。Doris的启动顺序很重要Meta Service → FE → BE。BE依赖FEFE依赖Meta Service如果顺序错了BE启动时会因为连不上FE而反复重试。networks: doris-net: driver: bridge ipam: config: - subnet: 172.20.0.0/16启动的时候用docker-compose up -d然后通过docker-compose logs -f观察日志。FE启动成功后会输出“FE started successfully”BE启动成功后会输出“BE started successfully”。如果看到反复重试的日志大概率是依赖服务没起来或者配置不对。4. 集群初始化与验证实操4.1 FE与BE的注册流程容器全部启动之后FE和BE并不会自动组成集群需要手动注册。FE的注册通过MySQL客户端连接FE的9030端口执行SQL完成。# 连接FE mysql -h 127.0.0.1 -P 9030 -uroot # 查看BE节点状态 SHOW BACKENDS;刚启动的时候SHOW BACKENDS可能返回空因为BE还没有注册到FE。BE注册有两种方式一种是在BE的be.conf里配置fe_servers参数BE启动时会自动向FE注册另一种是手动通过SQL添加。我推荐自动注册省事。如果自动注册没成功检查BE日志里有没有“register to FE failed”之类的错误。常见原因是FE的RPC端口没开、网络别名解析不了、或者FE还没完全启动BE就急着注册了。4.2 存算分离模式的功能验证集群注册成功后需要验证存算分离模式是否真正生效。最直接的方法是建表、插数据、查数据然后去MinIO里看数据文件是不是真的存在共享存储上。-- 创建数据库 CREATE DATABASE test_db; -- 创建表 USE test_db; CREATE TABLE test_table ( id INT, name VARCHAR(50), create_time DATETIME ) DUPLICATE KEY(id) DISTRIBUTED BY HASH(id) BUCKETS 3 PROPERTIES ( replication_num 1 ); -- 插入数据 INSERT INTO test_table VALUES (1, test1, NOW()), (2, test2, NOW()); -- 查询数据 SELECT * FROM test_table;插入数据后去MinIO控制台看doris-data存储桶里有没有生成对应的数据文件。如果有说明存算分离生效了。如果没有检查BE的be.conf里存储配置是否正确以及BE日志里有没有上传失败的错误。提示存算分离模式下replication_num参数的含义和存算一体不同。存算一体里这个参数控制数据副本数存算分离里数据副本由共享存储保证这个参数一般设为1即可。4.3 计算节点弹性扩缩容测试存算分离最大的卖点就是计算节点可以弹性扩缩容。测试方法很简单再启动一个BE容器注册到同一个FE然后观察查询是否能自动利用新节点。# 启动第二个BE docker-compose up -d --scale doris-be2注意用--scale扩容的时候容器的hostname和网络别名会冲突因为docker-compose默认给每个副本相同的别名。解决办法是在docker-compose里不指定固定的container_name和hostname让Docker自动生成然后通过环境变量传入不同的BE地址。扩容后在FE里执行SHOW BACKENDS应该能看到两个BE节点。然后跑一个稍微复杂的查询通过EXPLAIN看查询计划是否分配到了两个节点上。缩容就更简单了直接docker-compose stop掉一个BE容器然后在FE里执行ALTER SYSTEM DECOMMISSION BACKEND be_host:be_port等数据迁移完成后节点会自动下线。存算分离模式下因为数据在共享存储上下线节点不需要迁移数据速度比存算一体快很多。5. 常见问题排查与避坑经验5.1 容器启动失败类问题问题一FE启动报“meta service connection refused”这个几乎是最常见的问题。原因通常是Meta Service没启动或者FE配置里的meta_service_endpoint地址写错了。排查步骤先docker-compose ps看Meta Service容器是不是Up状态然后docker-compose logs doris-meta看有没有报错。如果Meta Service正常检查FE的fe.conf里meta_service_endpoint参数格式必须是meta-service:9010不能用localhost或者127.0.0.1因为容器里的localhost指向容器自己。问题二BE启动报“s3 endpoint connection failed”这个通常是MinIO没起来或者BE配置里的s3_endpoint地址不对。注意BE容器里访问MinIO要用Docker网络别名minio:9000不能用localhost:9000。另外检查MinIO的存储桶是否已经创建如果桶不存在BE上传数据时会报错。问题三Docker Desktop报“virtualization support not detected”这个问题在Windows上特别常见原因是BIOS里没开启虚拟化支持或者Hyper-V和WSL2冲突。解决办法进BIOS开启Intel VT-x或AMD-V然后在Windows功能里确保WSL2已启用。如果还是不行试试在Docker Desktop设置里切换后端为WSL2。5.2 集群通信类问题问题BE注册到FE失败日志显示“connect to FE failed”排查思路分三步。第一步确认FE的RPC端口默认9020在Docker网络内可访问可以在BE容器里telnet fe 9020测试。第二步检查FE的fe.conf里priority_networks参数这个参数决定了FE监听哪个网段的地址如果配错了FE可能只监听127.0.0.1导致BE连不上。第三步检查BE的be.conf里fe_servers参数格式必须是fe:9020端口是FE的RPC端口不是MySQL端口。5.3 存算分离特有问题问题数据写入成功但MinIO里看不到文件这个通常是因为BE配置里s3_use_path_style没开启或者存储桶名称写错了。另外注意Doris在存算分离模式下数据不是实时上传到共享存储的而是先写到本地缓存然后异步上传。如果刚插入数据就去MinIO看可能还没上传完。等几秒钟再刷新。问题查询报“missing file in shared storage”这个错误说明BE在共享存储上找不到需要的数据文件。常见原因是MinIO里的数据被误删或者BE的存储配置变更后没有重新同步元数据。解决办法检查MinIO里的文件是否完整然后在FE里执行ADMIN REPAIR TABLE尝试修复。5.4 常见问题速查表问题现象可能原因排查命令解决方案FE启动失败Meta Service未启动docker-compose logs doris-meta先启动Meta ServiceBE注册失败FE RPC端口不通telnet fe 9020检查网络和端口配置数据上传失败MinIO连接配置错误docker-compose logs doris-be检查s3_endpoint和密钥查询性能差BE内存不足docker stats增加BE内存限制容器频繁重启资源限制过严docker events调整CPU和内存限制提示排查Doris问题的时候日志是最重要的线索。FE日志在./fe/log/fe.logBE日志在./be/log/be.INFO。遇到问题先看日志比盲目搜索效率高得多。6. 性能调优与生产化建议6.1 测试环境到生产环境的配置差异测试环境跑通不代表生产环境能用这两者之间的配置差异主要体现在三个方面高可用、安全、监控。高可用方面生产环境FE至少部署3个节点Meta Service也要多副本。BE根据计算需求部署多个节点。Docker Compose适合单机测试生产环境建议用Kubernetes或者Docker Swarm做编排才能实现真正的弹性扩缩容和故障自愈。安全方面测试环境用默认密码没问题生产环境必须改MinIO的访问密钥FE的root密码也要设置强密码。另外Doris支持SSL加密通信生产环境建议开启。监控方面Doris暴露了Prometheus格式的监控指标FE的8030端口和BE的8040端口都有/metrics接口。生产环境建议接入PrometheusGrafana重点监控查询延迟、BE内存使用率、共享存储读写带宽这几个指标。6.2 共享存储选型对比MinIO适合测试和中小规模场景但生产环境如果数据量很大可能需要考虑其他方案。这里对比几种常见的共享存储后端存储类型优势劣势适用场景MinIO部署简单S3兼容大规模性能有限测试、中小规模AWS S3弹性好免运维成本高依赖网络云上生产环境HDFS成熟稳定生态好运维复杂已有Hadoop集群共享文件系统延迟低扩展性差小规模高性能场景选型的核心考量是数据量、访问延迟要求、运维成本。如果数据量在TB级别以内MinIO完全够用。如果到了PB级别建议上云对象存储或者自建HDFS集群。6.3 查询性能优化要点存算分离模式下查询性能的瓶颈往往在共享存储的读取带宽上。因为每次查询都要从共享存储拉数据如果带宽不够查询就会变慢。优化方向有几个第一开启本地缓存。BE支持把从共享存储读取的数据缓存在本地磁盘上下次查询同样的数据就不用再远程读取了。在be.conf里配置enable_file_cache true并设置缓存目录和大小。第二合理设置分区和分桶。分区裁剪和分桶裁剪可以减少需要扫描的数据量从而减少从共享存储读取的数据量。这个和存算一体架构的优化思路一致但在存算分离下效果更明显。第三调整BE的并发度。存算分离下BE的并发读取能力直接影响查询速度可以通过be.conf里的max_concurrent_remote_read参数调整。注意本地缓存虽然能提升性能但会占用BE的本地磁盘空间。缓存大小要根据BE磁盘容量合理设置不要设得太大导致磁盘写满。6.4 数据备份与恢复策略存算分离架构下数据都在共享存储上备份策略和存算一体不同。存算一体需要备份每个BE上的数据存算分离只需要备份共享存储上的数据。MinIO支持版本控制和桶复制可以用来做数据备份。元数据的备份同样重要。FE的元数据在doris-meta目录下建议定期打包备份。Meta Service的元数据也要备份。恢复的时候先恢复Meta Service再恢复FE最后启动BE。# 备份FE元数据 tar -czf fe-meta-backup-$(date %Y%m%d).tar.gz ./fe/doris-meta # 备份MinIO数据使用mc mirror ./mc mirror myminio/doris-data /backup/doris-data这套Docker部署方案我在三个项目里实际用过从开发机单机测试到测试环境三节点集群都跑过。最深的体会是存算分离的配置复杂度比存算一体高不少但一旦跑通后续的扩缩容和运维确实省心。尤其是计算节点可以随便加减这一点在应对突发查询压力的时候特别有用。如果你也在折腾Doris存算分离希望这篇内容能帮你少走点弯路。后面如果要做生产化部署建议把Docker Compose换成Kubernetes再配合CI/CD做自动化部署那又是另一个话题了。
02
RELATED NEWS

相关资讯

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

03
WHY YAOTU

想打造同款高转化官网?

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

场景化定制

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

营销型架构

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

全周期服务

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

免费获取你的建站方案

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