如果你正在寻找一个能快速上手、稳定运行的实时分析数据库,并且希望跳过繁琐的环境配置和依赖冲突,那么这篇文章就是为你准备的。
Doris(原名 Apache Doris)作为一款高性能、易扩展的实时分析数据库,近年来在数据仓库、OLAP 场景中备受关注。然而,对于很多开发者,尤其是个人或小团队而言,传统的物理机或虚拟机部署方式是一道不低的门槛:需要手动配置 Java 环境、处理系统依赖、调整内核参数,一个环节出错就可能让整个部署过程卡住,更别提后续的集群管理和扩容了。
这正是 Docker 的价值所在。通过 Docker 部署 Doris,你获得的不仅仅是一个“一键安装”的便利。它真正解决的是环境标准化和资源隔离问题。你可以在个人笔记本的 Docker Desktop 上快速搭建一个测试集群,其配置和运行方式与生产环境的 Kubernetes 集群保持高度一致。这极大地降低了学习、开发和测试的成本。
本文将提供一个超详细的 Docker 部署 Doris 的实战指南。我们不会止步于“跑起来就行”,而是会深入三个关键层面:
- 从零到一的完整流程:涵盖镜像拉取、容器启动、集群初始化到客户端连接的全过程。
- 生产级考量:讲解如何配置数据持久化、网络规划以及关键参数优化,让你的 Docker 环境更贴近真实使用场景。
- 避坑指南:汇总部署中最常见的错误,如端口冲突、权限问题、启动失败等,并提供清晰的排查思路。
无论你是想本地快速体验 Doris 功能,还是为团队搭建一个标准化的开发测试环境,这篇教程都能提供一条清晰、可复现的路径。
1. 为什么选择 Docker 部署 Doris?不止于方便
在深入操作之前,我们需要明确一个核心判断:用 Docker 部署 Doris,核心优势在于环境一致性与可移植性,而非极限性能。
对于数据库这类有状态服务,很多人对 Docker 化心存疑虑,担心网络和 I/O 性能损耗。这个顾虑有其道理,但对于 Doris 的学习、开发、测试以及中小数据量的原型验证场景,Docker 带来的收益远大于其微小的性能损失。
传统部署的典型痛点:
- 环境依赖复杂:需要特定版本的 Java(如 JDK 8/11),并可能涉及系统库(如
libtinfo)和内核参数(如vm.max_map_count)的调整。 - 污染主机环境:多个服务可能产生依赖冲突。
- 部署过程不透明:步骤繁琐,一旦失败,清理和重试成本高。
- 环境不一致:开发、测试、生产环境细微差异导致“在我机器上是好的”问题。
Docker 部署带来的改变:
- 环境隔离与封装:所有依赖(Java, 系统库)都打包在镜像内,与宿主机解耦。
- 一键启动与销毁:通过
docker run或docker-compose命令快速搭建完整环境,测试完后可彻底清理,不留痕迹。 - 标准化与可复现:镜像即环境,在任何装有 Docker 的机器上,运行同一镜像得到的环境完全一致。
- 简化集群模拟:通过 Docker 网络,可以轻松在单机上模拟出多节点(FE、BE)的 Doris 集群架构。
因此,如果你的目标是快速搭建一个用于功能验证、SQL 学习或应用开发的 Doris 环境,Docker 是最佳起点。对于生产环境,虽然也可以基于 Docker 和 Kubernetes 部署,但那涉及更复杂的存储、网络和编排设计,不在本文基础教程范围内。
2. 核心概念与架构预览
在动手部署前,快速理解 Doris 的核心组件和 Docker 部署的对应关系,能让你后续的配置和排错更有方向。
Doris 的核心组件:
- FE(Frontend):前端节点,负责元数据管理、集群管理、用户请求接入和查询计划生成。
- Leader/Follower:多个 FE 节点中,只有一个 Leader,负责写元数据;Follower 同步元数据并提供读服务。
- Observer:一种特殊的 FE,只同步元数据,用于扩展集群的查询能力,不参与选举。
- BE(Backend):后端节点,负责数据存储和查询执行。用户表的数据实际存储在 BE 节点上。
一个最小化的高可用 Doris 集群通常包含:1个 FE Leader + 至少1个 FE Follower + 至少3个 BE 节点。
Docker 部署的映射关系:当我们使用 Docker 时,每个 FE 或 BE 进程都运行在一个独立的容器中。这些容器通过 Docker 网络进行通信。我们需要重点关注:
- 容器间的网络互通:FE 和 BE 需要能通过主机名或 IP 相互发现和通信。
- 数据的持久化:BE 存储的数据以及 FE 存储的元数据必须映射到宿主机目录,否则容器重启后数据会丢失。
- 端口的暴露:需要将 Doris 的服务端口(如 FE 的 MySQL 协议端口
9030、HTTP 端口8030,BE 的9050等)映射到宿主机,以便从外部连接。
理解了这个模型,后面的配置命令就不再是魔法字符串了。
3. 环境准备:安装 Docker 与资源规划
3.1 安装 Docker
本文假设你已在目标机器上安装了 Docker。如果你的环境是干净的,可以参考以下快速命令(以 Ubuntu 22.04 为例):
# 更新软件包索引并安装必要工具 sudo apt-get update sudo apt-get install -y ca-certificates curl gnupg lsb-release # 添加 Docker 官方 GPG 密钥 sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg # 设置 Docker 稳定版仓库 echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null # 安装 Docker Engine sudo apt-get update sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin # 验证安装 sudo docker run hello-world对于 Windows/macOS 用户,请直接从 Docker 官网 下载并安装 Docker Desktop。
3.2 规划目录与网络
在开始前,规划好宿主机上的目录结构,便于管理数据和配置。
# 创建一个总工作目录,例如在 home 目录下 mkdir -p ~/doris-docker cd ~/doris-docker # 创建子目录用于持久化数据 mkdir -p storage/fe-meta storage/fe-log storage/be-data storage/be-log目录说明:
storage/fe-meta:持久化 FE 的元数据。storage/fe-log:存放 FE 的日志文件。storage/be-data:持久化 BE 的存储数据(Tablet 数据)。storage/be-log:存放 BE 的日志文件。
调整内核参数(Linux 必须):
Doris BE 进程对内存管理有一定要求,需要调整vm.max_map_count。
# 临时生效 sudo sysctl -w vm.max_map_count=2000000 # 永久生效,编辑 /etc/sysctl.conf,添加以下行 echo "vm.max_map_count=2000000" | sudo tee -a /etc/sysctl.conf sudo sysctl -p # 重新加载配置4. 部署单节点集群(快速体验)
我们先从最简单的单节点部署开始,即一个 FE(同时作为 Leader)和一个 BE 共存在一个容器内。这种方式仅适用于快速功能体验。
4.1 使用官方集成镜像
Apache Doris 社区提供了apache/doris:latest集成镜像,它包含了 FE 和 BE。
# 拉取最新镜像(也可以指定版本,如 apache/doris:2.0.4) docker pull apache/doris:latest # 运行容器 docker run -d \ --name doris-quickstart \ -p 9030:9030 \ # FE MySQL 协议端口 -p 8030:8030 \ # FE HTTP 端口(用于 Web UI) -p 8040:8040 \ # BE HTTP 端口 apache/doris:latest4.2 进入容器并启动服务
容器启动后,FE 和 BE 进程并未自动运行,需要进入容器手动启动。
# 进入容器 docker exec -it doris-quickstart bash # 在容器内,启动 FE /opt/apache-doris/fe/bin/start_fe.sh --daemon # 启动 BE /opt/apache-doris/be/bin/start_be.sh --daemon # 查看进程是否启动成功 ps aux | grep doris你应该能看到fe和be相关的 Java 进程。
4.3 连接与验证
现在,你可以从宿主机使用 MySQL 客户端连接 Doris。
# 安装 MySQL 客户端(如果尚未安装) # Ubuntu/Debian: sudo apt-get install -y mysql-client # CentOS/RHEL: sudo yum install -y mysql # 连接 Doris FE,默认用户为 root,密码为空 mysql -h 127.0.0.1 -P 9030 -uroot连接成功后,执行以下 SQL 验证集群状态:
-- 查看 FE 状态 SHOW PROC '/frontends'\G -- 查看 BE 状态,需要先添加 BE 到集群(在单节点镜像中,BE 可能已自动添加) -- 如果 SHOW PROC '/backends'; 显示 BE 未存活,则需要在 MySQL 客户端执行: ALTER SYSTEM ADD BACKEND "容器内BE的IP:9050"; -- 如何获取容器内IP?在容器内执行 `hostname -i` -- 例如:ALTER SYSTEM ADD BACKEND "172.17.0.2:9050"; -- 添加后再次查看 SHOW PROC '/backends'\G如果Alive列为true,则说明节点健康。
体验完毕,清理环境:
docker stop doris-quickstart docker rm doris-quickstart单节点模式虽然简单,但数据未持久化,且不适合进一步学习集群操作。接下来我们部署更接近生产逻辑的多容器独立节点集群。
5. 部署多节点集群(标准实践)
我们将部署一个经典的最小高可用集群:1 FE Leader + 1 FE Follower + 3 BE。每个组件运行在独立容器中,并使用自定义网络和数据卷。
5.1 创建 Docker 自定义网络
自定义网络能让容器通过容器名直接通信,比使用默认的bridge网络更便于管理。
docker network create doris-network5.2 启动第一个 FE(作为 Leader)
# 使用官方 fe 镜像 docker pull apache/doris:fe-latest # 启动 FE Leader 容器 docker run -d \ --name fe-leader \ --network doris-network \ --hostname fe-leader \ -p 9030:9030 \ # 对外暴露 MySQL 端口 -p 8030:8030 \ # 对外暴露 HTTP 端口 -v $(pwd)/storage/fe-meta:/opt/apache-doris/fe/doris-meta \ -v $(pwd)/storage/fe-log:/opt/apache-doris/fe/log \ -e FE_SERVERS="fe-leader:9010" \ apache/doris:fe-latest参数解释:
--network doris-network:加入自定义网络。--hostname fe-leader:设置容器主机名,用于集群内部通信。-v ...:/opt/apache-doris/fe/doris-meta:将元数据目录挂载到宿主机,实现持久化。-e FE_SERVERS:指定 FE 服务列表,当前只有自己。
5.3 初始化 FE 集群
等待 FE 容器启动几秒后,进入容器进行初始化。
# 进入 FE Leader 容器 docker exec -it fe-leader bash # 执行初始化脚本(仅第一次启动需要) /opt/apache-doris/fe/bin/start_fe.sh --daemon # 查看日志,等待 FE 启动完成(看到 `thrift server started` 等字样) tail -f /opt/apache-doris/fe/log/fe.log # 按 Ctrl+C 退出日志查看在宿主机上用 MySQL 客户端连接,并设置 root 密码。
mysql -h 127.0.0.1 -P 9030 -uroot-- 设置 root 密码(生产环境必须) SET PASSWORD FOR 'root' = PASSWORD('your_password_here'); -- 例如:SET PASSWORD FOR 'root' = PASSWORD('Doris@2024'); -- 创建用于后续添加 Follower 和 BE 的超级用户(可选但推荐) CREATE USER 'admin' IDENTIFIED BY 'admin_password'; GRANT ALL PRIVILEGES ON *.* TO 'admin';5.4 启动 FE Follower
docker run -d \ --name fe-follower \ --network doris-network \ --hostname fe-follower \ -v $(pwd)/storage/fe-follower-meta:/opt/apache-doris/fe/doris-meta \ -v $(pwd)/storage/fe-follower-log:/opt/apache-doris/fe/log \ -e FE_SERVERS="fe-leader:9010,fe-follower:9010" \ -e FE_ID=2 \ # ID 必须唯一,Leader 是 1 apache/doris:fe-latest进入容器并启动:
docker exec -it fe-follower bash /opt/apache-doris/fe/bin/start_fe.sh --helper fe-leader:9010 --daemon tail -f /opt/apache-doris/fe/log/fe.log--helper参数指向已存在的 Leader FE,新 Follower 会从 Leader 同步元数据。
5.5 启动三个 BE 节点
# 拉取 BE 镜像 docker pull apache/doris:be-latest # 启动 BE 1 docker run -d \ --name be-1 \ --network doris-network \ --hostname be-1 \ -v $(pwd)/storage/be-1-data:/opt/apache-doris/be/storage \ -v $(pwd)/storage/be-1-log:/opt/apache-doris/be/log \ -e FE_SERVERS="fe-leader:9010,fe-follower:9010" \ -e BE_ADDR="be-1:9050" \ apache/doris:be-latest # 启动 BE 2 docker run -d \ --name be-2 \ --network doris-network \ --hostname be-2 \ -v $(pwd)/storage/be-2-data:/opt/apache-doris/be/storage \ -v $(pwd)/storage/be-2-log:/opt/apache-doris/be/log \ -e FE_SERVERS="fe-leader:9010,fe-follower:9010" \ -e BE_ADDR="be-2:9050" \ apache/doris:be-latest # 启动 BE 3 docker run -d \ --name be-3 \ --network doris-network \ --hostname be-3 \ -v $(pwd)/storage/be-3-data:/opt/apache-doris/be/storage \ -v $(pwd)/storage/be-3-log:/opt/apache-doris/be/log \ -e FE_SERVERS="fe-leader:9010,fe-follower:9010" \ -e BE_ADDR="be-3:9050" \ apache/doris:be-latest分别进入每个 BE 容器启动服务:
# 以 be-1 为例 docker exec -it be-1 bash /opt/apache-doris/be/bin/start_be.sh --daemon tail -f /opt/apache-doris/be/log/be.log # 对 be-2, be-3 重复此操作5.6 将 BE 节点添加到集群
回到宿主机,使用 MySQL 客户端连接 FE Leader,添加所有 BE。
mysql -h 127.0.0.1 -P 9030 -uroot -p输入你之前设置的密码,然后执行:
-- 添加 BE 节点,使用容器名:端口(在 doris-network 内可解析) ALTER SYSTEM ADD BACKEND "be-1:9050"; ALTER SYSTEM ADD BACKEND "be-2:9050"; ALTER SYSTEM ADD BACKEND "be-3:9050"; -- 查看 BE 状态 SHOW PROC '/backends'\G检查输出,确保每个 BE 的Alive状态为true,SystemDecommissioned和ClusterDecommissioned为false。
6. 使用 Docker Compose 编排集群
手动运行多个docker run命令繁琐且易错。使用 Docker Compose 可以声明式地定义和管理整个集群。在~/doris-docker目录下创建docker-compose.yml文件:
version: '3.8' services: fe-leader: image: apache/doris:fe-latest container_name: fe-leader hostname: fe-leader ports: - "9030:9030" - "8030:8030" volumes: - ./storage/fe-meta:/opt/apache-doris/fe/doris-meta - ./storage/fe-log:/opt/apache-doris/fe/log environment: FE_SERVERS: "fe-leader:9010,fe-follower:9010" FE_ID: 1 networks: - doris-net command: /opt/apache-doris/fe/bin/start_fe.sh --daemon fe-follower: image: apache/doris:fe-latest container_name: fe-follower hostname: fe-follower volumes: - ./storage/fe-follower-meta:/opt/apache-doris/fe/doris-meta - ./storage/fe-follower-log:/opt/apache-doris/fe/log environment: FE_SERVERS: "fe-leader:9010,fe-follower:9010" FE_ID: 2 networks: - doris-net depends_on: - fe-leader command: /opt/apache-doris/fe/bin/start_fe.sh --helper fe-leader:9010 --daemon be-1: image: apache/doris:be-latest container_name: be-1 hostname: be-1 volumes: - ./storage/be-1-data:/opt/apache-doris/be/storage - ./storage/be-1-log:/opt/apache-doris/be/log environment: FE_SERVERS: "fe-leader:9010,fe-follower:9010" BE_ADDR: "be-1:9050" networks: - doris-net depends_on: - fe-leader command: /opt/apache-doris/be/bin/start_be.sh --daemon be-2: image: apache/doris:be-latest container_name: be-2 hostname: be-2 volumes: - ./storage/be-2-data:/opt/apache-doris/be/storage - ./storage/be-2-log:/opt/apache-doris/be/log environment: FE_SERVERS: "fe-leader:9010,fe-follower:9010" BE_ADDR: "be-2:9050" networks: - doris-net depends_on: - fe-leader command: /opt/apache-doris/be/bin/start_be.sh --daemon be-3: image: apache/doris:be-latest container_name: be-3 hostname: be-3 volumes: - ./storage/be-3-data:/opt/apache-doris/be/storage - ./storage/be-3-log:/opt/apache-doris/be/log environment: FE_SERVERS: "fe-leader:9010,fe-follower:9010" BE_ADDR: "be-3:9050" networks: - doris-net depends_on: - fe-leader command: /opt/apache-doris/be/bin/start_be.sh --daemon networks: doris-net: driver: bridge使用 Compose 管理集群:
# 在 docker-compose.yml 所在目录执行 # 启动所有服务(后台运行) docker-compose up -d # 查看服务状态 docker-compose ps # 查看某个服务的日志(如 fe-leader) docker-compose logs -f fe-leader # 停止所有服务 docker-compose down # 停止并删除所有数据卷(谨慎!会丢失数据) # docker-compose down -v使用 Docker Compose 后,集群的启动、停止和重建变得极其简单,非常适合开发和测试环境的维护。
7. 基础功能验证与操作示例
集群启动并添加 BE 后,让我们进行一些基本操作来验证其功能完整性。
7.1 创建数据库与表
-- 1. 创建数据库 CREATE DATABASE demo_db; USE demo_db; -- 2. 创建一张明细模型(Duplicate)表 CREATE TABLE IF NOT EXISTS user_behavior ( user_id INT, item_id INT, category_id INT, behavior VARCHAR(10), ts DATETIME ) DUPLICATE KEY(user_id, item_id) -- 指定排序列 DISTRIBUTED BY HASH(user_id) BUCKETS 10 -- 分桶 PROPERTIES ( "replication_num" = "3" -- 副本数,与 BE 节点数匹配或更少 ); -- 3. 插入测试数据 INSERT INTO user_behavior VALUES (1001, 2001, 101, 'view', '2024-01-01 10:00:00'), (1001, 2002, 102, 'buy', '2024-01-01 10:05:00'), (1002, 2001, 101, 'view', '2024-01-01 10:10:00'), (1002, 2003, 103, 'cart', '2024-01-01 10:15:00'); -- 4. 查询数据 SELECT * FROM user_behavior ORDER BY ts; SELECT user_id, COUNT(*) as action_count FROM user_behavior GROUP BY user_id;7.2 通过 Web UI 访问
Doris FE 提供了友好的 Web 管理界面。在浏览器中访问http://你的宿主机IP:8030。
- 用户名/密码:默认为
root和空密码,或你之前设置的密码。 - 在界面中,你可以:
- 查看集群健康状态。
- 执行 SQL 查询。
- 监控系统负载。
- 管理会话和变量。
7.3 数据导入小试(Stream Load)
除了 INSERT,Stream Load 是 Doris 常用的高效导入方式。我们使用curl模拟一个本地文件的导入。 首先,在宿主机上创建一个 CSV 文件test_data.csv:
1003,2004,104,view,2024-01-01 11:00:00 1004,2005,105,buy,2024-01-01 11:05:00然后使用 curl 通过 FE 的 HTTP 端口进行导入:
curl --location-trusted -u root:your_password -H "label:test_load_1" -H "column_separator:," -T ./test_data.csv http://127.0.0.1:8030/api/demo_db/user_behavior/_stream_load返回结果中包含"Status":"Success"即表示导入成功。回到 MySQL 客户端查询,应该能看到新增的两条数据。
8. 常见问题与排查思路
在部署和运行过程中,你可能会遇到以下问题。这里提供清晰的排查路径。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| MySQL 客户端连接失败 | 1. FE 容器未启动或启动失败。 2. 端口映射错误。 3. 防火墙/安全组限制。 | 1.docker ps检查容器状态。2. docker logs fe-leader查看 FE 日志。3. netstat -tlnp | grep 9030检查端口监听。 | 1. 确保容器在运行且start_fe.sh已执行。2. 检查 docker run或compose文件的端口映射。3. 关闭防火墙或放行端口(仅测试环境)。 |
BE 状态Alive为false | 1. BE 进程未成功启动。 2. BE 与 FE 网络不通。 3. BE 端口冲突或未正确上报。 | 1.docker logs be-1查看 BE 日志,关注错误。2. 在 FE 容器内 ping be-1。3. 在 BE 容器内 netstat -tlnp | grep 9050。 | 1. 根据 BE 日志错误修复(常见如目录权限)。 2. 确保所有容器在同一 Docker 网络。 3. 检查 BE_ADDR环境变量是否与容器内 IP/主机名一致。 |
FE 启动报错Failed to get master client | 首次启动 Follower 时,--helper参数指向的 Leader 未就绪或地址错误。 | 1. 确认 Leader FE 已完全启动(日志无报错)。 2. 确认 --helper参数的主机名和端口(9010)正确。 | 等待 Leader 启动完成,或使用正确的--helper地址重启 Follower。 |
创建表时提示Replica num should be less than or equal to backend num | 建表语句中replication_num属性设置的值大于当前存活的 BE 节点数。 | SHOW PROC '/backends';查看当前存活的 BE 数量。 | 将建表语句中的"replication_num" = "3"改为小于等于存活 BE 数的值,例如"replication_num" = "1"。 |
| 数据目录权限错误 | Docker 容器内进程(通常以doris用户运行)对挂载的宿主机目录没有写权限。 | 查看 BE/FE 日志,常见错误如Permission denied。 | 在宿主机上修改数据目录的权限:sudo chmod -R 777 ~/doris-docker/storage/(测试环境),生产环境应配置更精细的用户和组权限。 |
| 内存不足导致 BE 启动失败 | Doris BE 对内存有要求,容器内存分配不足或宿主机内存不足。 | 查看 BE 日志,关注Memory limit相关错误。 | 1. 为 Docker 容器分配更多内存(在docker run中使用-m参数)。2. 调整 BE 配置文件 be.conf中的内存相关参数(需挂载配置文件进容器)。 |
9. 生产环境部署建议与最佳实践
将 Docker 化 Doris 用于生产环境需要更周密的规划。以下是一些关键建议:
- 使用特定版本镜像:不要使用
:latest标签。应指定稳定版本,如apache/doris:fe-2.0.4和apache/doris:be-2.0.4,以确保环境一致性。 - 配置持久化与备份:
- 数据卷:必须使用具名卷(Named Volume)或宿主机目录绑定,并确保有备份策略。考虑使用云存储或分布式存储(如 Ceph、NAS)提供持久卷。
- 配置文件:将
fe.conf和be.conf等重要配置文件挂载到宿主机,方便修改和管理。可以在 Dockerfile 中基于官方镜像复制默认配置,或使用-v挂载自定义配置。
- 资源限制与监控:
- 使用
docker run的-m、--cpus参数或compose的deploy.resources为容器分配明确的 CPU 和内存限制,防止单个容器耗尽主机资源。 - 集成监控系统(如 Prometheus)。Doris 暴露了丰富的 JMX 和 HTTP 指标,可通过 Grafana 进行可视化。
- 使用
- 高可用与编排:
- 单机 Docker:对于重要环境,单机 Docker 仍有单点风险。应考虑使用 Docker Swarm 或 Kubernetes 进行编排,实现节点故障自动迁移。
- Kubernetes:生产级部署强烈推荐使用 K8s。可以部署多个 FE 和 BE 实例,并通过 Service 暴露。社区有 Helm Chart 可供参考。
- 网络与安全:
- 使用 overlay 网络或 host 网络模式以获得更好性能(取决于具体环境)。
- 修改默认的 root 空密码,并遵循最小权限原则创建业务用户。
- 仅将必要的端口(如 8030, 9030)暴露给外部网络,BE 间通信端口(如 9050)应限制在内部网络。
- 日志管理:将容器日志通过
json-file或journald驱动收集,并接入 ELK 或 Loki 等日志系统,便于集中查询和分析问题。
通过以上步骤,你不仅能在本地快速搭建一个功能完整的 Doris 集群,更能理解其 Docker 化部署的核心逻辑与潜在陷阱。这份教程提供的 Compose 文件和一整套操作命令,可以直接作为你团队内部开发测试环境的标准模板,有效统一环境,提升协作效率。