最近在尝试用 Docker 部署 Apache Doris 集群,本以为照着官方文档就能一帆风顺,结果在 FE(Frontend)和 BE(Backend)节点的配置与注册环节踩了不少坑。从镜像拉取、网络配置到节点状态反复异常,每一步都可能遇到意想不到的问题。本文将基于这些实战踩坑经验,为你梳理一套完整的 Docker 部署 Doris 的避坑指南,重点解决 FE/BE 节点无法正确注册、通信失败等核心难题。无论你是想快速搭建测试环境,还是为生产部署探路,这篇从零到一的实战记录都能帮你省下大量排查时间。
1. 背景与核心概念:为什么选择 Docker 部署 Doris?
在深入踩坑细节之前,我们有必要先厘清几个关键概念。Apache Doris 是一个基于 MPP 架构的高性能、实时的分析型数据库。它主要由两类节点组成:
- FE (Frontend):前端节点,负责元数据管理、集群管理、用户请求的接入和查询计划的生成。一个集群中通常有多个 FE 节点以实现高可用,其中一个为 Leader。
- BE (Backend):后端节点,负责数据存储和查询计划的执行。它是真正干“体力活”的节点,可以水平扩展。
那么,为什么我们要用 Docker 来部署 Doris 呢?对于开发、测试以及希望快速体验 Doris 功能的同学来说,Docker 部署具有显著优势:
- 环境隔离:避免污染宿主机环境,依赖全部封装在镜像内。
- 快速部署与销毁:一条命令即可启动一个完整的 Doris 组件,测试完成后可彻底清理。
- 版本管理:可以轻松切换不同版本的 Doris 进行测试。
- 简化运维:配置和部署过程标准化,易于复现和分享。
然而,Docker 的隔离性也带来了挑战,尤其是网络通信和持久化存储。FE 和 BE 节点之间、客户端与 FE 之间都需要稳定的网络连接。在 Docker 中,如果使用默认的bridge网络,容器间的通信需要特别注意。此外,Doris 的元数据和数据都需要持久化,否则容器重启后数据将丢失。这些正是我们踩坑的“高发区”。
2. 环境准备与版本说明
在开始操作前,请确保你的环境满足以下要求。本文的示例基于最常见的 Linux 环境,但原理同样适用于其他平台。
- 操作系统:Ubuntu 20.04 LTS 或 CentOS 7.9+(本文以 Ubuntu 为例)。
- Docker 引擎:版本 20.10.0 及以上。确保 Docker 服务已启动。
# 检查Docker版本及状态 docker --version sudo systemctl status docker - Docker Compose:版本 v2.0.0 及以上。虽然我们可以用纯
docker run命令部署,但使用docker-compose.yml能更好地管理多容器应用。建议安装。 - Apache Doris 镜像:我们将使用官方提供的镜像。截至本文撰写时,一个稳定且常用的版本是
apache/doris:1.2.4-fe-x86_64和apache/doris:1.2.4-be-x86_64。请注意,FE 和 BE 有独立的镜像。 - 系统资源:建议为 Docker 分配至少 4GB 内存。BE 节点对内存要求较高,尤其是在执行复杂查询时。
重要提示:Doris 版本迭代较快,部署命令和部分配置可能随版本变化。本文的核心是思路和方法,当你在实际操作时,请务必以你所使用的 Doris 版本对应的官方文档为最终依据。如果遇到命令报错,首先检查版本兼容性。
3. 核心原理与部署规划
在动手敲命令之前,合理的规划能避免很多后续的麻烦。我们需要决定两件事:网络方案和存储方案。
3.1 网络方案选择:Bridge 还是 Host?
这是决定节点能否成功通信的关键。
- Bridge 网络(默认):容器连接到 Docker 创建的虚拟网桥(如
docker0),拥有独立的 IP 地址。容器间可以通过 IP 或容器名通信(需要自定义网络或使用--link,后者已废弃)。优点是隔离性好。缺点是容器 IP 可能变动,且需要显式配置容器间的网络发现。 - Host 网络:容器直接使用宿主机的网络命名空间,共享宿主机的 IP 和端口。优点是网络性能最好,配置简单,容器间、容器与宿主机间通信就像本地进程一样。缺点是隔离性差,端口冲突风险高。
对于 Doris 集群部署,强烈建议在测试环境使用host网络模式。这能彻底避免容器间网络不通的诡异问题。FE 和 BE 会使用宿主机IP进行注册和心跳,非常直观。
3.2 存储卷规划:数据不能丢
Doris 有两类重要数据需要持久化:
- FE 元数据:位于
{FE_HOME}/doris-meta/。记录了库、表、分区、副本、集群节点等所有元信息。必须持久化,否则集群信息将丢失。 - BE 数据:位于
{BE_HOME}/storage/。存储了实际的表数据。必须持久化。
我们将使用 Docker 的-v参数或 Docker Compose 的volumes配置,将宿主机的目录挂载到容器内的上述路径。
3.3 部署架构图(逻辑)
我们计划部署一个最小化的集群:1个 FE(单节点,同时也是 Leader)和 2个 BE。
宿主机 (Host Machine) ├── Docker Container (FE) │ ├── 使用 host 网络 │ └── 元数据卷:/opt/doris-fe/doris-meta -> /data/doris/fe/doris-meta ├── Docker Container (BE-1) │ ├── 使用 host 网络 │ └── 数据卷:/opt/doris-be/storage -> /data/doris/be1/storage └── Docker Container (BE-2) ├── 使用 host 网络 └── 数据卷:/opt/doris-be/storage -> /data/doris/be2/storage所有容器都使用--net=host,因此它们对外(彼此和客户端)表现的 IP 就是宿主机的 IP。
4. 完整实战部署:一步步搭建集群
接下来,我们进入实战环节。我们将分别使用docker run命令和docker-compose两种方式来部署,后者更优雅,适合管理。
4.1 方式一:使用 Docker Run 命令部署
步骤1:创建持久化数据目录在宿主机上创建用于挂载的目录。
sudo mkdir -p /data/doris/fe/doris-meta sudo mkdir -p /data/doris/be1/storage sudo mkdir -p /data/doris/be2/storage # 为了方便,修改目录权限(生产环境请严格设置权限) sudo chmod -R 777 /data/doris/步骤2:启动 Frontend (FE) 节点
docker run -d \ --name doris-fe \ --net=host \ -v /data/doris/fe/doris-meta:/opt/doris-fe/doris-meta \ -e FE_SERVERS="fe1:192.168.1.100:9010" \ -e FE_ID=1 \ apache/doris:1.2.4-fe-x86_64参数拆解与踩坑点:
--net=host: 使用主机网络。-v ...: 将宿主机目录挂载到容器内元数据路径。务必确认路径正确,这是元数据持久化的关键。-e FE_SERVERS: 设置 FE 服务器列表。格式为fe_name:fe_host:edit_log_port。这里我们只有一个 FE,192.168.1.100需要替换为你宿主机的真实IP,不能是127.0.0.1或localhost,因为 BE 需要通过网络连接它。9010是 FE 的编辑日志端口。-e FE_ID: 指定 FE 节点的唯一 ID,从 1 开始。单节点设为 1。- 镜像标签:确保镜像标签与你想要的版本一致。
步骤3:启动 Backend (BE) 节点启动第一个 BE 节点:
docker run -d \ --name doris-be-1 \ --net=host \ -v /data/doris/be1/storage:/opt/doris-be/storage \ -e FE_SERVERS="fe1:192.168.1.100:9010" \ -e BE_ADDR="192.168.1.100:9050" \ apache/doris:1.2.4-be-x86_64启动第二个 BE 节点(注意修改名字、存储卷和 BE_ADDR 端口):
docker run -d \ --name doris-be-2 \ --net=host \ -v /data/doris/be2/storage:/opt/doris-be/storage \ -e FE_SERVERS="fe1:192.168.1.100:9010" \ -e BE_ADDR="192.168.1.100:9051" \ apache/doris:1.2.4-be-x86_64参数拆解与踩坑点:
-e FE_SERVERS:必须与启动 FE 时设置的值完全一致。这是 BE 寻找 FE 领导节点的依据。-e BE_ADDR: 指定 BE 节点的对外服务地址。格式为be_host:heartbeat_service_port。be_host同样必须是宿主机的真实 IP。端口必须不同(如 9050, 9051),否则第二个 BE 会因端口冲突无法启动。- 存储卷:每个 BE 必须使用独立的宿主机目录,防止数据混乱。
步骤4:检查容器状态
docker ps你应该看到三个状态为Up的容器:doris-fe,doris-be-1,doris-be-2。
4.2 方式二:使用 Docker Compose 部署(推荐)
使用 Docker Compose 可以通过一个配置文件管理所有服务,更加清晰和便捷。
步骤1:创建docker-compose.yml文件
version: '3.8' services: doris-fe: image: apache/doris:1.2.4-fe-x86_64 container_name: doris-fe hostname: doris-fe network_mode: "host" # 使用主机网络 environment: FE_SERVERS: "fe1:192.168.1.100:9010" FE_ID: 1 volumes: - /data/doris/fe/doris-meta:/opt/doris-fe/doris-meta restart: unless-stopped doris-be-1: image: apache/doris:1.2.4-be-x86_64 container_name: doris-be-1 hostname: doris-be-1 network_mode: "host" environment: FE_SERVERS: "fe1:192.168.1.100:9010" BE_ADDR: "192.168.1.100:9050" volumes: - /data/doris/be1/storage:/opt/doris-be/storage restart: unless-stopped depends_on: - doris-fe doris-be-2: image: apache/doris:1.2.4-be-x86_64 container_name: doris-be-2 hostname: doris-be-2 network_mode: "host" environment: FE_SERVERS: "fe1:192.168.1.100:9010" BE_ADDR: "192.168.1.100:9051" volumes: - /data/doris/be2/storage:/opt/doris-be/storage restart: unless-stopped depends_on: - doris-fe注意:请将文件中所有的192.168.1.100替换为你宿主机的真实 IP。
步骤2:启动集群在包含docker-compose.yml文件的目录下执行:
# 启动所有服务 docker-compose up -d # 查看服务状态 docker-compose ps # 查看日志(可用于排错) docker-compose logs -f doris-fe5. 节点配置、注册与验证
容器启动成功只是第一步,更关键的是 FE 和 BE 节点是否正常启动并成功加入集群。
5.1 验证 FE 节点状态
FE 启动后,需要一点时间进行初始化。我们可以通过 MySQL 客户端连接 FE 进行验证。
# 使用宿主机IP和FE查询端口(默认为9030)进行连接 mysql -h 192.168.1.100 -P 9030 -uroot如果连接成功,会看到 MySQL 提示符。执行以下命令:
-- 查看 FE 节点状态 SHOW PROC '/frontends'\G预期结果:你应该看到一条记录,其中Name为你设置的fe1(或doris-fe),Role为FOLLOWER或LEADER(单节点时即为 LEADER),IsMaster为true,并且Alive列为true。这表示 FE 节点运行正常。
5.2 添加并验证 BE 节点
BE 节点启动后,并不会自动加入集群,需要手动通过 FE 添加。 在刚才的 MySQL 客户端中执行:
-- 添加第一个BE节点,IP为宿主机IP,端口为BE的心跳端口(默认为9050) ALTER SYSTEM ADD BACKEND "192.168.1.100:9050"; -- 添加第二个BE节点,端口为9051 ALTER SYSTEM ADD BACKEND "192.168.1.100:9051";添加成功后,查询 BE 状态:
SHOW PROC '/backends'\G预期结果:你应该看到两条记录,对应两个 BE 节点。重点关注以下几列:
Alive: 必须为true。如果为false,说明 FE 无法连接到该 BE 的心跳端口。SystemDecommissioned和ClusterDecommissioned: 必须为false。LastHeartbeat: 显示最近一次心跳时间,应该是几秒内。ErrMsg: 如果Alive为false,这里会显示错误信息。
5.3 核心踩坑点:BE 状态为false的排查
这是 Docker 部署中最常见的问题。如果SHOW BACKENDS;显示 BE 的Alive状态为false,请按以下顺序排查:
检查网络连通性:在 FE 容器内,尝试 ping 或 telnet BE 的 IP 和心跳端口。
# 进入FE容器 docker exec -it doris-fe /bin/bash # 尝试连接BE心跳端口(示例) telnet 192.168.1.100 9050- 如果无法连通:根本原因是网络问题。确保所有容器都使用
--net=host,且FE_SERVERS和BE_ADDR中的 IP 是宿主机的、可被路由的正确 IP,而不是容器内部IP。
- 如果无法连通:根本原因是网络问题。确保所有容器都使用
检查 BE 日志:查看 BE 容器的日志,看是否有启动错误。
docker logs --tail 100 doris-be-1常见错误:端口被占用、存储路径权限不足、配置文件错误。
检查 FE 日志:查看 FE 容器的日志,看添加 BE 时是否有报错。
docker logs --tail 100 doris-fe确认
be.conf配置:虽然我们通过环境变量传递了主要配置,但有时需要确认容器内的配置文件。进入 BE 容器检查:docker exec -it doris-be-1 cat /opt/doris-be/conf/be.conf | grep -E "priority_networks|heartbeat_service_port"确保
priority_networks配置正确(在 host 网络下通常不需要特别设置),heartbeat_service_port与你设置的BE_ADDR端口一致。防火墙/SELinux:确保宿主机防火墙开放了 FE(9010,9030)和 BE(9050,9051,8060)相关端口的访问。
6. 基本功能测试
节点状态正常后,我们进行一个简单的测试,验证集群基本功能。
-- 1. 创建测试数据库 CREATE DATABASE docker_test_db; USE docker_test_db; -- 2. 创建测试表 CREATE TABLE test_table ( user_id INT, user_name VARCHAR(50), score DECIMAL(10, 2) ) ENGINE=OLAP DUPLICATE KEY(user_id) DISTRIBUTED BY HASH(user_id) BUCKETS 8 PROPERTIES ( "replication_num" = "2" -- 副本数,小于等于BE数量 ); -- 3. 插入测试数据 INSERT INTO test_table VALUES (1, 'Alice', 95.5), (2, 'Bob', 88.0), (3, 'Charlie', 92.3); -- 4. 查询数据 SELECT * FROM test_table; -- 5. 查看表的数据分布,确认数据成功写入BE SHOW TABLES; -- 可以通过 `SHOW DATA` 查看数据库容量,但新插入数据可能需要一点时间才能统计如果以上步骤都能成功执行,恭喜你,一个基于 Docker 的 Apache Doris 集群已经成功部署并运行起来了!
7. 常见问题与排查思路汇总
下表总结了部署过程中可能遇到的典型问题及解决方案:
| 问题现象 | 可能原因 | 排查思路与解决方案 |
|---|---|---|
docker run启动容器立刻退出 | 镜像拉取失败、启动命令错误、配置错误导致进程退出。 | 1.docker logs [容器ID]查看退出日志。2. 检查镜像名和标签是否正确。 3. 检查挂载卷路径是否存在且权限正确。 |
| FE 启动失败,元数据目录错误 | doris-meta目录权限不足或路径错误。 | 1. 确保宿主机目录存在:ls -ld /data/doris/fe/doris-meta。2. 确保容器内进程有写权限: chmod 777 /data/doris/fe/doris-meta(测试环境)。 |
MySQL 客户端无法连接 FE (ERROR 2003) | FE 未成功启动、网络不通、端口错误、防火墙。 | 1.docker ps确认 FE 容器运行中。2. docker logs doris-fe查看 FE 启动日志,确认9030端口监听成功。3. 在宿主机执行 telnet 127.0.0.1 9030测试端口连通性。4. 检查防火墙规则。 |
SHOW PROC ‘/backends’显示 BEAlive为false | 最常见问题。FE 无法与 BE 建立心跳连接。 | 1.核心检查:FE_SERVERS和BE_ADDR中的 IP 必须是宿主机可路由的真实 IP,非127.0.0.1。2. 确认所有容器使用 --net=host。3. 检查 BE 心跳端口(如9050)是否被占用或防火墙拦截。 4. 分别查看 FE 和 BE 的日志寻找连接错误。 |
执行ALTER SYSTEM ADD BACKEND时报错backend already exists | 该 BE 地址之前已被添加过。 | 1. 先执行SHOW BACKENDS;查看是否已存在。2. 如果已存在且状态异常,需要先移除: ALTER SYSTEM DECOMMISSION BACKEND “ip:port”;或ALTER SYSTEM DROP BACKEND “ip:port”;(谨慎使用 DROP)。 |
数据插入失败或查询报错No available backends | BE 节点状态异常、副本数设置大于可用 BE 数。 | 1. 确认SHOW BACKENDS;中所有 BE 的Alive为true。2. 建表时 PROPERTIES中的”replication_num”不能大于当前健康的 BE 节点数量。单 BE 时设为 1。 |
| 容器重启后数据丢失 | 未配置持久化存储卷。 | 确保docker run或docker-compose.yml中正确配置了-v或volumes,将doris-meta和storage目录挂载到宿主机。 |
8. 最佳实践与工程建议
将 Doris 用于更严肃的开发或测试环境时,可以参考以下建议:
生产环境慎用 Host 网络:虽然
host网络简化了测试部署,但在生产环境中,出于安全和隔离考虑,建议使用自定义的 Docker 桥接网络,并仔细规划容器间的 DNS 解析或使用静态 IP,确保 FE 和 BE 能通过容器名可靠通信。配置分离与管理:不要只依赖环境变量。对于复杂的配置,可以将自定义的
fe.conf和be.conf配置文件通过卷挂载到容器内的/opt/doris-fe/conf/和/opt/doris-be/conf/目录,覆盖镜像默认配置。这样更易于版本管理和批量修改。资源限制:为 Docker 容器设置合理的 CPU 和内存限制,避免单个容器耗尽宿主机资源。
# 在 docker-compose.yml 中示例 services: doris-be-1: ... deploy: resources: limits: cpus: '2.0' memory: 8G监控与日志:将 Doris 容器的日志(位于容器内
/opt/doris-fe/log/和/opt/doris-be/log/)挂载到宿主机统一的日志目录,便于使用 ELK 等工具进行收集和分析。同时,可以暴露 Doris 的 JMX 指标,接入 Prometheus 监控体系。高可用部署:对于 FE,生产环境至少部署 3 个节点(1 Leader + 2 Follower)以实现高可用。部署多个 FE 时,需要为每个 FE 设置不同的
FE_ID和正确的FE_SERVERS列表(包含所有 FE 信息)。备份与恢复:定期备份挂载到宿主机的元数据 (
doris-meta) 目录。虽然 Doris 自身有副本机制,但元数据的备份是集群恢复的最后保障。版本升级:Docker 升级相对简单,但需谨慎。建议流程:a) 备份元数据和重要数据。b) 在测试环境用新镜像部署新集群并导入数据测试。c) 生产环境采用逐个容器替换的方式,先升级 BE,最后升级 FE Leader。
通过以上步骤和最佳实践,你应该能够顺利搭建并管理一个 Docker 化的 Apache Doris 集群。记住,理解 FE 和 BE 的通信机制、重视网络配置和持久化存储,是避开大多数“坑”的关键。遇到问题时,多查看容器日志,善用SHOW PROC命令观察集群状态,大部分难题都能迎刃而解。