Docker Compose 部署 Doris 存算分离集群实战指南
2026/9/24 12:42:50 网站建设 项目流程

1. 为什么要在 Docker 里折腾 Doris 存算分离

第一次接触 Doris 存算分离架构的时候,我脑子里冒出来的第一个问题就是:好好的存算一体不用,为什么要拆开?后来在一个日志分析项目里被现实教育了——计算节点和存储节点绑死,扩容只能整体扩,存储不够了加机器,算力跟着浪费;算力不够了加机器,存储又冗余一堆。成本压不下来,运维还特别别扭。存算分离就是来解决这个矛盾的:把数据放到共享存储上,计算节点变成无状态,需要多少算力就起多少计算节点,存储按实际用量独立扩展。

Doris 从 3.0 版本开始正式支持存算分离模式,底层依赖共享存储来存放数据,计算节点通过缓存机制加速热数据访问。这个架构特别适合云原生环境,也特别适合用 Docker 来快速搭建验证环境。我这次就是在一台开发机上,用 Docker Compose 把整套 Doris 存算分离集群跑起来,包括元数据服务、共享存储、计算节点和前端节点。

你可能会问,为什么不用官方的一键部署脚本?原因很简单:存算分离涉及多个组件的协同,官方脚本对共享存储的配置有特定要求,而 Docker 方式能让你完全掌控每个组件的版本、网络和挂载配置。更重要的是,Docker 方式搭出来的环境可以随时销毁重建,对于学习和验证来说成本极低。这篇文章适合那些已经对 Doris 有基本了解、想动手试试存算分离架构的运维和开发人员,也适合想在自己机器上快速搭一套分析型数据库环境的数据工程师。

整个部署过程涉及几个核心组件:Doris 的 FE(前端节点,负责元数据管理和查询规划)、BE(后端节点,负责数据存储和计算)、共享存储层(这里我用 MinIO 来模拟对象存储)、以及 Docker 网络配置。我会把每一步的意图、参数选择的理由、以及我踩过的坑都讲清楚,让你能直接抄作业。

2. 部署前的整体设计与组件选型思路

2.1 存算分离架构的核心变化

存算一体模式下,BE 节点既管存储又管计算,数据落在本地磁盘上。存算分离模式下,BE 节点变成了无状态的计算节点,数据统一写到共享存储上,本地磁盘只用来做缓存。这个变化带来的直接影响是:BE 节点可以随时增减,不用担心数据丢失;存储容量和计算容量可以独立扩展;多集群可以共享同一份数据。

Doris 存算分离的架构里,FE 仍然负责元数据管理,但元数据也需要持久化到共享存储或者独立的元数据服务中。BE 节点启动时会从共享存储拉取数据分片的元信息,然后按需缓存热数据到本地。计算节点之间通过一致性哈希来分配数据分片,查询时如果本地缓存没有命中,就从共享存储读取。

这个架构对共享存储的要求比较高:需要支持高吞吐的顺序读写,需要兼容 S3 协议,延迟要尽量低。我用 MinIO 来模拟,因为它是开源的、兼容 S3 协议、Docker 部署极其简单,适合做验证环境。生产环境可以换成云厂商的对象存储或者其他兼容 S3 的分布式存储。

2.2 为什么选 Docker Compose 而不是单容器

单容器部署 Doris 存算分离几乎是不可能的,因为至少需要 FE、BE、共享存储三个组件,而且它们之间有网络通信和依赖关系。Docker Compose 能在一个 YAML 文件里定义所有服务、网络和卷,一条命令拉起整套环境,特别适合本地验证。

我对比过几种方案:手动 docker run 一个个起容器,网络配置和依赖顺序容易出错;用 Kubernetes 太重,本地开发机跑不动;用官方脚本又不够灵活。Docker Compose 刚好卡在中间,既有编排能力,又足够轻量。而且 Compose 文件本身就是最好的文档,谁拿到都能复现。

2.3 版本选择和资源规划

Doris 的存算分离功能在 3.0 版本之后才比较稳定,我选的是 3.0.x 的稳定版镜像。MinIO 用的是最新的稳定版。Docker 和 Docker Compose 的版本建议用较新的,因为涉及到一些网络和卷的特性。

资源方面,我给了 FE 2GB 内存、BE 4GB 内存、MinIO 1GB 内存。这是最低配了,再低跑起来会很卡。磁盘至少留 20GB 给 Docker 卷和镜像。CPU 核心数越多越好,BE 做查询的时候会吃满多核。

组件镜像版本内存建议CPU建议磁盘建议
Doris FE3.0.x2GB2核5GB
Doris BE3.0.x4GB4核10GB
MinIO最新稳定版1GB1核5GB

注意:BE 节点的内存不要低于 4GB,否则启动时可能因为内存不足直接退出,日志里会报 OOM 相关的错误。

3. 核心细节解析与实操要点

3.1 Docker 网络规划与容器互通

Docker Compose 默认会创建一个 bridge 网络,所有服务在同一个网络里可以通过服务名互相访问。这个特性对 Doris 部署特别重要,因为 FE 和 BE 之间需要频繁通信,BE 和 MinIO 之间需要传输数据。

我定义了一个自定义网络doris-net,子网用172.20.0.0/16。为什么要自定义子网?因为默认的 Docker 网络子网可能和宿主机所在网段冲突,导致容器无法访问外网或者宿主机无法访问容器。自定义子网能避免这个问题。

在 Compose 文件里,每个服务都加入这个网络,然后通过服务名来配置连接地址。比如 BE 配置里写 MinIO 的地址就是http://minio:9000,FE 配置里写 BE 的地址就是be:9060。这种服务名解析是 Docker 内置的 DNS 功能,不需要额外配置。

3.2 共享存储的配置要点

MinIO 的部署很简单,但有几个参数必须注意。首先是MINIO_ROOT_USERMINIO_ROOT_PASSWORD,这两个是访问密钥,Doris 配置里要用到。其次是数据卷的挂载路径,我挂到/data下,确保容器重启后数据不丢。

创建 bucket 的时候,我建议用doris-data这个名字,和 Doris 配置里的 bucket 名称保持一致。bucket 的权限要设置成私有,因为这是内部数据存储,不需要公开访问。

MinIO 的 API 端口是 9000,控制台端口是 9001。Doris 只需要 API 端口,控制台端口是用来在浏览器里管理 bucket 的。两个端口都映射到宿主机,方便调试。

3.3 Doris FE 和 BE 的关键配置项

FE 的配置里,meta_dir要指向一个持久化的卷,否则容器重启后元数据丢失,整个集群就废了。http_port默认是 8030,rpc_port默认是 9020,query_port默认是 9030。这些端口都要在 Compose 文件里映射出来,方便宿主机访问。

BE 的配置里,最关键的是storage_root_path和共享存储相关的配置。存算分离模式下,BE 需要知道共享存储的地址、密钥、bucket 名称。这些配置通过be.conf文件传入。另外,BE 的webserver_port默认是 8040,brpc_port默认是 8060,heartbeat_service_port默认是 9050。

还有一个容易忽略的点:FE 和 BE 的priority_networks配置。在 Docker 环境里,容器可能有多个网卡,Doris 需要知道用哪个网段来通信。我设置成172.20.0.0/16,和 Docker 子网保持一致。

# be.conf 关键配置示例 storage_root_path = /opt/apache-doris/be/storage priority_networks = 172.20.0.0/16 webserver_port = 8040 brpc_port = 8060 heartbeat_service_port = 9050

提示:priority_networks如果配错了,FE 会找不到 BE,日志里会一直报心跳超时。排查的时候先看这个配置。

3.4 环境变量与启动顺序控制

Docker Compose 的depends_on只能控制启动顺序,不能控制服务就绪状态。MinIO 启动很快,但 Doris FE 启动需要几十秒,BE 启动更慢。如果 BE 在 FE 还没就绪的时候就启动,BE 会注册失败。

我的做法是在 Compose 文件里用healthcheck来检测服务状态,然后让 BE 依赖 FE 的健康状态。MinIO 的 healthcheck 可以用mc ready local命令,FE 的 healthcheck 可以用curl检查 HTTP 端口。

healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8030/api/bootstrap"] interval: 10s timeout: 5s retries: 10

这个配置的意思是每 10 秒检查一次 FE 的 HTTP 端口,连续失败 10 次才认为不健康。BE 的depends_on里加上condition: service_healthy,就能确保 FE 完全启动后再启动 BE。

4. 完整实操过程与核心环节实现

4.1 环境准备与 Docker 安装检查

在开始之前,先确认 Docker 和 Docker Compose 已经安装好。用docker versiondocker compose version检查。如果还没装,Ubuntu 上可以用apt安装,CentOS 上用yum,Windows 和 macOS 直接装 Docker Desktop。

我遇到过一个问题:Docker Desktop 在 Windows 上启动时报virtualization support not detected,这是因为 BIOS 里的虚拟化支持没开。进 BIOS 把 Intel VT-x 或 AMD-V 打开就行。还有一个常见错误是failed to connect to the docker api at npipe,这通常是 Docker Desktop 没启动或者服务异常,重启一下就好。

磁盘空间也要检查,docker system df看看镜像和卷占了多少空间。如果空间不够,先docker system prune清理一下。

4.2 编写 Docker Compose 文件

Compose 文件是整个部署的核心,我把它拆成几个部分来写。首先是版本声明和网络定义:

version: "3.8" networks: doris-net: driver: bridge ipam: config: - subnet: 172.20.0.0/16

然后是 MinIO 服务:

services: minio: image: minio/minio:latest container_name: doris-minio networks: - doris-net ports: - "9000:9000" - "9001:9001" environment: MINIO_ROOT_USER: dorisadmin MINIO_ROOT_PASSWORD: dorisadmin123 volumes: - minio-data:/data command: server /data --console-address ":9001" healthcheck: test: ["CMD", "mc", "ready", "local"] interval: 10s timeout: 5s retries: 5

接着是 FE 服务:

fe: image: apache/doris:fe-3.0.3 container_name: doris-fe networks: - doris-net ports: - "8030:8030" - "9020:9020" - "9030:9030" environment: FE_SERVERS: "fe:9010" FE_ID: "1" volumes: - fe-meta:/opt/apache-doris/fe/doris-meta - ./fe.conf:/opt/apache-doris/fe/conf/fe.conf healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8030/api/bootstrap"] interval: 10s timeout: 5s retries: 10

最后是 BE 服务:

be: image: apache/doris:be-3.0.3 container_name: doris-be networks: - doris-net ports: - "8040:8040" - "8060:8060" - "9050:9050" environment: FE_SERVERS: "fe:9010" BE_ADDR: "be:9050" volumes: - be-storage:/opt/apache-doris/be/storage - ./be.conf:/opt/apache-doris/be/conf/be.conf depends_on: fe: condition: service_healthy minio: condition: service_healthy

volumes 部分定义持久化卷:

volumes: minio-data: fe-meta: be-storage:

这个 Compose 文件里,每个服务的配置都有明确的意图。MinIO 的 healthcheck 用mc ready local来检测,FE 的 healthcheck 用 HTTP 接口检测,BE 依赖这两个服务的健康状态。端口映射把容器内的端口暴露到宿主机,方便用 MySQL 客户端连接 Doris。

4.3 配置文件的详细参数说明

fe.conf 的关键配置:

# 元数据目录 meta_dir = /opt/apache-doris/fe/doris-meta # HTTP 端口 http_port = 8030 # RPC 端口 rpc_port = 9020 # 查询端口 query_port = 9030 # 编辑日志端口 edit_log_port = 9010 # 网络优先级 priority_networks = 172.20.0.0/16 # 存算分离模式 cloud_unique_id = 1

be.conf 的关键配置:

# 存储路径 storage_root_path = /opt/apache-doris/be/storage # 网络优先级 priority_networks = 172.20.0.0/16 # Web 服务端口 webserver_port = 8040 # BRPC 端口 brpc_port = 8060 # 心跳端口 heartbeat_service_port = 9050 # 共享存储配置 enable_file_cache = true file_cache_path = /opt/apache-doris/be/storage/cache # S3 兼容存储配置 aws_s3_endpoint = http://minio:9000 aws_s3_access_key = dorisadmin aws_s3_secret_key = dorisadmin123 aws_s3_bucket = doris-data aws_s3_region = us-east-1

这些配置里,cloud_unique_id是存算分离模式的标识,每个集群唯一。enable_file_cache开启本地缓存,能显著提升热数据查询性能。file_cache_path指定缓存目录,建议放在 SSD 上。

注意:aws_s3_region虽然 MinIO 不强制要求,但 Doris 的 S3 客户端需要这个参数,随便填一个合法的区域名就行,比如us-east-1

4.4 启动集群与初始化操作

配置文件准备好之后,在 Compose 文件所在目录执行:

docker compose up -d

这个命令会按依赖顺序启动所有服务。启动完成后,用docker compose ps查看状态,确保所有服务都是healthy

接下来要创建 MinIO 的 bucket。用mc客户端或者直接访问http://localhost:9001登录控制台创建。bucket 名称必须是doris-data,和 be.conf 里的配置一致。

然后进入 FE 容器,添加 BE 节点:

docker exec -it doris-fe bash mysql -h 127.0.0.1 -P 9030 -u root

在 MySQL 客户端里执行:

ALTER SYSTEM ADD BACKEND "be:9050";

这个命令把 BE 节点注册到 FE 中。执行完后用SHOW BACKENDS;查看状态,如果Alivetrue,说明 BE 注册成功。

4.5 验证存算分离是否生效

验证存算分离是否生效,最直接的方法是建表插入数据,然后看数据是否写到了 MinIO 里。先建一个测试库和表:

CREATE DATABASE test_db; USE test_db; CREATE TABLE test_table ( id INT, name VARCHAR(50) ) DISTRIBUTED BY HASH(id) BUCKETS 3 PROPERTIES ( "replication_num" = "1" );

插入几条数据:

INSERT INTO test_table VALUES (1, 'alice'), (2, 'bob'), (3, 'charlie');

然后去 MinIO 控制台看doris-databucket 里有没有文件生成。如果有,说明数据确实写到了共享存储上。再查一下数据:

SELECT * FROM test_table;

如果能查到数据,说明整个链路是通的。

还可以通过 BE 的 Web 界面查看缓存状态,访问http://localhost:8040,里面有缓存命中率和存储使用的统计信息。

5. 常见问题与排查技巧实录

5.1 BE 注册失败或心跳超时

这是最常见的问题。现象是SHOW BACKENDS;里 BE 的Alivefalse,或者 FE 日志里一直报心跳超时。排查思路分三步:先看网络通不通,再检查priority_networks配置,最后看端口有没有被占用。

网络排查用docker exec -it doris-be ping fe,如果能 ping 通说明网络没问题。priority_networks配置错了的话,BE 会用错误的网卡 IP 去注册,FE 自然找不到。端口占用用netstat -tlnp检查。

我遇到过一次 BE 注册失败,原因是be.confpriority_networks写成了172.20.0.0/24,但实际子网是172.20.0.0/16,网段不匹配导致 BE 选错了 IP。改成/16之后就好了。

5.2 共享存储连接失败

现象是 BE 启动时报 S3 连接错误,或者建表时提示存储不可用。排查的时候先确认 MinIO 的 bucket 是否存在,再检查密钥和 endpoint 配置。

docker exec -it doris-be curl http://minio:9000测试网络连通性。如果返回 XML 格式的错误信息,说明网络是通的,问题在认证配置上。检查aws_s3_access_keyaws_s3_secret_key是否和 MinIO 的环境变量一致。

还有一个坑是 bucket 名称大小写敏感。MinIO 的 bucket 名称必须全小写,如果写成Doris-Data会创建失败。Doris 配置里的 bucket 名称也要和实际创建的一致。

5.3 内存不足导致容器退出

BE 节点对内存比较敏感,如果宿主机内存不够,BE 容器会直接被 OOM Killer 杀掉。用docker logs doris-be看日志,如果最后几行是Killed或者Out of memory,就是内存不足。

解决办法有两个:一是给 BE 分配更多内存,在 Compose 文件里加mem_limit或者deploy.resources.limits.memory;二是调低 BE 的内存使用上限,在be.conf里设置mem_limit参数。我一般建议宿主机至少留 8GB 内存给 Docker。

5.4 查询性能不达预期

存算分离模式下,如果本地缓存没命中,查询需要从共享存储拉数据,延迟会比存算一体高。如果发现查询慢,先看缓存命中率。BE 的 Web 界面里有缓存统计,命中率低于 80% 就说明缓存配置有问题。

检查file_cache_path是否指向了 SSD,缓存目录的磁盘 IO 性能直接影响查询速度。另外enable_file_cache必须设为true,否则所有查询都走共享存储,性能会很差。

还有一个容易忽略的点是数据分桶数。分桶太少会导致单个分片数据量过大,缓存效率低。建表时根据数据量合理设置分桶数,一般建议每个分片 1GB 左右。

问题现象可能原因排查方法解决方案
BE 注册失败网络不通或 priority_networks 错误ping 测试、检查配置修正网段配置
存储连接失败密钥错误或 bucket 不存在curl 测试、检查 MinIO修正密钥和 bucket 名
容器退出内存不足查看容器日志增加内存或调低上限
查询慢缓存未命中或磁盘 IO 差查看缓存命中率开启缓存、换 SSD

5.5 实操心得与避坑清单

踩了这么多坑,我总结了几条经验。第一,Compose 文件里的 healthcheck 一定要配,不然启动顺序不可控,BE 大概率注册失败。第二,所有持久化卷都要显式声明,容器重启后数据不丢。第三,MinIO 的密钥不要用默认的,虽然验证环境无所谓,但养成好习惯。第四,BE 的缓存目录一定要放在性能好的磁盘上,机械硬盘会拖垮查询性能。

还有一个技巧:如果反复部署失败,先把所有容器和卷删掉重来。docker compose down -v会删除容器和卷,然后docker compose up -d重新拉起。这样能避免残留配置导致的奇怪问题。

提示:docker compose down -v会删除所有数据卷,生产环境慎用。验证环境随便删。

6. 集群扩展与后续优化方向

6.1 增加 BE 节点实现横向扩展

存算分离最大的优势就是计算节点可以随时扩展。在 Compose 文件里复制一份 BE 服务配置,改一下容器名和端口映射,然后docker compose up -d就能拉起新的 BE 节点。新节点启动后,在 FE 里执行ALTER SYSTEM ADD BACKEND注册,数据分片会自动重新平衡。

扩展的时候要注意,新 BE 节点的be.confpriority_networks和共享存储配置必须和现有节点一致。端口不能冲突,宿主机映射端口要错开。比如第一个 BE 映射 8040,第二个就映射 8041。

6.2 缓存策略调优

存算分离的性能很大程度上取决于缓存策略。Doris 支持按需缓存和预加载两种模式。按需缓存是查询时自动缓存热数据,预加载是提前把数据拉到本地。对于频繁查询的热数据,预加载能显著降低首次查询延迟。

缓存大小也要合理设置。file_cache_path所在磁盘的容量决定了缓存上限,一般建议缓存容量是热数据量的 1.5 倍。太小了缓存命中率低,太大了浪费磁盘。

6.3 监控与日志收集

生产环境一定要配监控。Doris 的 FE 和 BE 都暴露了 Prometheus 格式的指标接口,FE 的接口是http://fe:8030/metrics,BE 的是http://be:8040/metrics。用 Prometheus 抓取这些指标,再用 Grafana 做可视化,能实时看到集群状态。

日志方面,FE 和 BE 的日志都在容器内的/opt/apache-doris/*/log目录下。可以用 Docker 的日志驱动把日志转发到集中式日志系统,或者直接挂载到宿主机目录。

6.4 从验证环境到生产环境的差距

Docker Compose 搭出来的环境适合验证和学习,但直接上生产还有几个差距要补。首先是高可用,FE 需要至少三个节点做选举,BE 需要多副本。其次是存储的可靠性,MinIO 单节点没有冗余,生产要用分布式部署或者云对象存储。最后是网络和安全,生产环境需要配置 TLS 和访问控制。

我个人的建议是,先用 Docker Compose 把功能跑通,理解存算分离的工作原理和配置要点,然后再根据实际需求设计生产架构。Docker 环境里踩过的坑,在生产环境里大概率还会遇到,提前熟悉能省很多时间。

最后分享一个小技巧:Doris 的 FE 和 BE 都支持通过环境变量覆盖配置,在 Compose 文件里用environment字段就能动态调整参数,不用改配置文件。这个特性在调试的时候特别方便,改完重启容器就生效。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询