Doris 部署方式、架构选型与提效工具手册
从“9030 能连接”到分析链路真的可用
第一次接触 Doris,最容易被 MySQL 协议入口误导:mysql -P9030 能登录,只说明 FE 接受了连接;查询能否执行、数据能否提交,还取决于 BE 是否存活、Tablet 是否有健康副本、导入事务是否提交,以及查询是否拿到足够资源。Doris 是面向实时分析的 MPP OLAP 数据库,FE 保存元数据并解析、规划和协调请求,BE 保存 Tablet / Replica 并完成扫描、聚合、Join、导入和 compaction。沿着这条链路验证,才能把“端口通了”和“数据库可用”分开。
MySQL 客户端、DBeaver 和 JDBC 驱动可以复用,是因为 FE 兼容 MySQL 网络协议;Doris 的表模型、事务、函数和管理语句并不会因此变成 MySQL。应用配置应明确命名为 Doris,迁移 SQL 也要在 Doris 上逐条验证,避免把协议兼容误写成数据库语义兼容。
本地 Quick Start 适合学习 FE / BE、建表、导入和查询。进入共享或生产环境后,决策会扩展到多 FE、多 BE、副本、元数据持久化、资源隔离、备份恢复、升级回滚和容量成本;这些对象会在后续操作中逐一出现,而不是等到上线前才补。
启动前先看机器和数据
开始实验需要:
Docker Engine 或 Docker Desktop,并确认 docker version 可用。若使用本地完整部署,准备主流 Linux 环境和 JDK 17+。MySQL 协议客户端,例如 mysql、DBeaver、DataGrip 或兼容 JDBC 客户端。Doris FE 默认通过 9030 提供 MySQL 协议。curl,用于 Stream Load 和 FE HTTP / Web UI 入口验证。
本机端口预留:FE HTTP 8030、FE query 9030、BE Web 8040、BE heartbeat 9050、BE thrift 9060、BE BRPC 8060。如果本机已有 Doris,给实验容器映射其他宿主机端口,并同步修改命令中的连接地址。
资源预算。4.x 部署建议中,开发测试环境的 FE 下限为 8C / 8Gi、BE 下限为 8C / 16Gi;生产建议 FE 与 BE 分机部署,并从 16C / 64Gi 量级评估。Docker Quick Start 在更低配置上偶尔能启动,也不能据此承诺稳定导入、查询或 compaction。CPU 指令集确认。Doris 二进制和镜像会区分 x64 avx2、x64 no-avx2、ARM64 等目标,老机器启动 BE 前先确认 CPU 能力。
一个只用于实验的目录,例如 your-project/dev-dependencies/doris/,不要把真实 CSV、Parquet、日志、手机号、邮箱、订单明细或生产连接串放进仓库。
先确认本机端口:
docker ps --format "table {{.Names}}\t{{.Ports}}\t{{.Status}}"
lsof -i :8030 -i :9030 -i :8040 -i :9050 -i :9060 -i :8060Windows PowerShell:
Get-NetTCPConnection -State Listen |
Where-Object { $_.LocalPort -in 8030,9030,8040,9050,9060,8060 } |
Select-Object LocalAddress,LocalPort,OwningProcess确认 CPU 指令集:
grep -m 1 avx2 /proc/cpuinfo || echo "no avx2 flag found"
uname -m如果是 WSL2、Docker Desktop、VPN 或企业安全软件环境,先验证 FE / BE 互通。127.0.0.1 可能指向不同网络命名空间,表现就是 FE 可登录、BE 却持续 alive=false;此时应根据实际网段设置 priority_networks,并从 FE 容器或主机探测 BE 的 heartbeat、thrift 和 BRPC 端口。
版本号、CPU 包型和升级路径会直接决定二进制能否启动。开始前在 Apache Doris 下载页 选择团队批准的发行线,核对 x64 AVX2、x64 no-AVX2 或 ARM64 包型,并把精确版本锁进 .env、镜像 tag 和兼容矩阵。二进制集群面向主流 AMD64 / ARM64 Linux;Windows 和 macOS 开发机走 Docker 或 Linux 虚拟化环境,不把宿主系统当生产支持基线。学习环境可跟随新版本;共享和生产环境要优先服从插件、驱动、备份恢复演练与回滚验证结果。
Apache Doris 主仓库采用 Apache License 2.0,但发行物还包含第三方依赖。需要再分发镜像、裁剪功能或进入受监管制品库时,要同时审查发行包内的 LICENSE、NOTICE 和 thirdparty/LICENSE.txt;不能只看到主仓库许可证就推断所有可选依赖都满足同一许可策略。
| 入口 | 适合 | 不适合 | 必须确认 |
|---|---|---|---|
| Docker Quick Start | 个人快速体验、学习 FE / BE、最小 SQL 验证 | 生产、共享长期实例、容量测试 | 版本、端口、FE / BE alive、数据丢失边界 |
| 本地完整部署 | 理解 FE / BE 分离、配置文件、端口、JDK、系统参数 | 新人一键体验 | Linux、JDK 17+、Doris 用户、文件句柄、vm.max_map_count |
| Docker Compose / runtime 模板 | 小团队本地联调、沉淀目录和脚本 | 生产标准架构 | volume、网络、BE 注册、资源限制、日志 |
| 共享开发实例 | 多服务联调、统一样例数据、减少本机资源压力 | 随意压测、临时大导入、生产替代 | owner、账号、库名前缀、配额、清理窗口 |
| 集成存算集群 | 常规自建生产架构、数据和计算在 BE 上 | 极致弹性或云对象存储优先场景 | 多 FE、多 BE、副本、Tablet 分布、备份恢复 |
| 存算分离 / Compute Group | 弹性计算、对象存储、隔离不同工作负载 | 小团队本地快速验证 | Meta Service、共享存储、Compute Group、Workload Group |
| Kubernetes / Operator | 平台化交付、资源声明式管理 | 单项目临时验证 | CRD、存储、网络、FE / BE 服务、升级和恢复 |
| 托管 Doris / 云服务 | 降低运维复杂度、弹性和云生态 | 成本、数据边界、区域未确认 | 费用、SLA、网络、权限、备份、退出方案 |
Docker Quick Start
从 Quick Start 下载 start-doris.sh,再执行:
chmod 755 start-doris.sh
export DORIS_VERSION="4.0.6"
bash start-doris.sh -v "${DORIS_VERSION}"4.0.6 是这组命令的验证基线,不是浮动别名。执行前若团队选择了其他版本,要同时替换脚本参数、镜像 tag 和兼容矩阵,不能只改其中一处。
启动后先验证 FE / BE,而不是直接建表:
mysql -uroot -P9030 -h127.0.0.1 \
-e 'SELECT `host`, `join`, `alive` FROM frontends()'
mysql -uroot -P9030 -h127.0.0.1 \
-e 'SELECT `host`, `alive` FROM backends()'预期:
FE 的 join 和 alive 都为 true。BE 的 alive 为 1 或 true。如果 FE 可连接但 BE 不 alive,先看 BE 端口、防火墙、priority_networks 和 BE 日志,不要先怀疑 SQL。
Quick Start 的定位只到“本地验证”。它不证明生产部署、备份恢复、容量、监控、升级和多副本已经准备好。
本地完整部署
本地完整部署适合理解 Doris 真实组件边界:
下载二进制包并按 CPU 架构选择 x64 avx2、x64 no-avx2 或 ARM64。使用专用 Doris 用户,不用 root 长期运行。配置 fe/conf/fe.conf 和 be/conf/be.conf 的 priority_networks。
启动 FE 后通过 9030 验证 SHOW FRONTENDS。启动 BE,执行 ALTER SYSTEM ADD BACKEND "host:9050",再验证 SHOW BACKENDS。
这个入口的价值是让团队知道:Doris 不是一个单进程数据库。FE、BE、元数据、数据目录、端口、网络段和心跳缺一不可。
小团队共享实例
共享开发实例可以节省本机资源,但必须先建规则:
doris-dev/
owner: <team-name>
fe_http: http://doris-dev.example.com:8030
query_port: 9030
databases:
your_project_dev
your_project_test
accounts:
your_project_writer
your_project_reader
cleanup_window: Friday 18:00共享实例不允许:
所有人共用 root。每个需求随意建库。大文件直接导入公共库。
没有 label 规范的 Stream Load。没有 owner 的临时表长期保留。
端口与角色
| 组件 | 默认端口 | 用途 | 开发侧判断 |
|---|---|---|---|
| FE HTTP | 8030 | Web UI、HTTP API、Stream Load 入口 | 能访问不代表 BE 可用 |
| FE query | 9030 | MySQL 协议连接 | 能登录不代表集群健康 |
| FE RPC | 9020 | FE / BE / FE 内部通信 | 开发机一般不直接暴露 |
| FE edit log | 9010 | FE 元数据日志通信 | 生产多 FE 关键端口 |
| BE Web | 8040 | BE Web / HTTP | 排查 BE 状态和负载 |
| BE heartbeat | 9050 | FE 到 BE 心跳 | BE dead 先查这个 |
| BE thrift | 9060 | FE 到 BE 请求 | 导入和查询依赖 |
| BE BRPC | 8060 | BE 间通信 | 分布式执行和数据传输依赖 |
项目模板变量
.env.example:
DORIS_VERSION=4.0.6
DORIS_FE_HOST=127.0.0.1
DORIS_FE_HTTP_PORT=8030
DORIS_FE_QUERY_PORT=9030
DORIS_DATABASE=te_doris
DORIS_APP_USER=te_doris_app
DORIS_APP_PASSWORD=YOUR_STRONG_DORIS_PASSWORD
DORIS_ENV=local不要提交真实密码。开发脚本可以默认拒绝非本地环境:
case "${DORIS_ENV}" in
local|dev|test) ;;
*) echo "refuse to run Doris destructive script on env=${DORIS_ENV}" >&2; exit 1 ;;
esac目录与持久化
团队模板建议记录:
dev-dependencies/
doris/
README.md
.env.example
scripts/
verify-cluster.sh
init-schema.sql
stream-load-demo.sh
clean-dry-run.sh
clean-confirmed.sh
data/
events.csv
docs/
doris-contract.md如果使用容器或 Compose,需要明确 FE 元数据、BE 数据和日志目录是否持久化。Quick Start 可以临时体验,但共享环境必须写清:
FE 元数据目录。BE 存储目录。日志目录。
备份目录或对象存储位置。清理和恢复责任人。
最小表设计
本地验证表用 Duplicate Key,降低入门复杂度:
CREATE DATABASE IF NOT EXISTS te_doris;
USE te_doris;
CREATE TABLE IF NOT EXISTS event_demo
(
event_date DATE,
event_time DATETIME,
service VARCHAR(64),
event_type VARCHAR(64),
user_id BIGINT,
request_id VARCHAR(128),
cost_ms INT,
success BOOLEAN
)
DUPLICATE KEY(event_date, service, event_type)
PARTITION BY RANGE(event_date)
(
PARTITION p_event_month VALUES LESS THAN ("<EVENT_DATE>")
)
DISTRIBUTED BY HASH(user_id) BUCKETS 1
PROPERTIES
(
"replication_num" = "1"
);这里的 replication_num=1 只用于本地最小验证。共享环境和生产必须按节点数、副本、恢复窗口和容量规划重新评审。
为什么这样写:
Duplicate Key 适合原始明细样例,不做去重和聚合。event_date 分区方便清理测试数据。DISTRIBUTED BY HASH(user_id) 让团队从一开始意识到分桶键是架构决策。
BUCKETS 1 只适合本地单 BE demo,真实环境要按 Tablet 大小、BE 数量和查询并发重新计算。
最小验证必须证明:FE / BE 都正常、MySQL 协议可连、表可建、数据可写、查询可读、导入状态可追踪、权限边界可验证、测试对象可清理。
连接和集群状态
mysql -uroot -P9030 -h127.0.0.1 -e "SELECT VERSION();"
mysql -uroot -P9030 -h127.0.0.1 \
-e 'SELECT `host`, `join`, `alive` FROM frontends()'
mysql -uroot -P9030 -h127.0.0.1 \
-e 'SELECT `host`, `alive` FROM backends()'如果 SELECT VERSION() 成功,但 backends() 不 alive,不要继续建表和导入。
建库建表
mysql -uroot -P9030 -h127.0.0.1 < dev-dependencies/doris/scripts/init-schema.sql检查表:
mysql -uroot -P9030 -h127.0.0.1 -e "SHOW CREATE TABLE te_doris.event_demo\\G"INSERT 验证
INSERT INTO te_doris.event_demo VALUES
("<EVENT_DATE>", "<EVENT_TIME>", "api", "request", 1001, "req-001", 42, true),
("<EVENT_DATE>", "<EVENT_TIME>", "api", "request", 1002, "req-002", 180, true),
("<EVENT_DATE>", "<EVENT_TIME>", "worker", "job", 1003, "req-003", 900, false);
SELECT service, event_type, COUNT(*) AS total, AVG(cost_ms) AS avg_cost
FROM te_doris.event_demo
GROUP BY service, event_type
ORDER BY total DESC;这三行会形成两个分组,预期结果是:
api request 2 111
worker job 1 900这里同时验证了字段类型和聚合语义:cost_ms 若误建成字符串,AVG 会失败或发生不符合预期的转换;success 若在 CSV 映射时错位,后面的失败率统计就会失真。建表后先用少量已知数据做可人工心算的聚合,比直接导入百万行更容易发现字段顺序和类型错误。
再用同一个业务标识写两次,观察 Duplicate Key 不去重:
INSERT INTO te_doris.event_demo VALUES
("<EVENT_DATE>", "<EVENT_TIME>", "api", "retry", 1006, "req-duplicate", 10, true),
("<EVENT_DATE>", "<EVENT_TIME>", "api", "retry", 1006, "req-duplicate", 20, true);
SELECT request_id, COUNT(*) AS rows, SUM(cost_ms) AS total_cost
FROM te_doris.event_demo
WHERE request_id = "req-duplicate"
GROUP BY request_id;预期得到 req-duplicate | 2 | 30。DUPLICATE KEY(event_date, service, event_type) 决定排序前缀,不承担唯一约束;把它误当主键会让应用重试悄悄制造重复事实。
Stream Load 验证
data/events.csv:
<EVENT_DATE>,<EVENT_TIME>,api,request,1004,req-004,61,true
<EVENT_DATE>,<EVENT_TIME>,api,request,1005,req-005,320,false导入:
export DORIS_FE_HTTP="http://127.0.0.1:8030"
export DORIS_LOAD_LABEL="te_doris_event_demo_$(date +%s)"
curl --location-trusted -u root: \
-H "Expect:100-continue" \
-H "label:${DORIS_LOAD_LABEL}" \
-H "column_separator:," \
-H "columns:event_date,event_time,service,event_type,user_id,request_id,cost_ms,success" \
-T dev-dependencies/doris/data/events.csv \
-XPUT "${DORIS_FE_HTTP}/api/te_doris/event_demo/_stream_load"成功响应中的可变标识和耗时每次不同,但关键字段应满足:
{
"Label": "te_doris_event_demo_...",
"Status": "Success",
"NumberTotalRows": 2,
"NumberLoadedRows": 2,
"NumberFilteredRows": 0
}Status 表示整批事务是否提交,Label 是重试身份,NumberLoadedRows 是已写入行数,NumberFilteredRows 是被质量规则过滤的行数。严格数据链路不能只检查 HTTP 2xx;至少断言 Status=Success、加载行数等于 manifest 行数、过滤行数为 0,再查询表中关键聚合。
不要重新生成 label,原样再执行一次同一个 curl。预期 Status 变为 Label Already Exists,表中行数不增加。这条反向实验说明 label 去重发生在 FE 管理的导入事务上;若重试脚本每次都拼新时间戳,网络超时后的重复提交仍会写入两份数据。
再把 CSV 第二行的 cost_ms 改成 not-a-number,使用一个新 label 重试。默认 max_filter_ratio=0 时,预期批次失败,NumberFilteredRows 大于 0,并返回 ErrorURL 或错误信息。下载错误明细并保存 label、源文件 checksum 和响应 JSON,才能区分“网络没送到”“字段解析失败”和“事务提交失败”。不能为了让任务变绿而直接放宽过滤比例;只有业务明确允许坏行隔离,且过滤行另有补偿队列和告警时,才设置非零阈值。
查询诊断入口
EXPLAIN
SELECT service, COUNT(*) AS total
FROM te_doris.event_demo
WHERE event_date = "<EVENT_DATE>"
GROUP BY service;
SHOW PROCESSLIST;
SHOW LOAD FROM te_doris;Profile 的开启和查看方式受版本、客户端和配置影响,但诊断顺序不变:先用 EXPLAIN 确认分区裁剪、扫描节点、Join 分布和聚合阶段,再用 Profile、audit log 与 FE / BE 日志核对实际扫描行数、耗时、内存和数据倾斜。静态计划错误先改 schema、分区或分桶;计划合理而运行时变慢,再查资源竞争、compaction 和 IO。
清理
个人本地清理:
DROP TABLE IF EXISTS te_doris.event_demo;
DROP DATABASE IF EXISTS te_doris;共享环境清理必须先 dry-run:
SHOW TABLES FROM te_doris;
SELECT COUNT(*) FROM te_doris.event_demo;然后由 owner 确认清理窗口。不要让 DROP DATABASE 进入无人审查的一键脚本。
Doris 走 MySQL 协议,因此很多项目可以先用 MySQL 客户端或 JDBC 驱动验证连接。但项目接入时要把“协议兼容”和“数据库语义”分开。
JDBC 配置
.env.example:
DORIS_JDBC_URL=jdbc:mysql://127.0.0.1:9030/te_doris
DORIS_USERNAME=te_doris_app
DORIS_PASSWORD=YOUR_STRONG_DORIS_PASSWORD连接原则:
配置名必须写 doris,不要命名为 mysqlAnalytics。连接池探活 SQL 用 SELECT 1,复杂 MySQL 系统表探测要关闭或单独验证。应用账号只给目标 database / table 权限,不使用 root。
写入链路优先批量化,避免高频单行 INSERT。Stream Load 用独立导入账号和 label 规则,不和只读查询账号混用。
脚本化模板
建议沉淀:
scripts/doris-verify.sh
scripts/doris-init-schema.sh
scripts/doris-stream-load.sh
scripts/doris-clean-dry-run.sh
scripts/doris-clean-confirmed.sh
docs/doris-contract.mddocs/doris-contract.md 至少写:
Doris 环境名和连接入口。database / table 命名规则。表模型、分区、分桶和副本数。
导入方式、label 命名、批次大小和重试规则。查询账号、导入账号、维护账号。清理窗口、owner、备份恢复边界。
Doris 解决的核心架构问题
Doris 适合:
报表分析、Ad-hoc 查询、实时明细分析和宽表聚合。需要 MySQL 协议生态接入的 OLAP 场景。批量导入、本地文件导入、Kafka 近实时导入和外部数据源分析。
高并发点查和复杂分析混合,但前提是表模型、分区分桶和资源隔离设计正确。团队希望通过 FE / BE 架构横向扩展查询和导入能力。
Doris 不适合:
替代 MySQL 承担 OLTP 强事务主库。高频小事务、跨行复杂事务、严格行级锁语义。只想在本地临时查一个 CSV 文件的轻量场景,这类需求优先考虑 DuckDB。
没有 owner、没有资源隔离、没有导入规范的共享分析垃圾场。
架构师判断重点不是“Doris 快不快”,而是数据模型、导入方式、分区分桶、Tablet / Replica、FE / BE 资源、查询模式、权限和恢复能力是否匹配团队实际。
主流生产架构
单机或单 FE / 单 BE 开发验证
组成:一个 FE、一个 BE、单副本表、临时数据目录。
优点:启动快、理解成本低、适合新人入门和 SQL 语义验证。
问题:
无冗余。BE 掉线后表不可用。数据目录和元数据很容易随容器销毁。
无法代表真实 Tablet / Replica / compaction 压力。
适用:个人本地、培训、最小验证。
集成存算多 FE / 多 BE
组成:多个 FE 管理元数据和请求入口,多个 BE 存储数据并执行查询。FE 通常包含 Master、Follower、Observer 角色,BE 负责 Tablet 和 Replica。
能力:
FE 高可用。BE 横向扩展存储和计算。多副本提升数据可靠性。
查询和导入可以并行分发。
核心问题:
Tablet 分布、Replica 修复、BE 磁盘和 compaction 需要持续治理。FE 元数据和 edit log 需要备份。版本升级、节点下线和重平衡转部署运维 runbook。
适用:常规自建生产 Doris。
资源隔离型共享集群
组成:同一 Doris 集群承载多个业务 database,通过账号、role、Resource Group、Workload Group、Compute Group 或命名规则隔离。
能力:
降低多套集群成本。统一样例数据和查询入口。可以按工作负载限制 CPU、内存、IO 或查询时间。
核心问题:
配置错误会让一个大查询拖慢全组。Workload Group 和 Compute Group 行为与版本、部署模式相关。清理、审计和权限回收必须有 owner。
适用:中台型团队、测试验证平台、共享分析环境。
存算分离 / 云原生 Doris
组成:计算节点或 Compute Group、共享对象存储、Meta Service / 元数据服务、缓存和资源组。
能力:
计算弹性。存储和计算独立扩展。更适合云对象存储和多工作负载隔离。
核心问题:
对象存储、缓存、元数据服务、网络和权限复杂度上升。Compute Group、Storage Vault 和对象存储能力会随版本演进,升级前必须在兼容矩阵与隔离环境中验证创建、绑定、故障恢复和退出路径。备份恢复、成本和退出方案不能靠开发文档临时补。
适用:云上弹性分析和平台化数据服务。
托管 Doris / 云服务
托管服务降低部署运维复杂度,但架构师仍然要确认:
版本和升级策略。VPC、PrivateLink、IP allowlist、跨区访问。存储、计算、冷热数据和网络出口费用。
权限、审计、备份、恢复和导出。数据退出和多云迁移路径。
控制台只能辅助观察,选型结论必须回到可复核的容量、延迟、恢复、权限和退出证据,不能依赖逐屏点击经验。
核心机制
FE / BE
FE 是控制面和入口:负责 MySQL 协议接入、SQL 解析、查询规划、元数据、节点管理和导入事务协调。BE 是数据面和执行面:负责 Tablet / Replica、数据写入、扫描、聚合、Join、compaction 和磁盘。
一个常见误判是“能登录 FE 就代表 Doris 可用”。实际判断至少要同时看 FE 和 BE:
SHOW FRONTENDS;
SHOW BACKENDS;或:
SELECT `host`, `join`, `alive` FROM frontends();
SELECT `host`, `alive` FROM backends();Table、Tablet 和 Replica
Doris 表会被分区和分桶切成 Tablet,Tablet 再按副本数放到 BE 上。Tablet 太小会增加元数据、调度和 compaction 压力;Tablet 太大则影响迁移、恢复和并行度。官方导入最佳实践建议从单 Tablet 1 到 10 GB 的量级理解容量边界,而不是拍脑袋写 BUCKETS 32。
本地 BUCKETS 1 只是为了快速验证。真实环境要按:
数据总量。单 Tablet 目标大小。BE 数量。
查询并发。导入并发。副本数和恢复窗口。
重新计算。
Key Model
| 模型 | 适合 | 风险 |
|---|---|---|
| Duplicate Key | 原始明细、日志、事件、append-only 数据 | key 是排序和查询优化,不去重 |
| Aggregate Key | 写入时按 key 预聚合,适合指标汇总 | value 列必须定义聚合函数,明细会被合并 |
| Unique Key | 按 key 保留一行,支持 upsert 和更新语义 | 写入成本和语义更复杂,表设计要提前评审 |
Key Model 是建表时的架构决策。大表选错通常不是改几个参数,而是新建表、回填、校验和切换。
分区和分桶
分区解决生命周期和查询裁剪,分桶解决数据分布和并行度。常见规则:
时间型明细常按天、月或业务周期分区。不按用户、request_id、设备号这类高基数字段分区。分桶键要兼顾写入分布、查询过滤和 Join 模式。
分桶数要跟 BE 数量、Tablet 大小和增长趋势一起评审。
导入事务和 label
Doris 的导入不是“把文件复制到某个目录”。Stream Load、Broker Load、Routine Load、INSERT 都会进入导入事务,label 是追踪和幂等的关键。
团队 label 规则示例:
<project>_<table>_<yyyymmddhhmm>_<batch-id>失败时要保留:
label。返回 JSON。NumberLoadedRows。
NumberFilteredRows。ErrorURL。源文件校验和。
查询计划和 Profile
排障顺序:
找慢 SQL:FE audit log、audit table 或团队日志平台。看 schema:Key Model、分区、分桶、索引、物化视图。看计划:EXPLAIN。
看运行时:Profile。看机器:BE CPU、内存、IO、网络、compaction。
不要一上来调参数。Schema 和分桶错了,Profile 只会告诉你哪里慢,不会让错误模型变正确。
资源隔离
Doris 的资源隔离和部署模式有关:集成存算常用 Workload Group 控制 CPU、内存与查询并发,存算分离还要先把会话绑定到正确的 Compute Group。团队至少要落实这些规则:
普通开发账号有查询超时和内存限制。大导入和大查询走单独窗口。共享实例不允许随意创建全局资源组。
Workload Group 变更需要 owner 和回滚说明。
备份恢复
备份不是导出 CSV。集成存算模式下,BACKUP 把数据库、表或分区快照写入远端 Repository,RESTORE 再按 repository、snapshot label 和 timestamp 找回对象;存算分离模式不能直接套用这条路径。一次有效演练必须在隔离库执行恢复,检查 SHOW RESTORE 完成、表结构一致、行数与关键聚合对账,再删除隔离库。只有远端文件存在,没有恢复结果和耗时,就无法证明 RTO、权限或密钥仍然有效。
查看版本:
SELECT VERSION();查看 FE / BE:
SHOW FRONTENDS;
SHOW BACKENDS;查看库表:
SHOW DATABASES;
SHOW TABLES FROM te_doris;
SHOW CREATE TABLE te_doris.event_demo;查看导入任务:
SHOW LOAD FROM te_doris;
SHOW ROUTINE LOAD FROM te_doris;查看正在执行的查询:
SHOW PROCESSLIST;查看权限:
SHOW GRANTS;
SHOW PRIVILEGES;查询计划:
EXPLAIN
SELECT service, COUNT(*)
FROM te_doris.event_demo
WHERE event_date = "<EVENT_DATE>"
GROUP BY service;创建只读角色和用户的示意:
CREATE ROLE IF NOT EXISTS te_doris_reader;
GRANT SELECT_PRIV ON te_doris.* TO ROLE te_doris_reader;
CREATE USER "te_doris_reader"@"%" IDENTIFIED BY "YOUR_STRONG_DORIS_PASSWORD";
GRANT te_doris_reader TO "te_doris_reader"@"%";授权前先在目标版本执行 SHOW PRIVILEGES,再让低权限账号完成“查询成功、建表失败、导入失败”的反向验证。升级门禁应重跑这组三条断言,避免 privilege 名称或继承关系变化后出现越权。
能连 9030,但建表或查询失败
现象:mysql -P9030 登录成功,建表、导入或查询报错。
判断:
SHOW FRONTENDS;
SHOW BACKENDS;
SELECT `host`, `alive` FROM backends();常见原因:BE 未注册、BE heartbeat 端口不通、BE 资源不足、priority_networks 配置错、容器网络不可达。
修复:先让 BE alive,再验证 SQL。不要把 FE 登录成功误判成集群可用。
把 Doris 当 MySQL 用
现象:JDBC / BI 工具执行 MySQL 系统表探测、方言初始化或事务设置时报错。
判断:检查连接 URL、客户端方言、初始化 SQL、驱动日志。
修复:连接名写 doris-local / doris-dev-shared,方言和初始化 SQL 单独配置。不要复用 MySQL Workbench 里生产 MySQL 的连接模板。
Stream Load 返回失败或 307 处理异常
现象:curl 返回认证失败、307 重定向、连接 BE 失败或 JSON 中 Status 不是 Success。
判断:
FE HTTP 8030 是否可达。BE 相关端口是否可达。--location-trusted 是否允许跟随重定向并携带认证。
label 是否重复。NumberFilteredRows 和 ErrorURL 是否说明数据质量问题。
修复:先查网络和认证,再查文件格式、列映射和错误行。
Docker Quick Start 数据丢了
现象:容器重建后库表消失。
原因:官方 Quick Start 定位就是本地开发和测试,容器销毁可能丢数据,单副本也没有冗余。
修复:不要把 Quick Start 结果当共享实例;共享环境必须持久化 FE 元数据、BE 数据和日志,并有备份恢复。
BE 启动失败或 CPU 不支持
现象:BE 容器反复退出,日志提示指令集或启动错误。
判断:
docker logs <be-container-name> --tail 200
grep -m 1 avx2 /proc/cpuinfo || true修复:选择 no-avx2 或对应 ARM64 包 / 镜像,或换符合要求的开发机。
单副本配置被带到共享环境
现象:某个 BE 不可用后表不可查,或者恢复没有冗余。
判断:
SHOW CREATE TABLE te_doris.event_demo;看 replication_num。
修复:本地 demo 保留 replication_num=1;共享和生产按 BE 数量、磁盘、恢复窗口设计多副本。
分区分桶设计错误
现象:导入慢、查询慢、某个 BE 热点、Tablet 数量过多。
判断:看 SHOW CREATE TABLE、导入批次、BE 负载、Profile 和 Tablet 分布。
修复:重新评审分区粒度、分桶键、BUCKETS 和数据增长。大表通常需要新表回填,而不是在线改几个字段。
高频小批量导入拖慢集群
现象:Load 任务多、compaction 压力大、BE CPU / IO 飙升。
判断:
SHOW LOAD FROM te_doris;
SHOW ROUTINE LOAD FROM te_doris;修复:应用侧批量化、使用 Group Commit、Routine Load 或更适合的批量导入方式。每条事件一次 Stream Load 是坏味道。
权限看似只读但仍能拖垮资源
现象:只读账号执行大查询,把共享实例内存和 CPU 打满。
判断:SHOW PROCESSLIST、FE audit log、Profile、Workload Group 配置。
修复:只读账号也要有超时、内存、并发和审计限制。生产只读不是无限查询许可。
Doris 凭证治理重点:
root 空密码只允许本地临时验证,不进入共享实例和项目配置。每个项目至少拆分 reader、writer、maintainer 三类账号。Stream Load 账号要能写目标表,但不应拥有全局管理员权限。
BI / GUI 默认只读,并限制导出。连接串和密码来自环境变量、secret 或密码库,不提交 .env。FE Web UI 只给受控账号访问,不暴露在不可信网络。
导入文件、错误文件、ErrorURL 下载内容和 FE audit log 都可能包含敏感数据。
敏感信息扫描示例:
rg -n "DORIS_PASSWORD|jdbc:mysql://|root:|access_key|secret_key|BEGIN .*PRIVATE KEY" .团队账号模型:
| 账号 | 用途 | 权限边界 |
|---|---|---|
| root / admin | 本地初始化、紧急修复 | 不给普通开发长期使用 |
| writer | Stream Load、批量导入 | 只写目标 database / table |
| reader | BI、查询和排障 | 只读目标 database |
| maintainer | 建表、变更、资源配置 | 走评审和变更记录 |
| ci | 冒烟验证和清理测试对象 | 只操作测试前缀 |
团队模板至少沉淀:
dev-dependencies/doris/README.md。.env.example,只保留占位符。scripts/verify-cluster.sh,验证 FE / BE alive。
scripts/init-schema.sql,创建 database、table、分区、分桶和副本配置。scripts/stream-load-demo.sh,带 label、错误输出和结果判断。scripts/clean-dry-run.sh 和 scripts/clean-confirmed.sh。
docs/doris-contract.md,写清 Key Model、分区、分桶、导入方式、owner、保留期、权限和资源限制。
团队职责:
| 角色 | 负责 |
|---|---|
| 架构 / 数据 owner | Key Model、分区分桶、Tablet / Replica、导入链路和查询边界 |
| 后端 / 数据接入 owner | JDBC、Stream Load、批次、label、重试和错误行处理 |
| 测试 owner | 样例数据、脱敏、回归查询和清理脚本 |
| 平台 / 运维 owner | 共享实例、资源、备份恢复、监控和升级 |
| 安全 owner | 账号、FE Web、导出、日志、凭证和审计 |
上线到共享环境前必须确认:
数据脱敏来源。大导入窗口。默认查询超时。
账号权限。清理窗口。备份和恢复演练边界。
FE 能连不等于集群可用
9030 登录成功只证明 FE query port 可用。BE 不 alive 时,表创建、导入、扫描都会失败。判断入口是 frontends()、backends()、SHOW FRONTENDS、SHOW BACKENDS。团队验证脚本必须先检查节点状态,再做 SQL。
Doris 不是 MySQL 替代品
Doris 兼容 MySQL 协议,不代表兼容 MySQL 所有语义。连接池、BI 工具和客户端方言都要单独验证。连接名必须带 doris 和环境,避免开发误以为这是事务型 MySQL 库。
root 空密码会把本地坏习惯带进团队
Quick Start 可以用 root 空密码体验;共享环境必须改密码并创建项目账号。检查项是 SHOW GRANTS、账号清单、连接配置和 FE Web 登录方式。任何长期脚本里出现 -uroot 都要评审。
单副本是本地演示,不是可靠性方案
Quick Start 建表示例使用 replication_num=1。这方便本地跑通,但 BE 掉线就没有冗余。共享环境至少要写清副本数、BE 数量、磁盘和恢复窗口;生产多副本策略转部署运维 runbook。
FE 元数据不是临时缓存
FE 管元数据和节点状态。FE 元数据目录如果没有持久化,重启或重建容器后库表状态可能丢失。共享环境必须明确 FE 元数据路径、备份策略和恢复演练。
BE 存储路径和磁盘会决定稳定性
BE 承载 Tablet / Replica 和数据文件。磁盘满、路径错、权限错会导致导入失败、查询慢或副本异常。判断入口是 SHOW BACKENDS、BE Web、BE 日志和磁盘使用率。清理不能直接删 BE 目录,必须走 Doris 对象和备份恢复流程。
Tablet / Replica 异常不是 SQL 问题
查询失败、导入失败、某个分区不可用时,可能是 Tablet 或 Replica 状态异常。工具效率只写判断入口和边界,修复、迁移、下线 BE、补副本要转部署运维;但开发团队必须知道这不是改 SQL 能解决的事。
分桶键和 BUCKETS 是架构决策
分桶错误会制造单 BE 热点、Join shuffle 变重、导入慢和查询慢。判断入口是表 DDL、Profile、BE 负载和 Tablet 分布。大表改分桶通常需要新表回填,不能靠小参数热修。
分区过细会制造元数据和导入压力
按用户、设备、request_id 分区会产生大量 partition / Tablet。导入时一个批次跨太多分区会激活大量 MemTable,内存和 compaction 压力上升。分区按生命周期和查询裁剪设计,不按字段看起来“细”就用。
Key Model 选错会改变数据语义
Duplicate Key 不去重,Aggregate Key 会聚合,Unique Key 会按 key 保留一行。选错后,查询结果不是“慢一点”,而是语义错。上线前必须用重复数据、更新数据和聚合数据分别验证。
高频小批量导入会拖垮 compaction
每几行一次 Stream Load 会产生大量小事务和小 segment,FE / BE 调度和 compaction 压力上升。修复优先批量化、Group Commit、Routine Load 或异步批量导入,不是盲目扩容 BE。
label 不治理会让重试不可追踪
Stream Load label 是幂等和审计关键。没有 label 命名规范,就很难判断是重复导入、失败重试还是新批次。团队必须把 label、源文件校验和、错误输出保存到导入日志。
查询资源隔离不能靠自觉
只读账号也能发起大查询。共享实例必须有超时、并发、内存和 Workload Group / Resource Group 边界。判断入口是 SHOW PROCESSLIST、Profile、FE audit log 和资源组配置。
Schema Change 和 Rollup 不是小操作
大表结构变更、物化视图、Rollup、索引调整可能占用长时间和大量资源。上线前要有影子表、回填、校验和回滚计划。工具效率只写入口和风险,正式变更转数据库变更治理。
备份恢复不能停在“文件存在”
备份文件存在不等于可恢复。最小闭环是恢复到临时库、查行数、查关键聚合、验证权限和导入状态。生产备份恢复转部署运维,但团队开发环境也要知道恢复演练才算闭环。
真实数据导入是最高优先级安全风险
分析库常接触日志、行为明细、手机号、邮箱、订单号、地理位置和设备号。样例数据必须脱敏,错误文件、Profile、FE audit log、BI 导出也要审查。不要把“只读分析”误判成低风险。
本机跑通:
Doris 精确版本、CPU 包型、镜像 tag 和兼容矩阵一致。Docker Quick Start 只用于本地开发和测试。mysql 客户端可连接 FE query port 9030。
FE 的 join 和 alive 正常。BE 的 alive 正常。端口 8030、9030、8040、9050、9060、8060 没有冲突。
已确认 CPU 架构和 avx2 / no-avx2 边界。建库建表成功。INSERT 查询成功。
Stream Load 返回 Status: Success。EXPLAIN 可执行。测试库表可清理。
项目接入:
连接配置命名为 Doris,不伪装成 MySQL。应用账号不是 root。.env.example 只有占位值。
JDBC / BI / GUI 探活 SQL 已验证。Key Model、分区、分桶、replication_num 进入 DDL 和评审。Stream Load label 有命名规范。
错误行和导入结果会被记录。生产环境破坏性脚本默认拒绝执行。
架构判断:
单机验证、多 FE / 多 BE、共享实例、存算分离、Kubernetes / Operator 和托管服务边界已写清。FE 元数据、BE 数据、日志和备份目录有 owner。Tablet 大小、分桶数、副本数按数据量和 BE 数量评审。
查询资源、导入资源和共享实例配额有策略。备份恢复至少有临时库恢复演练计划。
安全治理:
root 空密码不进入共享实例。FE Web 不暴露到不可信网络。真实 CSV / Parquet / 日志不进仓库。
错误文件、Profile、audit log 不含真实敏感值。BI / GUI 默认只读。权限回收、账号审计和清理窗口有责任人。
