Apache Impala Docker Compose 部署指南
使用 Docker Compose 一键编排 HDFS、Hive Metastore 与 Apache Impala 4.5.3 全栈的部署指南
Apache Impala Docker Compose 部署指南
目标:在 Docker 环境中使用 Compose 一键部署 Apache Impala 4.5.3(MPP 分布式 SQL 查询引擎)全栈单机伪集群——镜像内封装全部前置组件:JDK 17/8、Hadoop 3.3.6(HDFS)、Hive 3.1.3(standalone Metastore),一个网络内按角色(namenode/datanode/metastore/statestored/catalogd/impalad)启动六个容器,覆盖 21000/21050/25000 等端口,
up -d即可建表查询。全文从零演示镜像构建、配置生成、容器编排、启动验证与 SQL 实测,命令与回显均为在 Ubuntu 22.04 服务器(Docker Engine 26.x、Compose v2,网络imparnet,子网 192.168.150.0/24)上验证的结果。
一、环境信息
本文在 Ubuntu 22.04 服务器上验证:宿主机 Ubuntu 22.04.5 LTS(x86_64),内核 6.8.0-138-generic,6 核 47GB;Docker Engine v26.x,Compose v2(docker compose 子命令)。项目目录 /opt/data/quzuo/work/impala-compose。容器编排与网络规划如下:
| 容器名 | 角色 | 镜像 | IP(imparnet) | 端口映射 |
|---|---|---|---|---|
| impala-namenode | HDFS NameNode | impala-compose-namenode | 192.168.150.2 | 9870、9000 |
| impala-datanode | HDFS DataNode | impala-compose-datanode | 192.168.150.3 | 9864 |
| impala-metastore | Hive Metastore | impala-compose-metastore | 192.168.150.4 | 9083 |
| impala-statestored | Impala StateStore | impala-compose-statestored | 192.168.150.5 | 24000、25010 |
| impala-catalogd | Impala Catalog | impala-compose-catalogd | 192.168.150.6 | 26000、25020 |
| impala-impalad | Impala 查询引擎 | impala-compose-impalad | 192.168.150.7 | 21000、21050、25000、27000 |
容器网络为自定义 bridge 网络 imparnet(同一 compose 项目自动共享,显式命名并固定子网 192.168.150.0/24,详见第七章)。基础镜像:ubuntu:22.04。容器内系统管理用户 root,密码固定 q1w2e3r4(演示环境凭据,生产环境务必更换并启用 Kerberos/LDAP 认证)。
端口语义:HDFS NameNode RPC 9000、WebUI 9870;DataNode 9864;Hive Metastore Thrift 9083;statestored RPC 24000、WebUI 25010;catalogd RPC 26000、WebUI 25020;impalad Beeswax 21000、HS2 21050、WebUI 25000、KRPC 27000。
二、前置条件
- 宿主机已安装 Docker Engine 与 Compose v2:
docker --version
docker compose version
- 宿主机内存建议 ≥ 8GB(6 个 JVM/C++ 进程至少 256–512MB 每个)。
- 可联网拉取基础镜像
ubuntu:22.04;容器网络imparnet由 Compose 自动创建。 - 项目目录内备齐三个安装介质(Hadoop/Hive/Impala DEB,见第四章)。
三、为什么用 Compose 部署 Impala
Impala 由三类守护进程组成,单机全栈部署需要按序启动多个进程并正确配置互访地址:
- statestored(StateStore):集群心跳中枢,维护各节点心跳与目录主题(catalog topic)分发。
- catalogd(Catalog):元数据服务,连接 Hive Metastore 并把库表元数据发布到 StateStore 主题。
- impalad(执行引擎):接收客户端 SQL,一个进程同时承担协调者(Coordinator)与执行者(Executor)职责。
Compose 把「下载介质、解包、装 JDK、配 HDFS、配 HMS、配 Impala、按顺序启动」固化为一套可复现的编排文件,一条命令即可拉起全栈。镜像把 Hadoop 3.3.6、Hive 3.1.3、Impala 4.5.3 三个安装介质(合计约 1.6GB)在构建阶段解包就绪,运行阶段只做配置生成与进程启动。
选型对照:
| 镜像方案 | 说明 | 适用 |
|---|---|---|
| 本地构建的一体化全栈镜像(本文方案) | 同一镜像内集成 JDK、Hadoop、Hive 与 Impala 4.5.3,ROLE 决定角色 | 开发/演示/教学 |
| 官方源码仓库自构建 | 用源码仓库 docker/ 目录构建,体积大 | 紧跟源码的研发环境 |
| 各发行版 CDH 镜像 | 与发行版绑定 | 企业存量栈 |
四、项目文件结构
impala-compose/
├── docker-compose.yml # 六个服务的编排定义
├── Dockerfile # 全栈镜像构建(JDK17/8 + Hadoop + Hive + Impala)
├── entrypoint.sh # 容器入口:按 ROLE 动态生成配置并启动对应进程
├── hadoop-3.3.6.tar.gz # Hadoop 安装介质(697MB)
├── hive.tar.gz # Hive 安装介质(312MB)
└── impala.deb # Impala 4.5.3 DEB 包(577MB,Ubuntu 22.04 构建)
五、镜像构建(Dockerfile)
Dockerfile 共四个阶段:装 JDK 与依赖、装 python3、解包三个介质、放 entrypoint。
# Impala 4.5.3 全栈镜像:JDK 17/8 + Hadoop 3.3.6 + Hive 3.1.3 + Impala 4.5.3
FROM ubuntu:22.04
# 1) 安装 JDK 与 Impala DEB 依赖
# 注意:openjdk-8 与 openjdk-17 必须分步安装,同批安装会因 update-alternatives
# 注册 /usr/share/binfmts/jar 冲突而失败(实测复现)
ENV DEBIAN_FRONTEND=noninteractive
RUN mkdir -p /usr/share/binfmts && apt-get update && apt-get install -y --no-install-recommends \
binfmt-support openjdk-8-jre-headless hostname language-pack-en tzdata \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update && apt-get install -y --no-install-recommends \
openjdk-17-jdk-headless \
krb5-user libsasl2-2 libsasl2-modules libsasl2-modules-gssapi-mit \
openssh-client curl python3 \
&& rm -rf /var/lib/apt/lists/*
ENV JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
ENV HADOOP_HOME=/opt/hadoop
ENV PATH=/opt/hadoop/bin:/opt/hadoop/sbin:$PATH
# 2) 拷贝安装介质并解包 Hadoop / Hive / Impala
COPY hadoop-3.3.6.tar.gz hive.tar.gz impala.deb /tmp/
RUN mkdir -p /opt/hadoop /opt/impala \
&& tar -xzf /tmp/hadoop-3.3.6.tar.gz -C /opt \
&& mv /opt/hadoop-3.3.6 /opt/hadoop-tmp && mv /opt/hadoop-tmp/* /opt/hadoop/ \
&& tar -xzf /tmp/hive.tar.gz -C /opt \
&& mv /opt/apache-hive-3.1.3-bin /opt/hive \
&& dpkg -x /tmp/impala.deb /opt/impala \
&& mv /opt/impala/opt/impala/* /opt/impala/ \
&& rm -rf /tmp/*.tar.gz /tmp/impala.deb
# 3) 基础配置(角色相关配置由 entrypoint.sh 按 ROLE 动态生成)
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
要点:
- JDK 8 与 JDK 17 必须分步安装:同一条 RUN 里同时
apt-get install openjdk-8-jre-headless openjdk-17-jdk-headless会在 postinst 阶段因 update-alternatives 注册/usr/share/binfmts/jar冲突而报错退出(实测复现)。Impala DEB 包声明依赖openjdk-8-jre-headless,而 Impala 4.5.3 官方推荐 JDK 17 运行 impalad,两者都要装。 - python3 是 impala-shell 的运行时依赖:镜像初版未装 python3,执行
/opt/impala/shell/impala-shell直接报python3: command not found、This impala-shell package was not built to support Python . Supported Python versions are: 3.10.(实测回显)。补齐 python3 后正常,版本 3.10.12。 - Impala DEB 解包路径修正:
dpkg -x impala.deb /opt/impala后内容落在/opt/impala/opt/impala/,需上移一级(mv /opt/impala/opt/impala/* /opt/impala/)再删除空目录。 - 安装介质在构建完成后从镜像中删除(
rm -rf /tmp/*.tar.gz /tmp/impala.deb),镜像瘦身约 1.5GB。
构建命令与真实回显(缓存命中时秒级完成;首次构建需下载基础镜像并解包介质,约 5-10 分钟):
cd impala-compose
docker compose build
真实回显(尾部节选):
#18 naming to docker.io/library/impala-compose-impalad:latest 0.0s done
#18 unpacking to docker.io/library/impala-compose-impalad:latest 0.0s done
#18 DONE 0.4s
Image impala-compose-statestored Built
Image impala-compose-catalogd Built
Image impala-compose-datanode Built
Image impala-compose-impalad Built
Image impala-compose-metastore Built
Image impala-compose-namenode Built
六、容器入口(entrypoint.sh)
entrypoint 按 ROLE 环境变量决定启动哪个进程,并动态生成三套配置:HDFS(core-site.xml/hdfs-site.xml)、Hive(hive-site.xml)、Impala(impala-env.sh + 三个 flags 文件)。关键逻辑如下。
容器通过单个环境变量 ROLE 声明本节点扮演角色,其余均由入口脚本生成:
| 环境变量 | 取值 | 说明 |
|---|---|---|
ROLE | namenode/datanode/metastore/statestored/catalogd/impalad | 必填,声明本节点扮演角色 |
角色内部默认值(无需手工注入,由入口脚本生成):
JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64JAVA_TOOL_OPTIONS=" -Xms256m -Xmx512m"(JVM 堆下限 256MB、上限 512MB)IMPALA_HOME=/opt/impala、HADOOP_HOME=/opt/hadoop
6.1 HDFS 配置生成
cat > /opt/hadoop/etc/hadoop/core-site.xml <<EOF
<?xml version="1.0"?>
<configuration>
<property><name>fs.defaultFS</name><value>hdfs://namenode:9000</value></property>
<property><name>hadoop.tmp.dir</name><value>/opt/hadoop/tmp</value></property>
</configuration>
EOF
cat > /opt/hadoop/etc/hadoop/hdfs-site.xml <<EOF
<?xml version="1.0"?>
<configuration>
<property><name>dfs.replication</name><value>1</value></property>
<property><name>dfs.namenode.name.dir</name><value>/opt/hadoop/namenode</value></property>
<property><name>dfs.datanode.data.dir</name><value>/opt/hadoop/datanode</value></property>
<property><name>dfs.permissions.enabled</name><value>false</value></property>
</configuration>
EOF
cat > /opt/hadoop/etc/hadoop/hadoop-env.sh <<EOF
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
export HADOOP_HOME=/opt/hadoop
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_SECONDARYNAMENODE_USER=root
export PATH=\$PATH:/opt/hadoop/bin:/opt/hadoop/sbin
EOF
要点:容器内以 root 运行 Hadoop 3.3.x 必须显式定义 HDFS_NAMENODE_USER/HDFS_DATANODE_USER 等变量,否则 start-dfs.sh 报 no HDFS_DATANODE_USER defined。dfs.permissions.enabled=false 关闭权限校验,避免 Impala(root 运行)与 HDFS 权限模型产生不一致。
6.2 Hive Metastore 配置生成
cat > /opt/hive/conf/hive-site.xml <<EOF
<?xml version="1.0"?>
<configuration>
<property><name>hive.metastore.uris</name><value>thrift://metastore:9083</value></property>
<property><name>hive.metastore.schema.verification</name><value>false</value></property>
<property><name>javax.jdo.option.ConnectionURL</name><value>jdbc:derby:/opt/hive/metastore_db/metastore_db;create=true</value></property>
<property><name>javax.jdo.option.ConnectionDriverName</name><value>org.apache.derby.jdbc.EmbeddedDriver</value></property>
<property><name>javax.jdo.option.ConnectionUserName</name><value>APP</value></property>
<property><name>hive.metastore.dml.events</name><value>true</value></property>
<property><name>hive.metastore.event.db.notification.api.auth</name><value>false</value></property>
<property><name>datanucleus.schema.autoCreateAll</name><value>true</value></property>
</configuration>
EOF
要点:hive.metastore.dml.events=true 让 HMS 产生 DML 通知事件(Impala 4.x catalogd 轮询依赖);datanucleus.schema.autoCreateAll=true 让 Derby 元数据库首次启动自动建表;schema.verification=false 避免 Derby 首次启动版本校验失败。
6.3 Impala 配置生成(含 JVM 堆 256-512MB)
MY_HOST=$(hostname)
cat > /opt/impala/conf/impala-env.sh <<EOF
#!/bin/bash
: \${JAVA_HOME:="/usr/lib/jvm/java-17-openjdk-amd64"}
export JAVA_TOOL_OPTIONS=\${JAVA_TOOL_OPTIONS:- -Xms256m -Xmx512m}
: \${CLASSPATH:=}
: \${LD_LIBRARY_PATH:=}
: \${IMPALA_HOME:="/opt/impala"}
: \${IMPALAD_PIDFILE:="/tmp/impalad.pid"}
: \${CATALOGD_PIDFILE:="/tmp/catalogd.pid"}
: \${ADMISSIOND_PIDFILE:="/tmp/admissiond.pid"}
: \${STATESTORED_PIDFILE:="/tmp/statestored.pid"}
: \${IMPALAD_OUTFILE:="/tmp/impalad.out"}
: \${CATALOGD_OUTFILE:="/tmp/catalogd.out"}
: \${ADMISSIOND_OUTFILE:="/tmp/admissiond.out"}
: \${STATESTORED_OUTFILE:="/tmp/statestored.out"}
: \${IMPALAD_ERRFILE:="/tmp/impalad.err"}
: \${CATALOGD_ERRFILE:="/tmp/catalogd.err"}
: \${ADMISSIOND_ERRFILE:="/tmp/admissiond.err"}
: \${STATESTORED_ERRFILE:="/tmp/statestored.err"}
EOF
JVM 堆限制说明(见第十章):export JAVA_TOOL_OPTIONS=${JAVA_TOOL_OPTIONS:- -Xms256m -Xmx512m} 将 impalad Frontend 与 catalogd 的 JVM 堆限制在初始 256MB、最大 512MB。impala.sh 启用 set -u,impala-env.sh 必须完整定义 CLASSPATH/LD_LIBRARY_PATH 与四组 PID/out/err 变量,缺任一变量会报 unbound variable(实测依次出现 CLASSPATH: unbound variable 与 !service_stdout_key: unbound variable)。
三个 flags 文件(statestored_flags / catalogd_flags / impalad_flags):
cat > /opt/impala/conf/statestored_flags <<EOF
-hostname=${MY_HOST}
-v=1
-log_filename=statestored
-max_log_files=10
-max_log_size=200
EOF
cat > /opt/impala/conf/catalogd_flags <<EOF
-hostname=${MY_HOST}
-state_store_host=statestored
-hive_metastore_uris=thrift://metastore:9083
-catalog_topic_mode=full
-v=1
-log_filename=catalogd
-max_log_files=10
-max_log_size=200
EOF
cat > /opt/impala/conf/impalad_flags <<EOF
-hostname=${MY_HOST}
-catalog_service_host=catalogd
-state_store_host=statestored
-mem_limit=3072m
-v=1
-log_filename=impalad
-max_log_files=10
-max_log_size=200
-use_local_catalog=false
EOF
关键参数:
-catalog_topic_mode=full:catalogd 以全量模式发布目录主题。实测中若不用此模式,impalad 启动时可能订阅到空主题(Size=0)而陷入「Waiting for local catalog」死等(见第十五章)。-use_local_catalog=false:impalad 使用集中式目录(通过 StateStore 主题同步),这是 4.x 的默认且与catalog_topic_mode=full配套。-mem_limit=3072m:限制 impalad 进程总内存(含 JVM 与查询缓冲区)。-hostname取自容器 hostname($(hostname)),使同一镜像可通过docker run --hostname impala-impalad2直接扩展第二个执行节点(分布式部署即按此方式横向扩展 impalad 节点)。
6.4 角色启动逻辑
case $ROLE in
namenode)
if [ ! -f /opt/hadoop/namenode/current/VERSION ]; then
echo "[namenode] 首次格式化 NameNode..."
/opt/hadoop/bin/hdfs namenode -format -force
fi
/opt/hadoop/bin/hdfs --daemon start namenode
echo "[namenode] NameNode 已启动"
;;
datanode)
wait_port namenode 9000 120 || exit 1
/opt/hadoop/bin/hdfs --daemon start datanode
echo "[datanode] DataNode 已启动"
;;
metastore)
/opt/hive/bin/hive --service metastore > /opt/hive/metastore.log 2>&1 &
echo "[metastore] Hive Metastore 已启动 (9083)"
;;
statestored)
cd /opt/impala && bin/impala.sh start statestored
echo "[statestored] statestored 已启动"
;;
catalogd)
wait_port statestored 24000 120 || exit 1
sleep 5
cd /opt/impala && bin/impala.sh start catalogd
echo "[catalogd] catalogd 已启动"
;;
impalad)
wait_port statestored 24000 120 || exit 1
wait_port catalogd 26000 120 || exit 1
sleep 5
cd /opt/impala && bin/impala.sh start impalad
echo "[impalad] impalad 已启动"
;;
esac
wait_port 用 /dev/tcp 探测 TCP 端口(无需额外工具)。启动顺序保证:namenode → datanode → metastore → statestored → catalogd → impalad,且依赖方等待被依赖方端口就绪后再启动。hdfs --daemon start 绕过 start-dfs.sh 对 ssh 的依赖(容器内未装 openssh-server,实测 start-dfs.sh 会因 ssh: command not found 中断)。
七、docker-compose.yml 编排
六个服务共用同一镜像与入口脚本,仅以 ROLE 环境变量区分;数据卷 nn-data/dn-data/hms-db 持久化 NameNode 元数据、DataNode 数据块与 Derby 元数据库。网络显式命名 imparnet 并固定子网 192.168.150.0/24(避开与宿主机上其它 Docker 网络的子网冲突,192.168.200.0/24 与既有网络重叠会导致创建失败)。
services:
namenode:
build: .
container_name: impala-namenode
hostname: namenode
environment:
- ROLE=namenode
volumes:
- nn-data:/opt/hadoop/namenode
ports:
- "9870:9870"
- "9000:9000"
healthcheck:
test: ["CMD-SHELL", "cat /proc/net/tcp | grep -q ':2328 '"]
interval: 10s
timeout: 5s
retries: 30
datanode:
build: .
container_name: impala-datanode
hostname: datanode
depends_on:
- namenode
environment:
- ROLE=datanode
volumes:
- dn-data:/opt/hadoop/datanode
ports:
- "9864:9864"
metastore:
build: .
container_name: impala-metastore
hostname: metastore
depends_on:
- namenode
environment:
- ROLE=metastore
volumes:
- hms-db:/opt/hive/metastore_db
ports:
- "9083:9083"
statestored:
build: .
container_name: impala-statestored
hostname: statestored
depends_on:
- metastore
environment:
- ROLE=statestored
ports:
- "24000:24000"
- "25010:25010"
catalogd:
build: .
container_name: impala-catalogd
hostname: catalogd
depends_on:
- statestored
- metastore
environment:
- ROLE=catalogd
ports:
- "26000:26000"
- "25020:25020"
impalad:
build: .
container_name: impala-impalad
hostname: impalad
depends_on:
- catalogd
- statestored
environment:
- ROLE=impalad
ports:
- "21000:21000"
- "21050:21050"
- "25000:25000"
- "27000:27000"
networks:
default:
name: imparnet
ipam:
config:
- subnet: 192.168.150.0/24
volumes:
nn-data:
dn-data:
hms-db:
💡 说明:容器的
hostname与服务名一致,Docker 内置 DNS 让namenode:9000、metastore:9083、statestored、catalogd等主机名在项目内可解析,这正是 Impala/Hadoop 按主机名互认的前提。
注意网络名合法性的一个真实坑:Docker 默认把网络命名为 <项目名>_<网络名>(本项目为 impala-compose_default,含下划线)。Impala 的 catalogd 连接 Hive Metastore 时,Java 的 HiveMetaStoreClient.resolveUris 会把短主机名 metastore 反查为容器的规范域名(形如 impala-metastore.impala-compose_default),下划线不是合法 hostname 字符,Java URI 解析直接抛 URISyntaxException: Illegal character in hostname,catalogd 反复重试后启动超时(实测错误见第十五章)。把网络显式命名为不含下划线的 imparnet 后,规范域名变为 impala-metastore.imparnet,问题消除,catalogd 一次启动成功。这是本编排方案独有的关键差异点。
数据持久化说明:编排使用命名数据卷,容器重启/重建不丢数据:
| 服务 | 容器内路径 | 数据卷 | 内容 |
|---|---|---|---|
| namenode | /opt/hadoop/namenode | nn-data | NameNode 元数据(current/VERSION 等) |
| datanode | /opt/hadoop/datanode | dn-data | 数据块 |
| metastore | /opt/hive/metastore_db | hms-db | Derby 元数据库(库/表/分区) |
⚠️ 注意:HDFS NameNode 元数据与 DataNode 数据务必同时持久化;否则只持久化一侧会在重建后造成 DataNode 数据与元数据不一致。
八、构建与启动(真实回显)
cd impala-compose
docker compose up -d --build
真实回显(节选,六镜像构建完成并逐个创建启动容器):
Image impala-compose-namenode Built
Image impala-compose-datanode Built
Image impala-compose-metastore Built
Image impala-compose-statestored Built
Image impala-compose-catalogd Built
Image impala-compose-impalad Built
Network imparnet Creating
Container impala-namenode Creating
Container impala-namenode Created
Container impala-namenode Starting
Container impala-namenode Started
Container impala-datanode Creating
Container impala-datanode Created
...
Container impala-catalogd Started
Container impala-impalad Starting
Container impala-impalad Started
查看编排状态:
docker compose ps
真实回显:
NAME IMAGE COMMAND SERVICE STATUS
impala-catalogd impala-compose-catalogd "/entrypoint.sh" catalogd running
impala-datanode impala-compose-datanode "/entrypoint.sh" datanode running
impala-impalad impala-compose-impalad "/entrypoint.sh" impalad running
impala-metastore impala-compose-metastore "/entrypoint.sh" metastore running
impala-namenode impala-compose-namenode "/entrypoint.sh" namenode running (healthy)
impala-statestored impala-compose-statestored "/entrypoint.sh" statestored running
九、启动验证(真实回显)
9.1 各容器角色日志
impalad 容器启动日志(docker logs impala-impalad,末尾):
Using JAVA_HOME: /usr/lib/jvm/java-17-openjdk-amd64
Using hadoop native libs in '/opt/hadoop/lib/native'
Service stdout is redirected to '/tmp/impalad.out'.
Service stderr is redirected to '/tmp/impalad.err'.
(1/20) impalad on port 25000 is not ready.
(2/20) Waiting for impalad to be ready.
(3/20) impalad is ready.
[impalad] impalad 已启动
catalogd 连接 Metastore 成功的日志标志(容器内 /tmp/catalogd.*.log.INFO.*):
I1007 11:31:43.620404 32 HiveMetaStoreClient.java:517] Opened a connection to metastore, current connections: 1
I1007 11:31:43.652539 32 HiveMetaStoreClient.java:570] Connected to metastore.
statestored 注册心跳与目录主题发布的日志标志(容器内 /tmp/statestored.*.log.INFO.*):
I1007 11:31:44.669631 84 statestore.cc:570] Subscriber 'catalog-server@catalogd:26000' with type CATALOGD registered (registration id: b74f3f3ff1374f07:757978a8218afba3)
I1007 11:31:54.434285 85 statestore.cc:570] Subscriber 'impalad@impalad:27000' with type COORDINATOR AND EXECUTOR registered (registration id: d84eecce869396c7:69384375fe5694a3)
I1007 11:31:54.434413 44 statestore.cc:515] Preparing initial catalog-update topic update for impalad@impalad:27000. Size = 259.00 B
Size = 259.00 B 表明 impalad 订阅目录主题时 catalogd 已发布数据,这是启动一次成功的关键。
9.2 服务状态与端口
在各容器内分别查询(impala.sh 只查本机 PID 文件,需在对应容器内执行):
docker exec impala-statestored /opt/impala/bin/impala.sh status statestored
docker exec impala-catalogd /opt/impala/bin/impala.sh status catalogd
docker exec impala-impalad /opt/impala/bin/impala.sh status impalad
真实回显:
statestored is running with PID 30.
catalogd is running with PID 32.
impalad is running with PID 47.
跨容器端口连通性(从 impalad 容器内探测其它组件):
docker exec impala-impalad bash -c 'for hp in statestored:24000 statestored:25010 catalogd:26000 catalogd:25020 namenode:9000 metastore:9083; do h=${hp%%:*}; p=${hp##*:}; timeout 2 bash -c "echo > /dev/tcp/$h/$p" 2>/dev/null && echo "$hp OPEN" || echo "$hp CLOSED"; done'
真实回显:
statestored:24000 OPEN
statestored:25010 OPEN
catalogd:26000 OPEN
catalogd:25020 OPEN
namenode:9000 OPEN
metastore:9083 OPEN
9.3 impala-shell SQL 全流程
进入 impalad 容器执行(impala-shell 依赖 python3,镜像已安装):
docker exec -it impala-impalad bash
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64
/opt/impala/shell/impala-shell -i impalad:21000 --protocol=beeswax
连接回显:
Starting Impala Shell with no authentication using Python 3.10.12
Warning: live_progress only applies to interactive shell sessions, and is being skipped for now.
Opened TCP connection to impalad:21000
Connected to impalad:21000
Server version: impalad version 4.5.3-RELEASE RELEASE (build b3e78704d824efd8f9ecb884d4aa1c09d4e12017)
建表、插入、查询(非交互,-q 单条执行):
/opt/impala/shell/impala-shell -i impalad:21000 --protocol=beeswax \
-q "CREATE TABLE IF NOT EXISTS default.emp (id INT, name STRING, dept STRING, salary INT) STORED AS PARQUET;"
真实回显:
Query: CREATE TABLE IF NOT EXISTS default.emp (id INT, name STRING, dept STRING, salary INT) STORED AS PARQUET
+-------------------------+
| summary |
+-------------------------+
| Table has been created. |
+-------------------------+
Fetched 1 row(s) in 1.63s
/opt/impala/shell/impala-shell -i impalad:21000 --protocol=beeswax \
-q "INSERT INTO default.emp VALUES (1, \"Alice\", \"Eng\", 12000), (2, \"Bob\", \"Sales\", 9000), (3, \"Carol\", \"Eng\", 15000);"
真实回显:
Query: INSERT INTO default.emp VALUES (1, "Alice", "Eng", 12000), (2, "Bob", "Sales", 9000), (3, "Carol", "Eng", 15000)
Query submitted at: 2026-10-07 11:33:35 (Coordinator: http://impalad:25000)
Query state can be monitored at: http://impalad:25000/query_plan?query_id=a64b6ba502d06822:c26f7c3300000000
Modified 3 row(s) in 5.75s
/opt/impala/shell/impala-shell -i impalad:21000 --protocol=beeswax \
-q "SELECT id, name, dept, salary FROM default.emp ORDER BY salary DESC;"
真实回显:
Query: SELECT id, name, dept, salary FROM default.emp ORDER BY salary DESC
Query submitted at: 2026-10-07 11:33:41 (Coordinator: http://impalad:25000)
Query state can be monitored at: http://impalad:25000/query_plan?query_id=ab463c75bf2ffad3:3c76371a00000000
+----+-------+-------+--------+
| id | name | dept | salary |
+----+-------+-------+--------+
| 3 | Carol | Eng | 15000 |
| 1 | Alice | Eng | 12000 |
| 2 | Bob | Sales | 9000 |
+----+-------+-------+--------+
Fetched 3 row(s) in 0.52s
9.4 WebUI 检查
| 页面 | 地址 | 内容 |
|---|---|---|
| impalad 查询界面 | http://localhost:25000 | 查询列表、/backends 执行节点 |
| statestored 心跳界面 | http://localhost:25010 | /topics 目录主题、订阅者心跳 |
| catalogd 元数据界面 | http://localhost:25020 | 数据库/表缓存统计 |
| NameNode | http://localhost:9870 | HDFS 文件与块 |
| DataNode | http://localhost:9864 | 数据块状态 |
例如查看已注册的执行节点(真实回显节选):
curl -s http://localhost:25000/backends | grep -oE "impalad[0-9]*:[0-9]+" | sort -u
impalad:25000
impalad:27000
十、JVM 与常用配置修改
10.1 JVM 堆内存限制(256-512MB)
Impala 由 C++ 主进程(impalad/catalogd/statestored)与 Java 组件(impalad 的 Frontend、catalogd 的 JNI 部分)组成。JVM 堆限制写在 /opt/impala/conf/impala-env.sh:
export JAVA_TOOL_OPTIONS=${JAVA_TOOL_OPTIONS:- -Xms256m -Xmx512m}
-Xms256m:JVM 初始堆 256MB;-Xmx512m:JVM 最大堆 512MB;JAVA_TOOL_OPTIONS会被 JVM 启动时自动读取(日志出现Picked up JAVA_TOOL_OPTIONS: -Xms256m -Xmx512m),作用于 impalad Frontend 与 catalogd 的 JVM 部分。
修改堆大小,例如改为 512MB-1GB:
# 在 impala-impalad / impala-catalogd 容器内
sed -i 's/-Xms256m -Xmx512m/-Xms512m -Xmx1g/' /opt/impala/conf/impala-env.sh
/opt/impala/bin/impala.sh restart catalogd # catalogd 容器内执行
/opt/impala/bin/impala.sh restart impalad # impalad 容器内执行
验证生效:
grep -E "JAVA_TOOL_OPTIONS|Xmx|Xms" /tmp/catalogd.*.log.INFO.* | tail -2
10.2 进程内存 mem_limit
-mem_limit=3072m 限制 impalad 进程总内存(含 JVM 与查询缓冲区)。小规格机器建议 1-2g,修改 impalad_flags:
sed -i 's/-mem_limit=3072m/-mem_limit=1536m/' /opt/impala/conf/impalad_flags
/opt/impala/bin/impala.sh restart impalad
10.3 修改端口
| 端口 | flags 参数 | 默认值 | 所在文件 |
|---|---|---|---|
| Beeswax | -beeswax_port | 21000 | impalad_flags |
| HS2 | -hs2_port | 21050 | impalad_flags |
| WebUI | -webserver_port | 25000 | impalad_flags |
| KRPC | -krpc_port | 27000 | impalad_flags |
| StateStore RPC | -statestore_port | 24000 | statestored_flags(同时 catalogd/impalad 需 -state_store_port=24000) |
| Catalog RPC | -catalog_service_port | 26000 | catalogd_flags |
修改端口后,所有指向该端口的组件(如 impalad 的 -catalog_service_host、-state_store_host 对应端口参数)都要同步修改并重启,compose 文件里的端口映射也要同步调整。
10.4 修改日志
三个 flags 文件里统一控制:
-log_dir=/var/log/impala
-log_filename=impalad
-max_log_files=10
-max_log_size=200
-log_dir 指定日志目录(默认写到进程 out/err 重定向的 /tmp 下带时间戳的 .INFO/.WARNING/.ERROR 文件);-max_log_files 与 -max_log_size(MB)控制轮转。修改后重启对应服务生效。
十一、配置文件持久化(conf 挂载)
如需把配置改为宿主机可编辑,可用只读挂载覆盖容器内的 flags 文件:
volumes:
- /opt/data/quzuo/work/impala-compose/conf/impalad_flags:/opt/impala/conf/impalad_flags:ro
即先在宿主机准备好 impalad_flags(内容同第六章,可按需修改),再挂载到容器内只读。对 statestored/catalogd 同理挂载 statestored_flags/catalogd_flags。
十二、等价 docker run 运行方式
不使用 Compose 的等价单容器启动方式(每个角色一条独立命令,禁止循环批量)。先一次性创建网络(与第七章编排中的固定子网一致):
docker network create --subnet=192.168.150.0/24 imparnet
再逐个启动(镜像为 compose 构建产出的各角色镜像):
docker run -d --name impala-namenode --network imparnet --hostname namenode -e ROLE=namenode impala-compose-namenode
docker run -d --name impala-datanode --network imparnet --hostname datanode -e ROLE=datanode impala-compose-datanode
docker run -d --name impala-metastore --network imparnet --hostname metastore -e ROLE=metastore impala-compose-metastore
docker run -d --name impala-statestored --network imparnet --hostname statestored -e ROLE=statestored impala-compose-statestored
docker run -d --name impala-catalogd --network imparnet --hostname catalogd -e ROLE=catalogd impala-compose-catalogd
docker run -d --name impala-impalad --network imparnet --hostname impalad -e ROLE=impalad impala-compose-impalad
--hostname 保证各节点按主机名互认(与 Compose 一致)。同一镜像也可用 docker run --hostname impala-impalad2 --network imparnet -e ROLE=impalad impala-compose-impalad 直接扩展第二个执行节点(分布式部署即按此方式横向扩展 impalad 节点,见第六章)。
十三、常用运维命令
docker compose ps # 查看各节点状态
docker compose logs -f impalad # 跟随查看 impalad 日志
docker compose exec impalad bash # 进入 impalad 节点
docker compose restart impalad # 重启 impalad(catalogd/statestored 同理)
docker compose down # 停止并删除容器(保留数据卷)
docker compose down -v # 停止并连同数据卷一起删除(演示用)
节点内部启停/健康检查:
docker compose exec impalad bash -c 'cd /opt/impala && bin/impala.sh status impalad'
docker compose exec impalad bash -c 'cd /opt/impala && bin/impala.sh health impalad'
查询验证:
docker compose exec impalad bash -c 'cd /opt/impala/shell && ./impala-shell -i impalad -q "SHOW DATABASES;"'
实测回显:
Connected to impalad:21050
Server version: impalad version 4.5.3-RELEASE RELEASE (build b3e78704d824efd8f9ecb884d4aa1c09d4e12017)
Query: SHOW DATABASES
+------------------+----------------------------------------------+
| name | comment |
+------------------+----------------------------------------------+
| _impala_builtins | System database for Impala builtin functions |
| default | Default Hive database |
+------------------+----------------------------------------------+
Fetched 2 row(s) in 0.09s
十四、CentOS 8 兼容性说明(真实约束)
Impala 官方发布的 4.5.3 DEB 二进制是针对 Ubuntu 22.04(glibc 2.35) 构建的。若把本编排的基础镜像换成 CentOS 8(glibc 2.28),三个守护进程(statestored/catalogd/impalad)会在动态链接阶段直接被拒绝,无法启动。以下是在 CentOS 8.4.2105(glibc 2.28)容器 impala-centos8 中执行 bin/impala.sh start statestored 的真实回显:
Using JAVA_HOME: /usr/lib/jvm/java-17-openjdk-17.0.1.0.12-2.el8_5.x86_64
HADOOP_HOME not set, using hadoop native libs in '/opt/impala/lib/native'
Service stdout is redirected to '/tmp/statestored.out'.
Service stderr is redirected to '/tmp/statestored.err'.
ps: /usr/lib64/libc.so.6: version `GLIBC_2.34' not found (required by /opt/impala/lib/native/libgcc_s.so.1)
statestored is stopped.
stderr 明细(/tmp/statestored.err):
/opt/impala/sbin/statestored: /usr/lib64/libc.so.6: version `GLIBC_2.34' not found (required by /opt/impala/sbin/statestored)
/opt/impala/sbin/statestored: /usr/lib64/libc.so.6: version `GLIBC_2.32' not found (required by /opt/impala/sbin/statestored)
/opt/impala/sbin/statestored: /usr/lib64/libm.so.6: version `GLIBC_2.29' not found (required by /opt/impala/sbin/statestored)
/opt/impala/sbin/statestored: /usr/lib64/libsasl2.so.2: no version information available (required by /opt/impala/sbin/statestored)
/opt/impala/sbin/statestored: /usr/lib64/libc.so.6: version `GLIBC_2.32' not found (required by /opt/impala/lib/native/libkudu_client.so.0)
/opt/impala/sbin/statestored: /usr/lib64/libc.so.6: version `GLIBC_2.34' not found (required by /opt/impala/lib/native/libkudu_client.so.0)
/opt/impala/sbin/statestored: /usr/lib64/libc.so.6: version `GLIBC_2.33' not found (required by /opt/impala/lib/native/libkudu_client.so.0)
/opt/impala/sbin/statestored: /usr/lib64/libm.so.6: version `GLIBC_2.29' not found (required by /opt/impala/lib/native/libkudu_client.so.0)
/opt/impala/sbin/statestored: /usr/lib64/libsasl2.so.2: no version information available (required by /opt/impala/lib/native/libkudu_client.so.0)
/opt/impala/sbin/statestored: /usr/lib64/libc.so.6: version `GLIBC_2.33' not found (required by /opt/impala/lib/native/libstdc++.so.6)
/opt/impala/sbin/statestored: /usr/lib64/libc.so.6: version `GLIBC_2.34' not found (required by /opt/impala/lib/native/libstdc++.so.6)
/opt/impala/sbin/statestored: /usr/lib64/libc.so.6: version `GLIBC_2.34' not found (required by /opt/impala/lib/native/libgcc_s.so.1)
结论与替代方案:
- 结论:官方 DEB 二进制要求 glibc ≥ 2.29(部分库需 2.34)与 GLIBCXX_3.4.26,CentOS 8 锁定 glibc 2.28,动态链接器拒绝加载,不能通过 yum 升级 glibc 解决(会破坏系统),也不是「补齐 .so 库」能解。因此 CentOS 8 上不要直接使用本 Compose 方案。
- 替代方案 A:使用 AlmaLinux 9 / Rocky Linux 9 / CentOS Stream 9(glibc 2.34)作为基础镜像替换 ubuntu:22.04,可原生运行同一 DEB 二进制。
- 替代方案 B:在 CentOS 8 上改用 Cloudera CDH 的 el8 RPM 构建(CDH 6.3 为 Impala 3.x)或自行编译 apache-impala-4.5.3 源码(需 CMake/LLVM/Maven 工具链)。
- 替代方案 C:保持 Ubuntu 22.04 平台(本方案默认),这是官方 DEB 的构建目标平台。
十五、已知限制与排查思路
15.1 网络名含下划线导致 catalogd 无法连接 Metastore
现象:catalogd 容器反复 (1/20) catalogd on port 25020 is not ready. 直到 Timed out waiting for catalogd to be ready,随后容器退出;impalad 因 wait_port catalogd 26000 超时报 [impalad] 等待 catalogd:26000 超时。
根因:compose 默认网络名 <项目名>_<网络名> 含下划线。Java 的 HiveMetaStoreClient 解析 thrift://metastore:9083 时把短主机名反查为规范域名 impala-metastore.impala-compose_default,下划线非法导致 URISyntaxException: Illegal character in hostname,catalogd 反复重试连接失败。真实错误日志:
E1007 11:15:25.610359 35 MetaStoreUtils.java:166] Got exception: java.net.URISyntaxException Illegal character in hostname at index 40: thrift://impala-metastore.impala-compose_default:9083
解法:把默认网络显式命名为不含下划线的 imparnet(见第七章 networks.default.name),catalogd 一次启动成功。排查时可用 docker exec impala-catalogd getent hosts metastore 确认解析结果。
15.2 impalad 等待本地 catalog 初始化(topic Size=0 竞态)
现象:impalad 端口 21000/21050 未监听,日志反复出现 Waiting for local catalog to be initialized, attempt: N。
根因:-use_local_catalog=false 时 impalad 从 StateStore 的 catalog-update 主题拉取元数据;若 statestored 刚启动而 catalogd 尚未发布任何条目,impalad 订阅到空主题(Size=0)后永久等待。
解法:启用 -catalog_topic_mode=full(本编排默认),并保证启动顺序 statestored → catalogd → impalad,且在 impalad 启动前确认 statestore 日志出现 Size = NNN.00 B(N>0)。排查时可先用 docker compose logs -f impalad 查看等待信息,并按序确认 statestored(24000)、catalogd(26000)已就绪。
15.3 impala-shell 报 python3 缺失
现象:/opt/impala/shell/impala-shell: line 40: python3: command not found、This impala-shell package was not built to support Python . Supported Python versions are: 3.10.
解法:镜像安装 python3(本编排 Dockerfile 已含)。这是使用官方 shell 脚本的前置条件。
15.4 子网冲突导致网络创建失败
现象:docker compose up 报 Error response from daemon: invalid pool request: Pool overlaps with other one on this address space。
解法:先 docker network ls 与 docker network inspect 排查已占用网段,改用未占用网段(本编排最终使用 192.168.150.0/24)。
15.5 安全说明
Impala 4.5.3 默认无内置认证(no-authentication),容器映射到宿主机的 21000/21050 端口可被任意客户端访问。生产环境请配置 -server_credentials(TLS)与 LDAP/Kerberos 认证,并将端口映射限制在受控网络内。系统管理凭据:root / q1w2e3r4(容器内登录或 docker exec)。
15.6 宿主机浏览器无法访问 25000 WebUI
现象:宿主机浏览器打不开 25000 Web UI。
解法:确认已映射 25000:25000,浏览器访问 http://<宿主IP>:25000,页面标题为 Apache Impala。
十六、参考链接
- Apache Impala 官网:https://impala.apache.org/
- Apache Impala 官方文档:https://impala.apache.org/impala-docs.html
- Docker Compose 官方文档:https://docs.docker.com/compose/