Appearance
Hadoop3.x集成Hive3.1.2
前置
部署JDK
部署Zookeeper
部署Hadoop
部署MySQL
创建hive使用的用户和数据库
sql
#授权用户名的权限,赋予任何主机访问数据的权限
CREATE DATABASE IF NOT EXISTS hive DEFAULT CHARACTER SET utf8;
# 创建hive用户
create user 'hive'@'%' identified by 'hive_password';
GRANT ALL PRIVILEGES ON hive.* to 'hive'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;安装Hive
https://archive.apache.org/dist/hive/hive-3.1.2/apache-hive-3.1.2-bin.tar.gz
解压、重命名
在/data/software目录
tar -zxf apache-hive-3.1.2-bin.tar.gz
mv apache-hive-3.1.2-bin hive配置修改
修改环境变量
bash
$ cat > /etc/profile.d/hive-env.sh <<"EOF"
export HIVE_HOME=/data/software/hive
export PATH=$PATH:$HIVE_HOME/bin
EOF
$ source /etc/profile配置hive-env.sh
bash
HADOOP_HOME=/data/software/hadoop
export HIVE_CONF_DIR=/data/software/hive/conf
export HIVE_AUX_JARS_PATH=/data/software/hive/lib配置hive-site.xml
xml
<!-- 记录Hive中的元数据信息 记录在mysql中 -->
<property>
<name>hive.metastore.db.type</name>
<value>mysql</value>
<description>
指定 Hive 元数据存储的类型为 MySQL,Hive 的元数据(如表结构、分区信息等)存储在数据库中,而非本地文件
支持MySQL、PostgreSQL、Oracle,需要注意ConnectionURL、ConnectionDriverName的配置
</description>
</property>
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop01:3306/hive?createDatabaseIfNotExist=true&useSSL=false&allowPublicKeyRetrieval=true&characterEncoding=UTF8&useUnicode=true</value>
<description>数据库的连接 URL</description>
</property>
<property>
<name>javax.jdo.option.ConnectionDriverName</name>
<value>com.mysql.cj.jdbc.Driver</value>
<description>指定 MySQL JDBC 驱动类名,对应的JDBC文件需要放入lib目录</description>
</property>
<!-- mysql的用户名和密码 -->
<property>
<name>javax.jdo.option.ConnectionUserName</name>
<value>hive</value>
<description>数据库的用户名</description>
</property>
<property>
<name>javax.jdo.option.ConnectionPassword</name>
<value>hive_password</value>
<description>数据库的密码</description>
</property>
<property>
<name>hive.metastore.warehouse.dir</name>
<value>/user/hive/warehouse</value>
<description>Hive 默认的仓库目录(存储表数据)</description>
</property>
<property>
<name>hive.exec.scratchdir</name>
<value>/user/hive/tmp</value>
<description>
Hive 执行临时文件的存储目录(如 MapReduce 任务的中间结果)
</description>
</property>
<property>
<name>hive.querylog.location</name>
<value>/user/hive/log</value>
<description>Hive 查询日志的存储路径</description>
</property>
<!-- hiveserver的工作目录 -->
<property>
<name>hive.exec.local.scratchdir</name>
<value>/data/soft_data/hive/tmp/hiveuser</value>
<description>本地临时目录(用于本地模式或任务执行时的临时文件)</description>
</property>
<property>
<name>hive.downloaded.resources.dir</name>
<value>/data/soft_data/hive/tmp/${hive.session.id}_resources</value>
<description>
定义临时资源下载目录
当 Hive 执行查询时,如果需要从远程(如 HDFS 或 HTTP)下载资源(如 UDF 的 JAR 包、配置文件等),这些资源会被临时存储到该目录中
会话隔离:
通过 ${hive.session.id} 动态变量,每个 Hive 会话(Session)的资源会存储到以会话 ID 为后缀的子目录中,避免不同会话间的资源冲突
运行 Hive 的用户需要对 /data/soft_data/hive/tmp 目录有读写权限
</description>
</property>
<!-- hiveserver的日志路径配置 -->
<property>
<name>hive.server2.logging.operation.log.location</name>
<value>/data/soft_logs/hive/tmp/operation_logs</value>
<description>
定义 HiveServer2 操作日志的存储路径
该配置指定 HiveServer2 服务在执行用户查询或操作时生成的日志文件(Operation Logs)的存储目录
</description>
</property>
<!-- 客户端远程连接 -->
<property>
<name>hive.server2.thrift.client.user</name>
<value>hadoop</value>
<description>指定 HiveServer2 Thrift 客户端连接时使用的用户名</description>
</property>
<property>
<name>hive.server2.thrift.client.password</name>
<value>hadoop123</value>
<description>指定 HiveServer2 Thrift 客户端连接时使用的密码</description>
</property>
<property>
<name>hive.server2.thrift.port</name>
<value>10000</value>
<description>HiveServer2 的 Thrift 服务监听端口。</description>
</property>
<property>
<name>hive.server2.thrift.bind.host</name>
<value>0.0.0.0</value>
<description>绑定到所有网络接口(允许远程连接)</description>
</property>
<property>
<name>hive.server2.webui.host</name>
<value>0.0.0.0</value>
<description>定义 HiveServer2 Web UI 的监听主机地址</description>
</property>
<!-- hive服务的页面的端口 -->
<property>
<name>hive.server2.webui.port</name>
<value>10002</value>
<description>HiveServer2 Web UI 的监听端口</description>
</property>
<property>
<name>hive.server2.long.polling.timeout</name>
<value>5000</value>
<description>定义 HiveServer2 长轮询的超时时间(毫秒)</description>
</property>
<property>
<name>hive.server2.enable.doAs</name>
<value>true</value>
<description>
是否启用用户代理(true 表示 HiveServer2 以客户端用户身份执行操作)
</description>
</property>
<property>
<name>datanucleus.autoCreateSchema</name>
<value>false</value>
<description>控制 DataNucleus(Hive 元数据存储的 JPA 实现)是否自动创建数据库模式</description>
</property>
<property>
<name>datanucleus.fixedDatastore</name>
<value>true</value>
<description>控制 DataNucleus 是否允许对数据库模式进行动态修改</description>
</property>
<property>
<name>hive.execution.engine</name>
<value>mr</value>
<description>
定执行引擎
mr:MapReduce(默认)
tez 或 spark:更高效的引擎(需额外安装)
</description>
</property>
<!-- zookeeper 相关配置 -->
<property>
<name>hive.zookeeper.quorum</name>
<value>hadoop01,hadoop02,hadoop03</value>
<description>
ZooKeeper 集群地址列表,用于服务发现和协调
可以带端口或配置多个地址以逗号隔开确保高可用,如:zk1:2181,zk2:2181,zk3:2181
</description>
</property>
<property>
<name>hive.server2.support.dynamic.service.discovery</name>
<value>true</value>
<description>
启用动态服务发现(通过 ZooKeeper 自动发现 HiveServer2 实例)
</description>
</property>
<property>
<name>hive.server2.zookeeper.namespace</name>
<value>hiveserver2</value>
<description>
ZooKeeper 中 HiveServer2 的命名空间路径(与 JDBC 连接字符串中的 zooKeeperNamespace 一致)
</description>
</property>
<property>
<name>hive.server2.zookeeper.publish.configs</name>
<value>true</value>
<description>控制 HiveServer2 是否将配置信息发布到 ZooKeeper</description>
</property>
<!-- 配置metastore高可用 -->
<property>
<name>hive.metastore.uris</name>
<value>thrift://hadoop01:9083,thrift://hadoop02:9083,thrift://hadoop03:9083</value>
<description>
远程元存储的Thrift URI。元存储客户端用于连接到远程元存储,配置多个 Hive Metastore 服务的 URI,实现高可用
</description>
</property>
<property>
<name>hive.metastore.uri.selection</name>
<value>RANDOM</value>
<description>
Metastore URI 的选择策略看,可选 [sequential, random].
SEQUENTIAL:按顺序尝试连接
RANDOM:随机选择一个可用的 Metastore。
确定元存储客户端用于连接到远程元存储的选择机制。
SEQUENTIAL意味着将从作为hive.metastore.URIs的一部分指定的URI中选择第一个有效的元存储。
RANDOM意味着元存储将被随机选取
</description>
</property>
<!-- 配置权限 -->
<property>
<name>hive.security.authorization.createtable.owner.grants</name>
<value>ALL</value>
<description>
表创建者自动拥有的权限(ALL 表示所有权限)
每当创建表时,自动授予所有者的特权
“select,drop”这样的示例将向表的所有者授予选择和删除权限。
请注意,默认情况下,表的创建者无权访问该表(但请参阅HIVE-8067)
</description>
</property>
<!-- 是否支持distinct多个字段 -->
<property>
<name>hive.groupby.skewindata</name>
<value>false</value>
<description>
是否优化 GROUP BY 查询的倾斜数据(数据分布不均时设置为 true)
</description>
</property>
<!-- 配置update和delete操作支持 -->
<!-- 参考: https://cwiki.apache.org/confluence/display/Hive/Hive+Transactions -->
<!-- http://bcxw.net/article/202.html -->
<property>
<name>hive.support.concurrency</name>
<value>true</value>
<description>
控制 Hive 是否支持并发控制,使用ZooKeeper Hive锁管理器时,ZooKeeper实例必须已启动并正在运行
</description>
</property>
<!-- 动态分区(事务要求必须开) -->
<property>
<name>hive.exec.dynamic.partition.mode</name>
<value>strict</value>
<description>
控制 Hive 动态分区(Dynamic Partition)的严格模式(strict)或非严格模式(nostrict)
在严格模式下,用户必须至少指定一个静态分区,以防用户意外覆盖所有分区
在非严格模式下,允许所有分区都是动态的。
相关配置:
hive.exec.dynamic.partition:控制是否启用动态分区(默认为 true)
hive.exec.max.dynamic.partitions:允许的最大动态分区数(默认为 1000)
hive.exec.max.dynamic.partitions.pernode:每个节点允许的最大动态分区数(默认为 100)
</description>
</property>
<property>
<name>hive.txn.manager</name>
<value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
<description>
指定 Hive 的事务管理器(Transaction Manager)
该配置项用于指定 Hive 使用的事务管理器实现。事务管理器负责处理 Hive 中的事务操作(如插入、更新、删除等),并确保数据的一致性和完整性
设置为org.apache.hadoop.hive.ql.lockmgr.DbTxnManager作为打开Hive事务的一部分,
依赖配置:
hive.compactor.initiator.on=true:启用压缩器(Compactor),定期清理事务日志和过期数据。
hive.compactor.worker.threads:配置压缩器工作线程数。
hive.support.concurrency=true:启用并发控制。
hive.exec.dynamic.partition.mode=nostrict:允许动态分区(非必须,但推荐与事务配合使用)
默认的DummyTxnManager复制Hive-0.13之前的行为,不提供事务
</description>
</property>
<property>
<name>hive.compactor.initiator.on</name>
<value>true</value>
<description>
控制 Hive 压缩器(Compactor)的发起者线程是否运行
该配置项用于指定是否在当前 Hive Metastore 实例上运行压缩器的发起者(Initiator)线程。
压缩器是 Hive 事务功能的一部分,用于定期清理事务日志和合并小文件,从而优化存储性能和数据一致性
</description>
</property>
<property>
<name>hive.compactor.worker.threads</name>
<value>1</value>
<description>
指定 Hive 压缩器(Compactor)的工作线程数
任务调度:工作线程本身不执行压缩操作,而是负责调度 MapReduce 任务来完成压缩。
并发控制:通过调整工作线程数,可以控制同时运行的压缩任务数量,从而影响压缩效率和集群负载。
依赖配置:
hive.txn.manager=org.apache.hadoop.hive.ql.lockmgr.DbTxnManager:启用事务管理器
hive.compactor.initiator.on=true:启用压缩器的发起者线程
hive.support.concurrency=true:启用并发控制
</description>
</property>
<property>
<name>hive.enforce.bucketing</name>
<value>true</value>
<description>
强制 Hive 在写入数据时遵循分桶(Bucketing)规则:
该配置项用于控制 Hive 在写入数据到分桶表时是否严格遵循分桶规则。
分桶是将表或分区的数据按照某个字段的哈希值分布到多个文件(桶)中的技术,可以优化查询性能(如减少全表扫描)和实现高效采样
依赖配置:
hive.exec.dynamic.partition.mode=nonstrict(可选):如果分桶表涉及动态分区,可能需要启用非严格模式。
hive.optimize.bucketmapjoin=true(可选):优化分桶表的连接操作。
分桶字段的选择:分桶字段通常选择高基数字段(如用户ID、日期等),以确保数据分布均匀
分桶的适用场景:
优化JOIN操作:如果两个表按照相同的字段分桶,Hive 可以直接基于桶进行高效的 Map-side Join(无需排序或Shuffle)。
采样查询:分桶表可以快速实现基于桶的采样查询(如 SELECT * FROM table TABLESAMPLE(BUCKET 1 OUT OF 4))。
数据倾斜处理:通过分桶可以减少数据倾斜问题,提高查询效率
</description>
</property>
<!-- 小文件合并问题(可选) -->
<property>
<name>hive.merge.size.per.task</name>
<value>268435456</value>
<description>
控制合并后文件的大小:
该配置项用于指定在 Hive 作业(如 INSERT、LOAD 或 CTAS)结束后,每个合并任务(Merge Task)生成的文件的目标大小(以字节为单位)
合并的触发条件:
作业配置了 hive.merge.mapfiles=true 或 hive.merge.mapredfiles=true(默认启用)
作业生成的文件数量超过阈值(如 hive.merge.mapredfiles 的默认值为 10)
合并后的文件大小会尽量接近 hive.merge.size.per.task 的值
与其他配置的关联:
hive.merge.smallfiles.avgsize:定义小文件的平均大小阈值。如果平均文件大小小于此值,Hive 会触发合并。
hive.merge.mapfiles:是否合并 Map 阶段的输出文件(默认 true)。
hive.merge.mapredfiles:是否合并 Reduce 阶段的输出文件(默认 true)。
hive.merge.size.per.task 和 hive.merge.smallfiles.avgsize 共同决定合并的目标
</description>
</property>
<property>
<name>hive.merge.smallfiles.avgsize</name>
<value>16777216</value>
<description>
触发小文件合并的阈值
该配置项定义了 Hive 作业(如 INSERT、LOAD 或 CTAS)输出文件的平均大小阈值(以字节为单位)
如果作业生成的输出文件的平均大小小于此值,Hive 会启动一个额外的 MapReduce 任务来合并这些小文件。
合并的目标是生成更大的文件,以减少文件数量并优化存储和查询性能
合并的触发条件:
小文件检测:Hive 会计算作业输出文件的平均大小。如果平均大小小于 hive.merge.smallfiles.avgsize,则触发合并。
合并任务:合并操作是一个额外的 MapReduce 任务(或 Tez/Spark 任务),用于将多个小文件合并为更大的文件。
合并目标大小:合并后的文件大小会尽量接近 hive.merge.size.per.task(需确保已配置该参数)
与其他配置的关联
hive.merge.mapfiles:是否合并 Map 阶段的输出文件(默认 true)。
hive.merge.mapredfiles:是否合并 Reduce 阶段的输出文件(默认 true)。
hive.merge.size.per.task:合并后文件的目标大小(默认 256 MB)。
如果未配置 hive.merge.size.per.task,合并后的文件大小可能不可控
</description>
</property>
<!-- 合并mr产生的小文件 -->
<property>
<name>hive.merge.mapredfiles</name>
<value>true</value>
<description>
启用 Reduce 阶段输出文件的合并
该配置项用于控制 Hive 是否在 MapReduce 作业的 Reduce 阶段结束后,对生成的小文件进行合并操作
如果设置为 true(默认值),Hive 会在作业结束时检查输出文件的大小,并根据其他合并相关配置
(如 hive.merge.smallfiles.avgsize 和 hive.merge.size.per.task)决定是否启动额外的合并任务。
如果设置为 false,则不会对 Reduce 阶段的输出文件进行合并
依赖其他配置
合并操作是否触发还取决于 hive.merge.smallfiles.avgsize(小文件平均大小阈值)和 hive.merge.size.per.task(合并后文件的目标大小)。
如果 Reduce 阶段生成的输出文件的平均大小小于 hive.merge.smallfiles.avgsize,Hive 会启动合并任务。
合并目标
合并后的文件大小会尽量接近 hive.merge.size.per.task 的值(默认 256 MB)
</description>
</property>
<!-- 合并tez产生的小文件 -->
<property>
<name>hive.merge.tezfiles</name>
<value>true</value>
<description>Merge small files at the end of a Tez DAG</description>
</property>
<!-- 合并spark产生的小文件 -->
<property>
<name>hive.merge.sparkfiles</name>
<value>true</value>
<description>Merge small files at the end of a Spark DAG Transformation</description>
</property>配置Hadoop中的core-site.xml
文件绝对路径:/data/software/hadoop/etc/hadoop/core-site.xml,(未做权限控制,暂时不做配置)
xml
<!-- 权限配置 hadoop.proxyuser.{填写自己的用户名}.hosts-->
<property>
<name>hadoop.proxyuser.hadoop.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.hadoop.groups</name>
<value>*</value>
</property>配置Hadoop中的hdfs-site.xml
配置目录:/data/software/hadoop/etc/hadoop
xml
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
<description>
启用 WebHDFS 服务
该配置项用于控制是否启用 Hadoop 分布式文件系统(HDFS)的 WebHDFS 接口
如果设置为 true,HDFS 将启用 WebHDFS 服务,允许通过 HTTP 协议访问 HDFS 的文件系统操作(如读取、写入、删除等)。
如果设置为 false,则禁用 WebHDFS 服务,无法通过 HTTP 协议访问 HDFS
</description>
</property>上传mysql驱动包
Download MySQL Connector/J 根据需要选择版本:8.0.xx,操作系统:Platform Independent
下载后解压啥的,拿到jar包放在/data/software/hive/lib目录下
更换guava包
将hive中的guava包,更换为hadoop环境的guava包
bash
$ cd /data/software/hive/lib
$ mv guava-19.0.jar guava-19.0.jar.bak
$ cp /data/software/hadoop/share/hadoop/common/lib/guava-27.0-jre.jar .初始化metadata
取消检查schema
准备工作,修改hive-site.xml中的两个配置,初始化前取消检查schema,并自动创建
xml
<!-- 自动创建元数据schema -->
<property>
<name>datanucleus.schema.autoCreateAll</name>
<value>true</value>
</property>
<!-- 不检查schema -->
<property>
<name>hive.metastore.schema.verification</name>
<value>false</value>
</property>初始化操作
bash
$ cd /data/software/hive/bin
$ ./schematool -initSchema -dbType mysql恢复hive-site.xml文件
xml
<!-- 自动创建元数据schema -->
<property>
<name>datanucleus.schema.autoCreateAll</name>
<value>false</value>
</property>
<!-- 不检查schema -->
<property>
<name>hive.metastore.schema.verification</name>
<value>true</value>
</property>移除log4j包
hive中的日志依赖包会和hadoop的冲突,所以需要移除一个,因为 hadoop 是共用的,尽量不要删它里面的东西,因此只能去掉 Hive 的
bash
$ mv /data/software/hive/lib/log4j-slf4j-impl-2.10.0.jar /data/software/hive/lib/log4j-slf4j-impl-2.10.0.jar.bak
# rm -rf /data/software/hive/lib/log4j-slf4j-impl-2.10.0.jar启动Hive
启动hiveserver
启动过程遇到问题可查看日志文件/tmp/hadoop/hive.log
需要将hiveserver作为后台进程启动,参考使用下面的命令启动
bash
$ nohup hive --service metastore >/data/soft_logs/hive/metastore.log 2>&1 &
$ nohup hive --service hiveserver2 >/data/soft_logs/hive/hiveserver2.log 2>&1 &在zookeeper验证是否成功HA
bash
$ /data/software/zookeeper/bin/zkCli.sh -server hadoop01
# 再查看是否注册hiverserver2
ls /hiveserver2通过beeline验证hiveserver服务
bash
# 两种连接方式
# 第一种连接方式
$ beeline
> !connect jdbc:hive2://hadoop01:2181,hadoop02:2181,hadoop03:2181/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2 hadoop hadoop123
# 第二种连接方式 database_name:要连接的Hive数据库名称
beeline -u 'jdbc:hive2://hadoop01:2181,hadoop02:2181,hadoop03:2181/database_name;;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2' -n hadoop -p 'hadoop123'
jdbc:hive2://hadoop01:2181,hadoop02:2181> create table test01(id int);
jdbc:hive2://hadoop01:2181,hadoop02:2181> insert into test01 values(1),(2),(3),(4);
# 验证完成后退出
> !quit通过封装脚本管理服务
bash
#!/bin/bash
HIVE_LOG_DIR=/data/soft_logs/hive
mkdir -p $HIVE_LOG_DIR
#检查进程是否运行正常,参数1为进程名,参数2为进程端口
function check_process()
{
pid=$(ps -ef 2>/dev/null | grep -v grep | grep -i $1 | awk '{print $2}')
ppid=$(netstat -nltp 2>/dev/null | grep $2 | awk '{print $7}' | cut -d '/' -f 1)
echo $pid
[[ "$pid" =~ "$ppid" ]] && [ "$ppid" ] && return 0 || return 1
}
function hive_start()
{
metapid=$(check_process HiveMetastore 9083)
cmd="nohup hive --service metastore >$HIVE_LOG_DIR/metastore.log 2>&1 &"
#cmd=$cmd" sleep 5; hdfs dfsadmin -safemode wait >/dev/null 2>&1"
#cmd=$cmd" sleep 60"
[ -z "$metapid" ] && eval $cmd || echo "Metastroe服务已启动"
sleep 5
server2pid=$(check_process HiveServer 10000)
cmd="nohup hive --service hiveserver2 >$HIVE_LOG_DIR/hiveServer2.log 2>&1 &"
[ -z "$server2pid" ] && eval $cmd || echo "HiveServer2服务已启动"
}
function hive_stop()
{
metapid=$(check_process HiveMetastore 9083)
[ "$metapid" ] && kill $metapid || echo "Metastore服务未启动"
server2pid=$(check_process HiveServer 10000)
[ "$server2pid" ] && kill $server2pid || echo "HiveServer2服务未启动"
}
case $1 in
"start")
hive_start
;;
"stop")
hive_stop
;;
"restart")
hive_stop
sleep 2
hive_start
;;
"status")
check_process HiveMetastore 9083 >/dev/null && echo "Metastore服务运行正常" || echo "Metastore服务运行异常"
check_process HiveServer 10000 >/dev/null && echo "HiveServer2服务运行正常" || echo "HiveServer2服务运行异常"
;;
*)
echo Invalid Args!
echo 'Usage: '$(basename $0)' start|stop|restart|status'
;;
esac编码问题处理
如果已经遇到???的情况,执行以下操作并不会恢复,但是新增或修改的是正常的
sql
-- 修改字段字符集
ALTER table COLUMNS_V2 modify column COMMENT varchar(256) character set utf8;
-- 修改表注释字符集
ALTER table TABLE_PARAMS modify column PARAM_VALUE varchar(20000) character set utf8;
-- 修改分区参数,支持用中文表示
ALTER table PARTITION_PARAMS modify column PARAM_VALUE varchar(20000) character set utf8;
ALTER table PARTITION_KEYS modify column PKEY_COMMENT varchar(20000) character set utf8;
-- 修改索引名称,支持中文表示
ALTER table INDEX_PARAMS modify column PARAM_VALUE varchar(4000) character set utf8;
-- 修改视图,支持视图中文
ALTER TABLE TBLS modify COLUMN VIEW_EXPANDED_TEXT mediumtext CHARACTER SET utf8;
ALTER table TBLS modify column VIEW_ORIGINAL_TEXT mediumtext CHARACTER set utf8;xml
<!-- 在 hive-site.xml 内添加或修改mysql链接字符串 characterEncoding=UTF8 useUnicode=true -->
<property>
<name>javax.jdo.option.ConnectionURL</name>
<value>jdbc:mysql://hadoop01:3306/hive?createDatabaseIfNotExist=true&characterEncoding=UTF8&useSSL=false&useUnicode=true</value>
<description>Mysql连接协议</description>
</property>