跳到主要内容

Shell Scripts

本页面介绍如何使用 DockerHub 上提供的预构建 Docker 镜像在 Minikube 上操作 Hive on MR3。所有组件(Metastore、HiveServer2、MR3 DAGAppMaster 和 MR3 ContainerWorkers)将在 Minikube 内运行。对于 Metastore 数据库,我们将在 Docker 容器中运行 MySQL 数据库,但使用现有的 MySQL 数据库也可以。按照以下说明,用户将学习:

  1. 如何启动 Metastore
  2. 如何运行 Hive on MR3
  3. 如何创建 Beeline 连接并向在 Minikube 内运行的 HiveServer2 发送查询

前置条件

在 Minikube 上运行 Hive on MR3 有以下前置条件:

  • 一个正在运行的 Minikube 集群可用。
  • 用户能够执行:1) 命令 kubectl;2) 命令 docker(如果没有 MySQL 数据库可用)。

安装 Hive on MR3 后,进入 kubernetes 目录。

cd kubernetes/

在我们的示例中,所有命令由用户 gla 执行。

概述

Hive on MR3 由四个组件构成:Metastore、HiveServer2、MR3 DAGAppMaster 和 MR3 ContainerWorkers。用户手动创建一个 Metastore Pod 和一个 HiveServer2 Pod。HiveServer2 创建一个 DAGAppMaster Pod,DAGAppMaster 在执行查询时创建 ContainerWorker Pod。

运行 Hive on MR3 涉及以下步骤:

  • 用户更新 env.sh 以设置其他环境变量。
  • 用户更新目录 yaml 中的几个 yaml 文件。
  • 用户在配置目录 conf 中更新 hive-site.xmlmr3-site.xmltez-site.xml
  • 用户执行 run-metastore.shrun-hive.sh 来启动 Metastore 和 HiveServer2。

在第三步中,更新 hive-site.xmlmr3-site.xml 通常足以开始使用,因为 tez-site.xml 中的默认值在常见设置中效果良好。

启动 MySQL 数据库

为简单起见,我们将在 Docker 容器中为 Metastore 数据库运行 MySQL 数据库。

docker run -d --name mysql-server -p 3306:3306 -e MYSQL_ROOT_PASSWORD=passwd mysql:5.6
mysql --user=root --password=passwd --host=127.0.0.1 -e 'show databases;'
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
+--------------------+

创建本地目录

我们需要创建两个新的本地目录:

  1. 用于由所有 Pod 共享的 PersistentVolume
  2. 用于 ContainerWorker Pod 写入中间数据的 hostPath 卷

为 PersistentVolume 创建本地目录。在我们的示例中,我们使用 /data1/gla/workdir

mkdir /data1/gla/workdir
chmod 777 /data1/gla/workdir

为 ContainerWorker Pod 的 hostPath 卷创建本地目录。在我们的示例中,我们使用 /data1/gla/k8s

mkdir -p /data1/gla/k8s
chmod 777 /data1/gla/k8s

配置 env.sh

env.sh 是一个自我描述的脚本,包含在每个环境中应该设置的主要环境变量。

打开 env.sh 并设置以下环境变量。

vi env.sh
HIVE_DATABASE_HOST=192.168.10.1 # use your IP address (where the MySQL database is running)
  • HIVE_DATABASE_HOST 指定运行 MySQL 数据库的主机。

Docker 镜像

我们使用 DockerHub 上提供的预构建 Docker 镜像。打开 env.sh 并设置以下环境变量。

  • DOCKER_HIVE_IMG 指定 MR3 DAGAppMaster Pod 的 Docker 镜像。
  • DOCKER_HIVE_WORKER_IMG 指定 MR3 ContainerWorker Pod 的 Docker 镜像。
vi env.sh
DOCKER_HIVE_IMG=mr3project/hive:4.0.0.mr3.2.4
DOCKER_HIVE_WORKER_IMG=$DOCKER_HIVE_IMG

yaml/metastore.yamlyaml/hive.yaml 中,将 image 字段设置为 Metastore 和 HiveServer2 Pod 的 Docker 镜像。

vi yaml/metastore.yaml
spec:
template:
spec:
containers:
- image: mr3project/hive:4.0.0.mr3.2.4
vi yaml/hive.yaml
spec:
template:
spec:
containers:
- image: mr3project/hive:4.0.0.mr3.2.4

Metastore 和 HiveServer2 Pod 的资源

打开 env.sh 并设置以下环境变量,以调整分配给 HiveServer2 和 Metastore Pod 的内存大小(以 MB 为单位)。

  • HIVE_SERVER2_HEAPSIZE 应与 HiveServer2 Pod 的内存大小匹配。
  • HIVE_METASTORE_HEAPSIZE 应与 Metastore Pod 的内存大小匹配。

在我们的示例中,我们使用以下值。

vi env.sh
HIVE_SERVER2_HEAPSIZE=8192 # HiveServer2 Pod memory in MB
HIVE_METASTORE_HEAPSIZE=8192 # Metastore Pod memory in MB

打开 yaml/metastore.yaml 并设置资源以匹配 env.sh 中的 HIVE_METASTORE_HEAPSIZE

vi yaml/metastore.yaml
containers:
resources:
requests:
cpu: 1
memory: 8Gi
limits:
cpu: 1
memory: 8Gi

打开 yaml/hive.yaml 并设置资源以匹配 HIVE_SERVER2_HEAPSIZE

vi yaml/hive.yaml
containers:
resources:
requests:
cpu: 1
memory: 8Gi
limits:
cpu: 1
memory: 8Gi

DAGAppMaster Pod 的资源

默认情况下,我们为 DAGAppMaster Pod 分配 16GB 内存和 4 个 CPU。要调整资源,请更新 conf/mr3-site.xml

vi conf/mr3-site.xml
<property>
<name>mr3.am.resource.memory.mb</name>
<value>16384</value>
</property>
<property>
<name>mr3.am.resource.cpu.cores</name>
<value>4</value>
</property>

配置 PersistentVolume

更新 yaml/workdir-pv.yaml 以使用先前创建的目录创建 hostPath PersistentVolume。

vi yaml/workdir-pv.yaml
spec:
capacity:
storage: 100Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Delete
hostPath:
path: "/data1/gla/workdir"

配置 Metastore Pod

打开 yaml/metastore.yaml 并更新以下字段。

  • 删除 nodeAffinity,因为我们不使用节点亲和性规则。
  • args 包含 "--init-schema",因为这是首次运行 Metastore。
  • imagePullPolicy 设置为 IfNotPresent,因为我们从 DockerHub 下载 Docker 镜像。
vi yaml/metastore.yaml
affinity:
# nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution:
# nodeSelectorTerms:
# - matchExpressions:
# - key: roles
# operator: In
# values:
# - "masters"
containers:
args: ["start", "--kubernetes", "--init-schema"]
imagePullPolicy: IfNotPresent

配置 HiveServer2 Pod

打开 yaml/hive.yaml 并更新以下字段。

  • imagePullPolicy 设置为 IfNotPresent,因为我们从 DockerHub 下载 Docker 镜像。
vi yaml/hive.yaml
containers:
imagePullPolicy: IfNotPresent

配置 HiveServer2 的 Service

清单 yaml/hiveserver2-service.yaml 定义了一个 Service,用于将 HiveServer2 暴露到 Minikube 集群外部。使用本地机器的 IP 地址为 HiveServer2 Pod 定义一个 Service。默认情况下,HiveServer2 使用端口 9852 进行 Thrift 传输,端口 10001 进行 HTTP 传输。

vi yaml/hiveserver2-service.yaml
spec:
ports:
- protocol: TCP
port: 9852
targetPort: 9852
name: thrift
- protocol: TCP
port: 10001
targetPort: 10001
name: http
externalIPs:
- 192.168.10.1 # use your IP address

配置 MR3 DAGAppMaster 和 ContainerWorker Pod

打开 conf/mr3-site.xml 并将配置键 mr3.k8s.pod.image.pull.policy 设置为 IfNotPresent,因为我们从 DockerHub 下载 Docker 镜像。将配置键 mr3.k8s.pod.worker.hostpaths 设置为 hostPath PersistentVolume 的本地目录。

vi conf/mr3-site.xml
<property>
<name>mr3.k8s.pod.image.pull.policy</name>
<value>IfNotPresent</value>
</property>
<property>
<name>mr3.k8s.pod.worker.hostpaths</name>
<value>/data1/gla/k8s</value>
</property>

配置安全

更新 conf/hive-site.xml 中的以下配置键。

  • 两个配置键 javax.jdo.option.ConnectionUserNamejavax.jdo.option.ConnectionPassword 应与 MySQL 服务器用于 Metastore 的用户名和密码匹配。
  • hive.metastore.pre.event.listeners 设置为空,因为我们在 Metastore 端未启用安全。
  • hive.security.authorization.manager 设置为使用 SQLStdHiveAuthorizerFactory
vi conf/hive-site.xml
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>root</value>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>passwd</value>
</property>
<property>
<name>hive.metastore.pre.event.listeners</name>
<value></value>
</property>
<property>
<name>hive.security.authorization.manager</name>
<value>org.apache.hadoop.hive.ql.security.authorization.plugin.sqlstd.SQLStdHiveAuthorizerFactory</value>
</property>

配置资源

conf/hive-site.xml 中,以下配置键指定分配给 Map Task、Reduce Task 或 ContainerWorker 的资源。在我们的示例中,我们为 Map Task、Reduce Task 和 ContainerWorker 分配 2GB 内存和单个核心。

vi conf/hive-site.xml
<property>
<name>hive.mr3.map.task.memory.mb</name>
<value>2048</value>
</property>
<property>
<name>hive.mr3.map.task.vcores</name>
<value>1</value>
</property>
<property>
<name>hive.mr3.reduce.task.memory.mb</name>
<value>2048</value>
</property>
<property>
<name>hive.mr3.reduce.task.vcores</name>
<value>1</value>
</property>
<property>
<name>hive.mr3.all-in-one.containergroup.memory.mb</name>
<value>2048</value>
</property>
<property>
<name>hive.mr3.all-in-one.containergroup.vcores</name>
<value>1</value>
</property>

更新这些配置键时,应满足以下要求:

  • hive.mr3.map.task.memory.mbhive.mr3.all-in-one.containergroup.memory.mb
  • hive.mr3.map.task.vcoreshive.mr3.all-in-one.containergroup.vcores
  • hive.mr3.reduce.task.memory.mbhive.mr3.all-in-one.containergroup.memory.mb
  • hive.mr3.reduce.task.vcoreshive.mr3.all-in-one.containergroup.vcores

配置 Minikube

在启动 Hive on MR3 之前,用户应从 minikube 节点删除标签 node-role.kubernetes.io/master。这是因为 Hive on MR3 在估计 ContainerWorker Pod 的资源时不计算主节点的资源。由于 minikube 节点是 Minikube 集群中唯一的节点且是主节点,我们应该将其降级为普通节点,以便为 ContainerWorker Pod 保障资源。因此,为了能够在 minikube 节点中创建 ContainerWorker Pod,用户应执行以下命令:

kubectl label node minikube node-role.kubernetes.io/master-

启动 Metastore

要运行 Metastore,请执行脚本 run-metastore.sh。在启动 Metastore 之前,脚本会自动从 https://cdn.mysql.com/Downloads/Connector-J/mysql-connector-java-8.0.28.tar.gz 下载 MySQL 连接器,因为 --init-schema 选项被传递给 Metastore。

./run-metastore.sh
...
CLIENT_TO_AM_TOKEN_KEY=87fae4e6-22fe-4ba2-bc6c-ec6390d90e02
MR3_APPLICATION_ID_TIMESTAMP=11559
MR3_SHARED_SESSION_ID=c358fea5-3ed9-45be-a6a0-955b4d331509
configmap/client-am-config created
statefulset.apps/hivemr3-metastore created
service/metastore created

启动 HiveServer2

要运行 HiveServer2,请执行脚本 run-hive.sh

./run-hive.sh
...
CLIENT_TO_AM_TOKEN_KEY=d669b617-aa23-43b4-9ba5-75f4cc6e34d6
MR3_APPLICATION_ID_TIMESTAMP=3027
MR3_SHARED_SESSION_ID=4840bc48-f592-4673-8daf-e6972b49153d
Error from server (AlreadyExists): configmaps "client-am-config" already exists
deployment.apps/hivemr3-hiveserver2 created
service/hiveserver2 created

这些脚本在 Metastore 和 HiveServer2 Pod 内挂载以下文件:

  • env.sh
  • conf/*

这样,用户可以完全指定 Metastore 和 HiveServer2 以及 DAGAppMaster 和 ContainerWorkers 的行为。

信息

为了使对这些文件的任何更改生效,用户应在删除命名空间 hivemr3 中的现有 ConfigMaps 和 Services 后重启 Metastore 和 HiveServer2。

执行脚本 run-hive.sh 会立即启动一个 HiveServer2 Pod 和一个 DAGAppMaster Pod。HiveServer2 Pod 在 readiness probe 联系后变为就绪状态。根据 readiness probe 的配置,HiveServer2 可能会在正常运行之前重启一次。在提交查询之前不会创建任何 ContainerWorkers Pod。

kubectl get pods -n hivemr3
NAME READY STATUS RESTARTS AGE
hivemr3-hiveserver2-b9d6bdbb-484h6 1/1 Running 0 103s
hivemr3-metastore-0 1/1 Running 0 2m
mr3master-1559-0-654ff9999f-dsgj2 1/1 Running 0 73s

运行 Beeline

用户可以使用任意客户端程序(不一定是 MR3 release 中包含的 Beeline)通过使用 yaml/hiveserver2-service.yaml 创建的 Service 连接到 HiveServer2(默认打开 Thrift 端口 9852 和 HTTP 端口 10001)。在我们的示例中,我们在 Hiveserver2 Pod 内运行 Beeline。

下载示例数据集并将其复制到 PersistentVolume 的目录。

wget https://github.com/mr3project/mr3/releases/download/v2.0/pokemon.csv
cp pokemon.csv /data1/gla/workdir
chmod 777 /data1/gla/workdir/pokemon.csv

用户可以验证示例数据集在 HiveServer2 Pod 内可访问。

kubectl exec -n hivemr3 -it hivemr3-hiveserver2-b9d6bdbb-484h6 -- /bin/bash -c "ls /opt/mr3-run/work-dir/pokemon.csv"
/opt/mr3-run/work-dir/pokemon.csv

运行 Beeline。

kubectl exec -n hivemr3 -it hivemr3-hiveserver2-b9d6bdbb-484h6 -- /bin/bash -c 'export PS1="$ "; exec /bin/bash'
export USER=root
/opt/mr3-run/hive/run-beeline.sh
Output directory: /opt/mr3-run/hive/run-result/hivemr3-2025-03-19-02-25-28
# Running Beeline using Hive-MR3
...
Connecting to jdbc:hive2://hivemr3-hiveserver2-b9d6bdbb-484h6:9852/;;
Connected to: Apache Hive (version 4.0.0)
Driver: Hive JDBC (version 4.0.0)
Transaction isolation: TRANSACTION_REPEATABLE_READ
Beeline version 4.0.0 by Apache Hive
0: jdbc:hive2://hivemr3-hiveserver2-b9d6bdbb->

使用默认数据库。

0: jdbc:hive2://hivemr3-hiveserver2-b9d6bdbb-> show databases;
...
+----------------+
| database_name |
+----------------+
| default |
+----------------+
1 row selected (1.999 seconds)

创建一个名为 pokemon 的表。

0: jdbc:hive2://hivemr3-hiveserver2-b9d6bdbb-> CREATE TABLE pokemon (Number Int,Name String,Type1 String,Type2 String,Total Int,HP Int,Attack Int,Defense Int,Sp_Atk Int,Sp_Def Int,Speed Int) row format delimited fields terminated BY ',' lines terminated BY '\n' tblproperties("skip.header.line.count"="1");

导入示例数据集。

0: jdbc:hive2://hivemr3-hiveserver2-b9d6bdbb-> load data local inpath '/opt/mr3-run/work-dir/pokemon.csv' INTO table pokemon;

执行查询。

0: jdbc:hive2://hivemr3-hiveserver2-b9d6bdbb-> select avg(HP) from pokemon;
...
+---------------------+
| _c0 |
+---------------------+
| 144.84882280049567 |
+---------------------+
1 row selected (20.011 seconds)
0: jdbc:hive2://hivemr3-hiveserver2-69b7c4574> create table pokemon1 as select *, IF(HP>160.0,'strong',IF(HP>140.0,'moderate','weak')) AS power_rate from pokemon;
...
0: jdbc:hive2://hivemr3-hiveserver2-69b7c4574> select COUNT(name), power_rate from pokemon1 group by power_rate;
...
+------+-------------+
| _c0 | power_rate |
+------+-------------+
| 108 | moderate |
| 363 | strong |
| 336 | weak |
+------+-------------+
3 rows selected (1.509 seconds)

用户可以看到已创建 ContainerWorker Pod。

kubectl get pods -n hivemr3
NAME READY STATUS RESTARTS AGE
hivemr3-hiveserver2-b9d6bdbb-484h6 1/1 Running 0 5m18s
hivemr3-metastore-0 1/1 Running 0 5m35s
mr3master-1559-0-654ff9999f-dsgj2 1/1 Running 0 4m48s
mr3worker-0968-1 1/1 Running 0 62s
mr3worker-0968-2 1/1 Running 0 29s

用户可以找到仓库目录 /data1/gla/workdir/warehouse

ls /data1/gla/workdir/warehouse
pokemon pokemon1

停止 Hive on MR3

删除 HiveServer2 的 Deployment。

kubectl -n hivemr3 delete deployment hivemr3-hiveserver2
deployment.extensions "hivemr3-hiveserver2" deleted

删除 HiveServer2 的 Deployment 不会自动终止 DAGAppMaster Pod。这是功能,不是错误,这是由于 Hive on MR3 支持高可用性。例如,在正确设置环境变量 MR3_APPLICATION_ID_TIMESTAMP 后,再次执行脚本 run-hive.sh 会将现有的 DAGAppMaster Pod 附加到新的 HiveServer2 Pod。

删除 DAGAppMaster 的 Deployment。

kubectl delete deployment -n hivemr3 mr3master-1559-0
deployment.extensions "mr3master-1559-0" deleted

删除 DAGAppMaster Pod 会自动删除所有 ContainerWorker Pod。

删除 Metastore 的 StatefulSet。

kubectl -n hivemr3 delete statefulset hivemr3-metastore
statefulset.apps "hivemr3-metastore" deleted

过一会儿,命名空间 hivemr3 中应该没有 Pod 在运行。要删除所有剩余资源,请执行以下命令:

kubectl -n hivemr3 delete configmap --all; kubectl -n hivemr3 delete svc --all; kubectl -n hivemr3 delete secret --all; kubectl -n hivemr3 delete serviceaccount --all; kubectl -n hivemr3 delete role --all; kubectl -n hivemr3 delete rolebinding --all; kubectl delete clusterrole node-reader; kubectl delete clusterrolebinding hive-clusterrole-binding; kubectl -n hivemr3 delete persistentvolumeclaims workdir-pvc; kubectl delete persistentvolumes workdir-pv