Doris thirdparty 回归测试使用的 Hive2/Hive3 Docker Compose 模板与引导脚本。
英文版: README.md
Hive 启动被拆分为三层互相独立的抽象:
所有服务均使用 network_mode: host,端口直接暴露在宿主机上。
| 服务 | 职责 | Hive3 端口 | Hive2 端口 |
|---|---|---|---|
hive-server | HiveServer2 (SQL/JDBC 入口) | 13000 | 10000 |
hive-metastore | Hive Metastore (HMS) | 9383 | 9083 |
hive-metastore-postgresql | Metastore 元数据库 | 5732 | 5432 |
namenode | HDFS NameNode | 8320 | 8020 |
datanode | HDFS DataNode | — | — |
容器名前缀由 CONTAINER_UID(定义在 custom_settings.env)指定。 例如 CONTAINER_UID=doris-jack- → 容器名为 doris-jack-hive3-server。
--hive-modules)每个模块对应 scripts/data/ 下的一个目录或一组专用脚本。 模块是增量刷新的:只有内容 SHA 发生变化的模块才会被重新执行。
| 模块 | 源路径 | 内容 |
|---|---|---|
default | scripts/data/default/ | default 库中的基础外部表 |
multi_catalog | scripts/data/multi_catalog/ | 多格式、多路径的外部表用例 |
partition_type | scripts/data/partition_type/ | 各类分区类型覆盖(int、string、date 等) |
statistics | scripts/data/statistics/ | 表统计与空表统计相关用例 |
tvf | scripts/data/tvf/ | TVF 测试数据(上传到 HDFS) |
regression | scripts/data/regression/ | 特殊回归数据集(serde、分隔符等) |
test | scripts/data/test/ | 轻量级冒烟测试数据 |
preinstalled_hql | scripts/create_preinstalled_scripts/*.hql | 约 77 个 HQL 文件,通过 xargs -P 并行执行 |
view | scripts/create_view_scripts/create_view.hql | View 定义 |
启动脚本会按 Hive 版本自动选择正确的文件集合:
bootstrap/hive2_only.*.list 中列出的文件bootstrap/hive3_only.*.list 中列出的文件这是内部实现细节,开发者通常不需要手工配置。
Hive 运行态(HDFS 数据、Postgres Metastore、模块 SHA 记录)存放在每个版本 4 个 Docker 命名卷中,不再使用宿主机 bind mount。共享卷前缀固定为 doris-shared。
| 卷 | 挂载位置 |
|---|---|
doris-shared-<hive_version>-namenode | NameNode 元数据 |
doris-shared-<hive_version>-datanode | DataNode 数据块 |
doris-shared-<hive_version>-pgdata | Hive Metastore Postgres 数据 |
doris-shared-<hive_version>-state | /mnt/state — 增量刷新用的各模块 SHA 文件 |
生命周期:
--hive-mode fast:卷在多次运行间保留。--hive-mode refresh:卷会先被重置,再从已发布的 baseline tarball 恢复,然后再做模块刷新。--hive-mode rebuild:卷被删除(docker volume rm)后重建为空。脚本会在两种情况下从预构建的 baseline tarball 恢复卷:
--hive-mode refresh:每次都先重置卷,再恢复已发布 baseline,然后按需对变化模块做 reconcile。--hive-mode fast:仅当卷为空时(全新 CI 主机,或手动清理过后)才恢复 baseline。恢复流程:
${HIVE_BASELINE_TARBALL_CACHE:-docker/thirdparties/docker-compose/hive/scripts/baseline}/<hive_version>-baseline-<version>.tar.gz 查找本地缓存。https://${s3BucketName}.${s3Endpoint}/regression/datalake/pipeline_data/hive_baseline/<hive_version>-baseline-<version>.tar.gz 下载。${HIVE_BASELINE_TARBALL_CACHE:-docker/thirdparties/docker-compose/hive/scripts/baseline}/<hive_version>-baseline-<version>/ 这个解压缓存目录;如果不存在,就把 tarball 解压到这里一次。alpine tar 容器把解压缓存目录恢复到 4 个卷中。HIVE_BASELINE_VERSION 后,本地缓存文件名和自动拼接的 OSS URL 会同时变化,因此 CI 主机会重新下载新发布的 baseline,而不是复用旧缓存。相关环境变量:
| 变量 | 默认值 | 作用 |
|---|---|---|
HIVE_BASELINE_TARBALL_CACHE | custom_settings.env 中的 docker/thirdparties/docker-compose/hive/scripts/baseline | 下载 tarball 和解压 baseline 目录的本地缓存目录;缓存名称会带上 HIVE_BASELINE_VERSION |
HIVE_BASELINE_VERSION | custom_settings.env 中的 20260415 | baseline 发布的唯一版本变量:同时用于本地缓存文件名和自动拼接的 OSS tarball URL |
在一次完整 bootstrap 成功后,停止容器并运行:
sudo docker compose -p "${CONTAINER_UID}hive3" \ -f docker/thirdparties/docker-compose/hive/hive-3x.yaml down bash docker/thirdparties/docker-compose/hive/scripts/snapshot-hive-baseline.sh \ "${CONTAINER_UID}hive3" /tmp/hive3-baseline.tar.gz
然后把得到的 tarball 上传到 oss://<s3BucketName>/regression/datalake/pipeline_data/hive_baseline/hive3-baseline-<version>.tar.gz(hive2 同理)。 发布新 baseline 时,只需要在 docker/thirdparties/custom_settings.env 中更新一次 HIVE_BASELINE_VERSION,随后按相同版本号生成并上传对应 tarball。
# 启动 Hive3(默认为 refresh 模式) ./docker/thirdparties/run-thirdparties-docker.sh -c hive3 # 启动 Hive2 ./docker/thirdparties/run-thirdparties-docker.sh -c hive2 # 同时启动两者 ./docker/thirdparties/run-thirdparties-docker.sh -c hive2,hive3 # 停止 Hive3 ./docker/thirdparties/run-thirdparties-docker.sh -c hive3 --stop
--hive-mode)| 模式 | 行为 | 适用场景 |
|---|---|---|
fast | 复用已有卷;若 stack 已 healthy 则跳过 compose up;完全跳过数据刷新 | 机器重启或 Docker 重启后,想尽快把之前的 Hive 环境恢复起来 |
refresh | 先把卷重置到已发布 baseline,再只重跑 SHA 发生变化的模块/HQL 文件 (默认) | 日常开发、PR 验证;改了 case 脚本或 HQL 后,希望先回到干净 baseline 再增量应用改动 |
rebuild | 拆掉 stack,清空所有卷,不复用 baseline,从本地脚本完整重建 | 明确要忽略已发布 baseline,从当前仓库内容完整构建,通常用于准备导出新的 baseline tarball |
# fast:复用已有卷,在机器重启后快速恢复之前的 docker 环境 ./docker/thirdparties/run-thirdparties-docker.sh -c hive3 --hive-mode fast # refresh:回到 baseline,并按需拾取 HQL/脚本变化(默认) ./docker/thirdparties/run-thirdparties-docker.sh -c hive3 --hive-mode refresh # rebuild:从零开始完整重建,一般用于准备导出新的 baseline ./docker/thirdparties/run-thirdparties-docker.sh -c hive3 --hive-mode rebuild
--hive-modules)只刷新关心的模块:
# 只重跑变化的 preinstalled HQL 文件(并行) ./docker/thirdparties/run-thirdparties-docker.sh -c hive3 \ --hive-mode refresh --hive-modules preinstalled_hql # 刷新两个特定模块 ./docker/thirdparties/run-thirdparties-docker.sh -c hive3 \ --hive-mode refresh --hive-modules default,multi_catalog # 显式刷新所有模块 ./docker/thirdparties/run-thirdparties-docker.sh -c hive3 \ --hive-mode refresh --hive-modules all
每次 refresh 结束时,日志都会输出一份增量刷新摘要,说明这次实际重刷了哪些内容,例如:
[hive-refresh] summary refreshed_modules=2 modules=multi_catalog,preinstalled_hql [hive-refresh] summary details=multi_catalog:run_sh=74;preinstalled_hql:files=3(create_preinstalled_scripts/run40.hql,create_preinstalled_scripts/run69.hql,create_preinstalled_scripts/run76.hql)
fast:机器或 Docker 服务刚重启,只想把之前的 Hive 容器和数据快速拉起来,不做任何刷新。refresh:正常开发默认用这个。改了 Hive case 数据、run.sh、HQL 后,用它在干净 published baseline 上增量应用改动。rebuild:刻意不使用 published baseline,而是从当前仓库状态完整 bootstrap,一般用于生成新的 baseline tarball 前的准备。./docker/thirdparties/run-thirdparties-docker.sh -c hive3 --hive-mode refresh --hive-modules preinstalled_hqlscripts/data/multi_catalog 下的一小部分数据: ./docker/thirdparties/run-thirdparties-docker.sh -c hive3 --hive-mode refresh --hive-modules multi_catalog./docker/thirdparties/run-thirdparties-docker.sh -c hive3 --hive-mode fast./docker/thirdparties/run-thirdparties-docker.sh -c hive3 --hive-mode rebuild按数据存放方式,有两种模式。
run.sh(HDFS 数据 + DDL)当测试数据文件需要上传到 HDFS 时使用这种模式。
在合适的模块下新建目录:
scripts/data/<module>/<your_dataset>/ ├── run.sh # 必需:模块刷新时被执行 └── <data files> # csv、parquet、orc 等
run.sh 必须是幂等的(反复运行不出问题):
#!/bin/bash set -x CUR_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" # 仅在 HDFS 上不存在时才上传 hadoop fs -mkdir -p /user/doris/preinstalled_data/your_dataset if [[ -z "$(hadoop fs -ls /user/doris/preinstalled_data/your_dataset 2>/dev/null)" ]]; then hadoop fs -put "${CUR_DIR}"/data/* /user/doris/preinstalled_data/your_dataset/ fi # 建表(drop 后再 create,保证幂等) hive -e " DROP TABLE IF EXISTS your_table; CREATE EXTERNAL TABLE your_table (...) STORED AS PARQUET LOCATION '/user/doris/preinstalled_data/your_dataset'; "
若仅供 Hive2 或 Hive3 使用,把 run.sh 的相对路径加入对应清单:
bootstrap/hive2_only.run_sh.list bootstrap/hive3_only.run_sh.list
create_preinstalled_scripts/(仅 HQL)适用于不需要上传 HDFS 文件的场景(指向已有 HDFS 数据的外部表,或通过 INSERT VALUES 写入内部表)。
新建 scripts/create_preinstalled_scripts/runNN.hql:
use default; DROP TABLE IF EXISTS `your_new_table`; CREATE EXTERNAL TABLE `your_new_table` ( id INT, name STRING ) STORED AS PARQUET LOCATION '/user/doris/preinstalled_data/existing_path';
约定:
DROP TABLE IF EXISTS 再 CREATE —— 不要只写 CREATE IF NOT EXISTSrunNN 编号bootstrap/hive2_only.preinstalled_hql.list 或 bootstrap/hive3_only.preinstalled_hql.listbootstrap/tpch.preinstalled_hql.list触发一次刷新让它生效:
./docker/thirdparties/run-thirdparties-docker.sh -c hive3 \ --hive-mode refresh --hive-modules preinstalled_hql
所有容器都是 network_mode: host,端口在宿主机上可直接访问。
# 进入 hive-server 容器 docker exec -it ${CONTAINER_UID}hive3-server bash # 通过 beeline 连接(PATH 里的 hive shim 会自动走这里) beeline -u "jdbc:hive2://localhost:13000/default" -n root # 也可以直接用 hive 别名 hive -e "show databases;" hive -e "show tables in default;" hive -f /path/to/your.hql
# 宿主机上的 beeline 已在 PATH 中;使用本地回环地址即可 beeline -u "jdbc:hive2://127.0.0.1:13000/default" -n root
# 执行单条查询 docker exec ${CONTAINER_UID}hive3-server \ beeline -u "jdbc:hive2://localhost:13000/default" -n root \ -e "SELECT * FROM default.your_table LIMIT 10;" # 执行 HQL 文件(文件需在容器内或已挂载的路径下) docker exec ${CONTAINER_UID}hive3-server \ hive -f /mnt/scripts/create_preinstalled_scripts/run02.hql
# 列出 HDFS 顶层目录 docker exec ${CONTAINER_UID}hadoop3-namenode \ hadoop fs -ls /user/doris/ # 检查指定路径是否存在 docker exec ${CONTAINER_UID}hadoop3-namenode \ hadoop fs -ls /user/doris/preinstalled_data/your_dataset/
# 直接连接 metastore 库(Hive3 是 5732 端口) psql -h 127.0.0.1 -p 5732 -U postgres -d metastore \ -c "SELECT TBL_NAME, DB_ID FROM TBLS LIMIT 20;"
| 日志文件 | 内容 |
|---|---|
docker/thirdparties/logs/start_hive3.log | Hive3 完整启动日志 |
docker/thirdparties/logs/start_hive2.log | Hive2 完整启动日志 |
开启详细 xtrace:
HIVE_DEBUG=1 ./docker/thirdparties/run-thirdparties-docker.sh -c hive3 --hive-mode refresh
每个阶段结束时会打印耗时:
[14:02:31] [hive3] compose up done took=18s [14:02:49] [hive3] init-hive-baseline begin [14:03:11] [hive3] init-hive-baseline done took=22s [14:03:11] [hive3] refresh-hive-modules begin (mode=refresh modules=all) [14:05:44] [hive3] refresh-hive-modules done took=153s
Metastore 健康检查失败
${CONTAINER_UID}hive3-metastore-postgresql 已 healthy:docker pstail -100 docker/thirdparties/logs/start_hive3.logHiveServer2 连不上
docker ps | grep hive3-servernc -z 127.0.0.1 13000docker exec ${CONTAINER_UID}hive3-server tail -50 /tmp/hive-server2.logJuiceFS format/init 失败
JFS_CLUSTER_META 可达(默认为 mysql://root:123456@(127.0.0.1:3316)/juicefs_meta)export JFS_CLUSTER_META=<your_uri>Refresh 明显变慢
--hive-modules preinstalled_hql容器被硬杀后状态残留
--hive-mode rebuild 重置干净Baseline 下载慢或失败
https://${s3BucketName}.${s3Endpoint}/regression/datalake/pipeline_data/hive_baseline/${HIVE_BASELINE_TARBALL_CACHE:-docker/thirdparties/docker-compose/hive/scripts/baseline}/<hive_version>-baseline-<version>.tar.gz 即可跳过下载docker/thirdparties/custom_settings.env 中的 s3BucketName 和 s3Endpoint 设置正确手动查看或删除卷
# 列出某个版本的 4 个卷 docker volume ls | grep "${CONTAINER_UID}hive3-" # 删除全部 4 个(等价于 --hive-mode rebuild 的清理步骤) for s in namenode datanode pgdata state; do docker volume rm -f "${CONTAINER_UID}hive3-${s}" done