这次我们来看一个用 Docker 部署 Apache Doris 的实战方案。Doris 作为一款高性能的实时分析型数据库,在数据仓库、OLAP 场景下表现突出,但传统部署方式涉及多节点配置、依赖环境复杂,对新手和快速验证环境来说门槛不低。而 Docker 部署能极大简化这一过程,实现环境隔离、一键启动和快速清理。

这篇文章的核心是带你走通从零到一的 Docker 化 Doris 部署全流程。我们会重点关注几个关键问题:Docker 环境如何准备?官方镜像怎么获取和启动?FE(前端)和 BE(后端)节点如何配置与通信?部署完成后如何验证集群状态并进行基础操作?整个过程会避开复杂的源码编译和系统级配置,专注于可复现的容器化实践。

无论你是想快速搭建一个 Doris 测试环境来验证功能,还是为 CI/CD 流水线准备一个标准化的数据库服务,亦或是学习 Doris 的容器化部署最佳实践,这篇教程都能提供直接的指引。下面,我们就从 Docker 和 Doris 的基础准备开始。

1. 核心能力速览

在深入部署步骤之前,我们先通过一个表格快速了解本次 Docker 部署 Doris 方案的核心特性和要求,帮助你判断是否适合你的场景。

能力项 说明
部署方式 基于 Docker 容器化部署,实现环境隔离与快速启动。
核心组件 部署 Apache Doris 的核心组件:FE (Frontend) 和 BE (Backend)。
资源需求 灵活。建议至少 2核 CPU、4GB 内存。BE 节点对内存和磁盘 I/O 更敏感,生产环境需根据数据量调整。
存储持久化 支持。通过 Docker 卷(Volume)或绑定挂载(Bind Mount)持久化元数据和数据,避免容器重启数据丢失。
网络模式 通常使用自定义的 Docker 网络,便于 FE 和 BE 容器间通信,并暴露 FE 的查询端口(如 9030)和 Web UI 端口(如 8030)给宿主机。
配置管理 支持通过环境变量或挂载自定义配置文件到容器内,覆盖默认配置。
适合场景 开发测试、功能验证、CI/CD 环境、学习研究、快速原型搭建。
不适合场景 超大规模生产集群(需考虑容器编排、网络、存储性能等更复杂因素)。

2. 适用场景与使用边界

Docker 化部署 Doris 主要服务于特定场景,明确边界能帮助你更好地决策。

它非常适合以下情况:

  • 快速原型与功能验证 :当你需要快速验证 Doris 的某个特性、测试 SQL 兼容性或评估性能时,Docker 能在几分钟内提供一个干净的、可随时销毁的环境。
  • 开发与测试环境 :为开发团队提供统一的、隔离的 Doris 实例,确保环境一致性,避免“在我机器上好好的”问题。
  • 学习与研究 :对于想学习 Doris 架构、操作的学生或研究人员,无需关心复杂的系统依赖和编译过程,专注于数据库本身的使用。
  • 集成测试与 CI/CD :在自动化流水线中,可以快速启动一个 Doris 服务用于执行集成测试,测试结束后自动清理,非常高效。

需要注意的边界与限制:

  • 性能与资源隔离 :Docker 容器虽然轻量,但其网络、存储 I/O 性能与原生部署仍有细微差别。对于追求极致性能的生产环境,仍需谨慎评估并可能选择物理机或虚拟机部署。
  • 存储持久化 :必须正确配置数据卷。如果仅将数据存储在容器内部,容器删除意味着数据丢失,这是使用 Docker 部署有状态服务时必须牢记的。
  • 集群复杂度 :本文演示单机伪集群(1 FE, 1 BE)部署。虽然 Docker 也可以部署多节点集群,但涉及容器发现、网络配置和存储共享,复杂度会显著增加,可能需要配合 Docker Compose 或 Kubernetes。
  • 数据安全与合规 :在容器内处理敏感数据时,需确保数据卷的访问权限和加密措施符合安全要求。镜像来源应优先选择官方或可信渠道。

3. 环境准备与前置条件

开始部署前,请确保你的操作环境满足以下基本要求。

3.1 操作系统

  • 推荐 :Linux 发行版(如 Ubuntu 20.04/22.04, CentOS 7/8)。大多数生产环境和教程基于此。
  • 也可行 :macOS (Docker Desktop for Mac) 或 Windows 10/11 (Docker Desktop for Windows/WSL 2)。用于开发和测试完全没问题。
    • Windows/macOS 用户注意 :文件路径、性能(特别是磁盘I/O)可能与 Linux 有差异,建议通过 WSL 2 (Windows) 运行 Docker 以获得更接近 Linux 的体验。

3.2 Docker 环境

  • Docker Engine :版本 20.10.0 或更高。这是运行容器的核心。
  • Docker Compose :版本 v2.0.0 或更高。虽然本文主要用 docker run 命令演示,但 Docker Compose 是管理多容器服务的更优雅方式,后续扩展集群时会用到。
  • 安装验证 :打开终端,执行以下命令检查安装是否成功。
    # 检查 Docker 版本
    docker --version
    # 检查 Docker Compose 版本
    docker compose version
    # 运行一个测试容器
    docker run hello-world
    
    如果 hello-world 容器能正常运行并输出欢迎信息,说明 Docker 环境基本就绪。

3.3 系统资源检查

  • CPU与内存 :建议为 Docker 分配至少 2 个 CPU 核心和 4 GB 内存。可以通过 Docker Desktop 的设置或 Linux 系统配置进行调整。
  • 磁盘空间 :确保有足够的磁盘空间存放 Docker 镜像和即将创建的持久化数据卷。Doris 镜像本身约 1-2 GB,数据卷空间取决于你的测试数据量。
  • 网络 :确保主机可以访问互联网,以下载 Doris 官方镜像。如果在内网,需要提前准备镜像或配置内部镜像仓库。

4. 安装部署与启动方式

我们将分步启动一个包含 1 个 FE 节点和 1 个 BE 节点的最小化 Doris 集群。

4.1 获取 Doris Docker 镜像 Apache Doris 社区提供了官方镜像。我们选择最新的稳定版本,例如 apache/doris:2.0.5-fe-x86_64 apache/doris:2.0.5-be-x86_64

# 拉取 FE 镜像
docker pull apache/doris:2.0.5-fe-x86_64
# 拉取 BE 镜像
docker pull apache/doris:2.0.5-be-x86_64

拉取完成后,可以使用 docker images 命令查看已下载的镜像。

4.2 创建 Docker 网络 为了让 FE 和 BE 容器在独立的网络空间中通信,我们创建一个自定义的 Docker 网络。

docker network create doris-network

创建后,可以用 docker network ls 查看网络列表,确认 doris-network 已存在。

4.3 启动 FE 节点 FE 是 Doris 的前端节点,负责元数据管理、客户端连接和查询规划。

# 创建用于持久化 FE 元数据的目录
mkdir -p /opt/doris-data/doris-fe

# 启动 FE 容器
docker run -d \
  --name doris-fe \
  --network doris-network \
  --hostname doris-fe \
  -p 8030:8030 \ # Web UI 端口
  -p 9030:9030 \ # MySQL 客户端连接端口
  -v /opt/doris-data/doris-fe:/opt/apache-doris/fe/doris-meta \
  -e FE_SERVERS="doris-fe:9010" \
  -e FE_ID=1 \
  apache/doris:2.0.5-fe-x86_64

参数解释

  • -d : 后台运行容器。
  • --name : 指定容器名称。
  • --network : 加入我们创建的 doris-network
  • --hostname : 设置容器主机名,用于集群内部通信。
  • -p : 端口映射。将容器内的 8030 (HTTP Web UI) 和 9030 (MySQL 协议端口) 映射到宿主机相同端口。
  • -v : 数据卷挂载。将宿主机的 /opt/doris-data/doris-fe 目录挂载到容器内 FE 的元数据目录,实现持久化。
  • -e : 设置环境变量。 FE_SERVERS 定义了 FE 节点列表(目前只有自己), FE_ID 是节点唯一标识。

4.4 启动 BE 节点 BE 是后端节点,负责数据存储和查询执行。

# 创建用于持久化 BE 数据的目录
mkdir -p /opt/doris-data/doris-be

# 启动 BE 容器
docker run -d \
  --name doris-be \
  --network doris-network \
  --hostname doris-be \
  -p 8040:8040 \ # BE HTTP 状态端口
  -v /opt/doris-data/doris-be:/opt/apache-doris/be/storage \
  -e FE_HOST=doris-fe \
  -e FE_PORT=9010 \
  apache/doris:2.0.5-be-x86_64

参数解释

  • 端口 8040 用于访问 BE 的 Web 状态页面。
  • 数据卷挂载到 BE 的存储目录 /opt/apache-doris/be/storage
  • 环境变量 FE_HOST FE_PORT 告诉 BE 节点如何去连接 FE 节点(通过我们在 doris-network 中定义的容器名 doris-fe 和 FE 内部端口 9010 )。

4.5 使用 Docker Compose 一键启动(推荐) 对于多容器应用,使用 Docker Compose 管理更为清晰。创建一个 docker-compose.yml 文件:

version: '3.8'
services:
  doris-fe:
    image: apache/doris:2.0.5-fe-x86_64
    container_name: doris-fe
    hostname: doris-fe
    ports:
      - "8030:8030"
      - "9030:9030"
    volumes:
      - ./data/doris-fe:/opt/apache-doris/fe/doris-meta
    environment:
      - FE_SERVERS=doris-fe:9010
      - FE_ID=1
    networks:
      - doris-net

  doris-be:
    image: apache/doris:2.0.5-be-x86_64
    container_name: doris-be
    hostname: doris-be
    ports:
      - "8040:8040"
    volumes:
      - ./data/doris-be:/opt/apache-doris/be/storage
    environment:
      - FE_HOST=doris-fe
      - FE_PORT=9010
    networks:
      - doris-net
    depends_on:
      - doris-fe

networks:
  doris-net:
    driver: bridge

然后在 docker-compose.yml 文件所在目录执行:

# 启动服务
docker compose up -d
# 查看服务状态
docker compose ps
# 停止并移除服务
docker compose down

这种方式更利于版本控制和一键启停。

5. 功能测试与效果验证

服务启动后,我们需要验证集群是否正常,并进行基本的数据库操作。

5.1 验证服务状态 首先,检查容器是否在运行:

docker ps | grep doris

应该能看到 doris-fe doris-be 两个容器,状态为 Up

5.2 访问 Web UI

  • FE Web UI : 在浏览器中访问 http://你的服务器IP:8030 。默认用户名是 root ,密码为空。登录后可以查看系统状态、集群信息、查询管理等。
  • BE Web UI : 访问 http://你的服务器IP:8040 ,可以查看 BE 节点的基本状态和指标。

5.3 使用 MySQL 客户端连接并操作 Doris 兼容 MySQL 协议,我们可以用任何 MySQL 客户端连接。这里使用 mysql 命令行工具(需提前安装)。

# 连接 Doris FE(端口 9030)
mysql -h 127.0.0.1 -P 9030 -uroot

连接成功后,会看到 MySQL 提示符 mysql>

5.4 执行基础 SQL 测试 在 MySQL 客户端中执行以下 SQL,完成从建库、建表到查询的全流程测试。

-- 1. 查看集群状态(在 Doris 中,这是一个命令)
SHOW PROC '/frontends'\G
SHOW PROC '/backends'\G
-- 确认 FE 和 BE 的 `Alive` 字段是否为 `true`。

-- 2. 创建测试数据库
CREATE DATABASE IF NOT EXISTS test_db;
USE test_db;

-- 3. 创建一张测试表(以 Duplicate 模型为例)
CREATE TABLE IF NOT EXISTS test_table (
    user_id INT,
    date DATE,
    city VARCHAR(20),
    age SMALLINT,
    cost BIGINT
)
DUPLICATE KEY(user_id, date, city)
DISTRIBUTED BY HASH(user_id) BUCKETS 10
PROPERTIES (
    "replication_num" = "1"
);

-- 4. 插入测试数据
INSERT INTO test_table VALUES
(1001, '2024-01-01', 'Beijing', 25, 150),
(1002, '2024-01-01', 'Shanghai', 30, 200),
(1001, '2024-01-02', 'Beijing', 25, 100),
(1003, '2024-01-02', 'Guangzhou', 28, 180);

-- 5. 查询数据
SELECT * FROM test_table ORDER BY date, user_id;

-- 6. 执行聚合查询
SELECT city, SUM(cost) as total_cost, AVG(age) as avg_age
FROM test_table
GROUP BY city;

如果每一步都能成功执行并返回预期结果,说明你的 Docker Doris 集群已经可以正常工作了。

6. 接口 API 与批量任务

除了 MySQL 协议,Doris 还提供了 HTTP Restful API,便于程序集成和批量任务。

6.1 通过 HTTP API 执行查询 FE 的 Web 服务端口(8030)提供了查询接口。

# 使用 curl 执行一个简单查询
curl -X POST \
  http://127.0.0.1:8030/api/test_db/_query \
  -u root: \
  -H "Content-Type: application/json" \
  -d '{
    "query": "SELECT city, SUM(cost) FROM test_table GROUP BY city"
  }'
  • -u root: 指定用户名和密码(root用户空密码)。
  • test_db 是数据库名。
  • 返回结果是 JSON 格式,包含了列信息和数据行。

6.2 使用 Stream Load 进行批量数据导入 这是 Doris 高性能数据导入的方式之一,通过 HTTP 协议将本地文件数据批量导入。 假设你有一个 data.csv 文件,内容如下:

1004,2024-01-03,Shenzhen,32,220
1005,2024-01-03,Hangzhou,26,170

可以使用 curl 命令导入:

curl -X PUT \
  -T ./data.csv \
  -H "format: csv" \
  -H "column_separator: ," \
  -H "columns: user_id, date, city, age, cost" \
  http://127.0.0.1:8030/api/test_db/test_table/_stream_load
  • -T 指定要上传的文件。
  • format 指定文件格式为 CSV。
  • column_separator 指定列分隔符。
  • columns 指定 CSV 文件列对应的表字段名。
  • 导入成功后,会返回一个包含 Status: Success 和导入事务ID TxnId 的 JSON。

6.3 编程语言集成示例(Python) 你可以使用 requests 库在 Python 脚本中调用 Doris API。

import requests
import json

# 配置信息
fe_host = "127.0.0.1"
fe_http_port = 8030
db = "test_db"
table = "test_table"
user = "root"
password = ""

# 1. 执行查询
query_url = f"http://{fe_host}:{fe_http_port}/api/{db}/_query"
query_sql = "SELECT * FROM test_table LIMIT 5"

response = requests.post(query_url,
                         auth=(user, password),
                         json={"query": query_sql},
                         headers={"Content-Type": "application/json"})
if response.status_code == 200:
    result = response.json()
    print("查询结果:", json.dumps(result, indent=2, ensure_ascii=False))
else:
    print("查询失败:", response.text)

# 2. 流式导入数据 (Stream Load)
stream_load_url = f"http://{fe_host}:{fe_http_port}/api/{db}/{table}/_stream_load"
csv_data = "1006,2024-01-04,Chengdu,29,190\n"

headers = {
    "format": "csv",
    "column_separator": ",",
    "columns": "user_id, date, city, age, cost"
}

response = requests.put(stream_load_url,
                        data=csv_data,
                        headers=headers,
                        auth=(user, password))
print("导入结果:", response.json())

7. 资源占用与性能观察

部署完成后,了解如何监控容器和 Doris 本身的资源消耗至关重要。

7.1 容器资源监控 使用 Docker 命令查看实时资源占用:

# 查看所有容器的资源使用概况(CPU,内存,网络IO等)
docker stats
# 查看指定容器的详细信息
docker inspect doris-fe
# 查看容器日志,有助于排查启动或运行时错误
docker logs -f doris-fe

7.2 Doris 集群状态监控

  • FE 管理界面 http://IP:8030 中的“集群”、“系统”等选项卡提供了丰富的监控指标,如表数量、查询统计、连接数等。
  • BE 状态界面 http://IP:8040 可以查看 BE 的存储使用情况、Tablet 状态、 compaction 信息等。
  • 通过 SQL 查询系统表 :Doris 内置了许多系统表,可以查询集群负载。
    -- 查看正在执行的查询
    SHOW PROC '/current_queries';
    -- 查看集群负载(需在 FE 上执行)
    SHOW PROC '/cluster_balance/cluster_load';
    

7.3 性能调优初步建议 对于 Docker 环境,性能瓶颈通常出现在 I/O 和内存。

  • 磁盘 I/O :确保数据卷 ( /opt/doris-data ) 挂载在 SSD 磁盘上,能极大提升数据读写和 Compaction 性能。
  • 内存限制 :如果宿主机内存紧张,可以为 Docker 容器设置内存限制(在 docker run 中使用 -m 参数),但需注意,过小的内存会导致 BE 进程因 OOM 被杀死。建议 BE 容器至少分配 4GB 内存。
  • CPU 限制 :同样可以使用 --cpus 参数限制容器使用的 CPU 核数。对于计算密集型查询,足够的 CPU 资源是关键。

8. 常见问题与排查方法

部署和使用过程中可能会遇到一些问题,下表列出了常见现象及解决方法。

问题现象 可能原因 排查方式 解决方案
容器启动后立即退出 1. 端口冲突。
2. 挂载的宿主机目录权限不足。
3. 环境变量配置错误。
docker logs <容器名> 查看启动日志。 1. 更换宿主机端口或停止占用端口的进程。
2. 使用 chmod 修改宿主机目录权限为可读写。
3. 检查 docker run 命令中的 -e 环境变量值是否正确。
MySQL 客户端连接被拒绝 1. FE 容器未正常运行。
2. 端口映射错误(宿主机端口非9030)。
3. 防火墙/安全组阻止了端口。
1. docker ps 确认 FE 容器状态。
2. docker port doris-fe 查看端口映射。
3. 在宿主机执行 telnet 127.0.0.1 9030 测试端口连通性。
1. 重启 FE 容器并查看日志。
2. 修正 -p 映射参数。
3. 关闭防火墙或放行 9030、8030、8040 端口。
BE 节点无法加入集群 1. BE 容器无法解析 FE 主机名。
2. FE 的 fe.conf priority_networks 未配置或配置错误。
3. BE 的 be.conf priority_networks 问题。
1. 在 BE 容器内 ping doris-fe
2. 进入 FE 容器查看 /opt/apache-doris/fe/log/fe.warn.log
3. 进入 BE 容器查看 /opt/apache-doris/be/log/be.WARNING
1. 确保使用自定义网络,且 --hostname 正确。
2. 对于复杂网络,可能需要通过 -e PRIORITY_NETWORKS=... 环境变量为 FE/BE 指定网络。
Stream Load 导入失败 1. 文件格式或分隔符指定错误。
2. 列数量或类型不匹配。
3. 表不存在或用户无权限。
仔细查看 Stream Load 返回的 JSON 错误信息,其中 Message 字段通常很详细。 1. 核对 format , column_separator , columns 参数。
2. 确保 CSV 文件数据与表结构匹配。
3. 确认数据库、表名正确,使用有权限的用户。
查询速度慢 1. 数据未正确分桶或分布。
2. 容器资源(CPU/内存)不足。
3. 未建立合适的索引(如 Rollup)。
1. 使用 EXPLAIN 查看查询计划。
2. 使用 docker stats 观察资源瓶颈。
3. 在 FE Web UI 查看慢查询日志。
1. 优化表的分桶键和分桶数。
2. 为 Docker 容器分配更多资源。
3. 根据查询模式创建 Rollup 物化视图。
数据卷权限问题 容器内进程(UID)对挂载的宿主机目录无写权限。 docker exec -it doris-fe ls -la /opt/apache-doris/fe/doris-meta 在宿主机上,将数据目录的权限设置为 777 (测试环境)或更精细地匹配容器内进程的 UID。

9. 最佳实践与使用建议

为了让你的 Docker Doris 环境更稳定、高效,遵循以下实践建议。

  • 数据持久化是必须项 :永远不要依赖容器的内部存储来保存 Doris 的元数据和用户数据。务必使用 -v 参数进行卷挂载。定期备份宿主机的数据目录 ( /opt/doris-data )。
  • 使用 Docker Compose 管理 :对于多容器应用, docker-compose.yml 文件能清晰定义服务、网络和卷,是比一堆 docker run 命令更可维护的方式。将 docker-compose.yml 纳入版本控制。
  • 为生产环境定制配置 :本文使用的 Docker 镜像是默认配置。对于生产环境,你应该通过挂载自定义的 fe.conf be.conf 文件到容器内,来调整内存限制、线程数、日志级别等关键参数。
    # 在 docker-compose.yml 中为 FE 服务添加配置挂载
    volumes:
      - ./conf/fe.conf:/opt/apache-doris/fe/conf/fe.conf
    
  • 关注日志 :将 Doris 的日志目录也挂载到宿主机,方便排查问题。日志路径通常在 /opt/apache-doris/fe/log /opt/apache-doris/be/log
  • 网络与安全 :在生产环境中,不要随意将 Doris 的端口(特别是 9030)暴露在公网。应通过内部网络或 VPN 访问,并使用强密码替代 root 空密码。
  • 资源限制与监控 :在 docker-compose.yml docker run 命令中为容器设置合理的资源限制( cpus , mem_limit ),防止单个容器耗尽主机资源。同时,建立对容器和 Doris 本身的基础监控。
  • 镜像版本管理 :明确记录所使用的 Doris 镜像版本。在升级版本时,先在测试环境验证兼容性,并做好数据备份。

10. 总结与下一步

通过以上步骤,你应该已经成功在 Docker 环境中部署并验证了一个可用的 Apache Doris 集群。这种部署方式的核心优势在于 环境标准化 部署敏捷性 ,特别适合前期技术调研、开发测试和持续集成场景。

最值得尝试的下一步:

  1. 数据导入性能测试 :尝试使用 Stream Load 或 Broker Load 导入一个百兆或 GB 级别的真实数据集,观察导入速度和资源消耗。
  2. 查询性能体验 :执行一些复杂的多表关联、聚合查询,感受 Doris 作为 OLAP 数据库的查询速度,并与 EXPLAIN 计划结合分析。
  3. 探索高级特性 :在稳定的测试环境上,尝试使用 Rollup 物化视图预聚合、Colocate Join、动态分区等高级功能,理解它们对查询的优化作用。
  4. 尝试集群扩展 :参考官方文档,尝试在 Docker Compose 中配置多个 BE 节点,体验 Doris 的横向扩展能力。

最容易踩的坑:

  • 忽略数据持久化 :这是容器化有状态服务的第一大忌。
  • 网络配置不当 :FE 和 BE 容器间无法通信是导致集群组建失败的最常见原因。
  • 资源分配不足 :尤其是在运行数据导入或复杂查询时,BE 节点可能因内存不足而崩溃。

把这个 Docker 化的 Doris 环境当作你的一个标准“数据库沙盒”,可以大胆地进行各种功能实验和性能测试,而不用担心污染主机环境。当测试完成后,一个 docker compose down -v (谨慎使用,会删除数据卷)就能清理得干干净净,为下一次实验做好准备。

更多推荐