Hive on Spark调优(大数据技术6)

文章介绍了Hive中的Join算法,包括CommonJoin、MapJoin和SortMergeBucketMapJoin,重点讲述了MapJoin和SortMergeBucketMapJoin的优化方法。MapJoin适合于小表与大表的Join,通过设置hive.auto.convert.join等相关参数进行优化。而SortMergeBucketMapJoin则利用分桶表进行优化,需要设置hive.optimize.bucketmapjoin.sortedmerge等参数,并确保分桶字段和排序。文章提供了具体的SQL示例和优化步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  文章最前: 我是Octopus,这个名字来源于我的中文名--章鱼;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github ;这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的动态,一起学习,共同进步。

相关文章:

  1. Hive on Spark调优(大数据技术1)
  2. Hive on Spark调优(大数据技术2) 
  3. Hive on Spark调优(大数据技术3)

  4. Hive on Spark调优(大数据技术4) 
  5. Hive on Spark调优(大数据技术5)

  6. Hive on Spark调优(大数据技术6)

  7. Hive on Spark调优(大数据技术7)

  8. Hive on Spark调优(大数据技术8)

  9. Hive on Spark调优(大数据技术9)


6章 Join优化

6.1 Hive Join算法概述

Hive拥有多种join算法,包括common join,map join,sort Merge Bucket Map Join等。下面对每种join算法做简要说明:

1)common join

Map端负责读取参与join的表的数据,并按照关联字段进行分区,将其发送到Reduce端,Reduce端完成最终的关联操作。

2)map join

若参与join的表中,有n-1张表足够小,Map端就会缓存小表全部数据,然后扫描另外一张大表,在Map端完成关联操作。

3)Sort Merge Bucket Map Join

        若参与join的表均为分桶表,且关联字段为分桶字段,且分桶字段是有序的,且大表的分桶数量是小表分桶数量的整数倍。此时,就可以以分桶为单位,为每个Map分配任务了,Map端就无需再缓存小表的全表数据了,而只需缓存其所需的分桶。 

6.2 Map Join优化

示例SQL语句如下:

select
    *
from
(
    select
        *
    from dwd_trade_order_detail_inc
    where dt='2020-06-16'
)fact
left join
(
    select
        *
    from dim_sku_full
    where dt='2020-06-16'
)dim
on fact.sku_id=dim.id;

6.2.1 优化前执行计划

6.2.2 优化思路

上述参与join的两表一大一小,可考虑map join优化。

Map Join相关参数如下:

--启用map join自动转换
set hive.auto.convert.join=true;
--common join转map join小表阈值
set hive.auto.convert.join.noconditionaltask.size

 6.2.3 优化后执行计划

 6.3 Sort Merge Bucket Map Join

6.3.1 优化说明

Sort Merge Bucket Map Join相关参数:

--启动Sort Merge Bucket Map Join优化
set hive.optimize.bucketmapjoin.sortedmerge=true;
--使用自动转换SMB Join
set hive.auto.convert.sortmerge.join=true;

6.3.2 优化案例

1)示例SQL语句

select
    *
from(
    select
        *
from  dim_user_zip  
where dt='9999-12-31'
)duz
join(
    select
        *
    from dwd_trade_order_detail_inc
    where dt='2020-06-16'
)dtodi

on duz.id=dtodi.user_id;

2)优化前

上述SQL语句共有两张表一次join操作,故优化前的执行计划应包含一个Common Join任务,通过一个MapReduce Job实现。

3)优化思路

经分析,参与join的两张表,数据量如下:

表名

大小

dwd_trade_order_detail_inc

162900000000(约160g)

dim_user_zip

12320000000 (约12g)

两张表都相对较大,可以考虑采用SMBSMB Map Join对分桶大小是没有要求的。下面演示如何使用SMB Map Join。

首先需要依据源表创建两个的有序的分桶表,dwd_trade_order_detail_inc建议分36个bucket,dim_user_zip建议分6个bucket,注意分桶个数的倍数关系以及分桶字段和排序字段

--订单明细表
hive (default)> 
drop table if exists dwd_trade_order_detail_inc_bucketed;
create table dwd_trade_order_detail_inc_bucketed(
id string,
order_id string,
user_id string,
sku_id string,
province_id string,
activity_id string,
activity_rule_id string,
coupon_id string,
date_id string,
create_time string,
source_id string,
source_type_code string,
source_type_name string,
sku_num bigint,
split_original_amount decimal(16,2),
split_activity_amount decimal(16,2),
split_coupon_amount decimal(16,2),
split_total_amount decimal(16,2)
)
clustered by (user_id) sorted by(user_id) into 36 buckets
row format delimited fields terminated by '\t';


--用户表
hive (default)> 
drop table if exists dim_user_zip_bucketed;
create table dim_user_zip_bucketed(
id string,
login_name string,
nick_name string,
name string,
phone_num string,
email string,
user_level string,
birthday string,
gender string,
create_time string,
operate_time string,
start_date string,
end_date string,
dt string
)
clustered by (id) sorted by(id) into 6 buckets
row format delimited fields terminated by '\t';

 然后向两个分桶表导入数据。

--订单明细分桶表
hive (default)> 
insert overwrite table dwd_trade_order_detail_inc_bucketed
select
id ,
order_id ,
user_id ,
sku_id ,
province_id ,
activity_id ,
activity_rule_id ,
coupon_id ,
date_id ,
create_time ,
source_id ,
source_type_code ,
source_type_name ,
sku_num ,
split_original_amount ,
split_activity_amount ,
split_coupon_amount,
split_total_amount
from  dwd_trade_order_detail_inc
where dt='2020-06-16';



--用户分桶表
hive (default)> 
insert overwrite table dim_user_zip_bucketed
select
id,
login_name,
nick_name,
name,
phone_num,
email,
user_level,
birthday,
gender,
create_time,
operate_time,
start_date,
end_date,
dt
from dim_user_zip
where dt='9999-12-31';

然后设置以下参数:

--启动Sort Merge Bucket Map Join优化
set hive.optimize.bucketmapjoin.sortedmerge=true;
--使用自动转换SMB Join
set hive.auto.convert.sortmerge.join=true;

最后在重写SQL语句,如下:

hive (default)> 
select
    *
from dwd_trade_order_detail_inc_bucketed od
join dim_user_zip_bucketed duser
on od.user_id = duser.id;

优化后的执行计如图所示:

<think>嗯,用户问的是如何实现Hive on Spark。我之前整理过大数据开发面试题,里面提到了HiveSpark的Shuffle机制对比,可能用户现在需要更具体的步骤来配置Hive使用Spark作为执行引擎。 首先,我需要回忆一下Hive on Spark的基本原理。Hive本身默认使用MapReduce作为执行引擎,但MapReduce在迭代计算和性能上不如Spark。所以Hive社区后来支持了Spark作为执行引擎,这样Hive的查询可以利用Spark的内存计算来加速执行。 接下来,用户可能需要详细的步骤,包括环境准备、配置修改、验证等。需要确认HiveSpark的版本兼容性,比如Hive 2.x和Spark 2.x是否兼容,或者Hive 3.x与Spark 3.x的组合。不同版本之间的配置可能有差异,所以版本兼容性很重要。 然后,安装和配置步骤。用户可能需要知道如何下载对应的HiveSpark,如何解压安装,设置环境变量。接着是Hive的配置文件修改,比如hive-site.xml中添加Spark相关的配置项,如hive.execution.engine设置为spark,以及Spark的主节点地址、应用程序名称等。 还需要将Spark的依赖包放到Hive的lib目录下,或者通过软链接的方式引用。可能还需要配置Spark的参数,比如executor的内存、核心数,以及Hive的参数如hive.spark.dynamicAllocation.enabled来启用动态资源分配。 验证部分,用户可能需要运行简单的Hive查询,比如select count(*) from table,来检查是否成功切换到Spark引擎。同时,查看Spark的Web UI来确认任务是否正确执行。 另外,需要注意的常见问题,比如版本不兼容导致的错误,依赖包缺失,或者配置错误。比如,HiveSpark的版本必须匹配,否则可能会出现类冲突或者无法启动的情况。此外,日志文件的位置和如何查看日志来排查问题也是关键。 用户可能的深层需求是希望通过Hive on Spark来提升查询性能,特别是在处理复杂查询或大数据集时。他们可能已经遇到了Hive on MapReduce的性能瓶颈,想要迁移到Spark来获得更好的性能。因此,在回答中需要强性能的相关参数,比如executor的数量、内存分配、Shuffle配置等。 最后,可能需要给出一些建议和最佳实践,比如如何根据集群资源Spark参数,如何处理数据倾斜,以及监控任务执行情况的方法。这样用户不仅能够成功配置Hive on Spark,还能优化其性能,满足实际业务需求。</think>实现 Hive on Spark 的核心目标是让 Hive 查询通过 Spark 引擎执行,从而利用 Spark 的内存计算势提升性能。以下是完整步骤及注意事项: --- ### **1. 环境准备** #### **版本兼容性要求** - **Hive 版本 ≥ 2.0**(Hive 2.x 或 3.x) - **Spark 版本 ≥ 2.0**(推荐 Spark 2.4.x 或 3.0.x) - **Hadoop 版本 ≥ 2.7**(HiveSpark 均依赖 Hadoop) - **兼容性验证**: - Hive 3.x 通常兼容 Spark 3.x - Hive 2.x 兼容 Spark 2.4.x - 参考官方文档:[Hive on Spark 官方指南](https://cwiki.apache.org/confluence/display/Hive/Hive+on+Spark) #### **依赖组件** - **Hive 安装**:确保 Hive 已配置并能正常运行(如 HDFS 和 Metastore) - **Spark 安装**:部署 Spark 集群(Standalone、YARN 或 Kubernetes 模式) - **JDK 1.8+** - **Hadoop 集群**(HDFS 和 YARN) --- ### **2. 配置 Hive 使用 Spark 引擎** #### **步骤 1:下载并安装 HiveSpark** ```bash # Hive 安装示例(以 Hive 3.1.3 为例) wget https://downloads.apache.org/hive/hive-3.1.3/apache-hive-3.1.3-bin.tar.gz tar -zxvf apache-hive-3.1.3-bin.tar.gz -C /usr/local/ mv /usr/local/apache-hive-3.1.3-bin /usr/local/hive # Spark 安装示例(以 Spark 3.1.2 为例) wget https://downloads.apache.org/spark/spark-3.1.2/spark-3.1.2-bin-hadoop3.2.tgz tar -zxvf spark-3.1.2-bin-hadoop3.2.tgz -C /usr/local/ mv /usr/local/spark-3.1.2-bin-hadoop3.2 /usr/local/spark ``` #### **步骤 2:配置 Hive 使用 Spark** 修改 `hive-site.xml` 文件,添加以下配置: ```xml <configuration> <!-- 设置执行引擎为 Spark --> <property> <name>hive.execution.engine</name> <value>spark</value> </property> <!-- Spark 主节点地址(Standalone 模式) --> <property> <name>spark.master</name> <value>spark://spark-master:7077</value> </property> <!-- Spark 应用名称 --> <property> <name>spark.app.name</name> <value>Hive on Spark</value> </property> <!-- Spark 依赖的 Hive JAR 包路径 --> <property> <name>spark.sql.hive.hiveserde</name> <value>true</value> </property> <!-- Spark 动态资源分配(可选) --> <property> <name>hive.spark.dynamicAllocation.enabled</name> <value>true</value> </property> </configuration> ``` #### **步骤 3:复制 Spark 依赖到 Hive** 将 Spark 的 JAR 包软链接到 Hive 的 `lib` 目录: ```bash cd /usr/local/hive/lib for jar in /usr/local/spark/jars/*.jar; do ln -s $jar $(basename $jar); done ``` --- ### **3. 验证 Hive on Spark** #### **启动 Hive CLI 并执行查询** ```bash # 启动 Hive CLI hive # 在 Hive 中执行查询 hive> SELECT count(*) FROM your_table; ``` - **检查日志**:查看 Hive 日志(默认在 `/tmp/$USER/hive.log`)确认是否使用 Spark 引擎。 - **查看 Spark UI**:访问 Spark Web UI(默认 `http://spark-master:4040`)确认任务是否提交成功。 --- ### **4. 常见问题与解决方案** #### **问题 1:类冲突或版本不兼容** - **现象**:启动 Hive 时抛出 `ClassNotFoundException` 或 `NoSuchMethodError` - **解决**: - 确保 HiveSpark 版本兼容(参考官方文档) - 使用 `spark-submit` 的 `--conf spark.driver.extraClassPath` 指定 Hive 依赖路径 #### **问题 2:Spark 无法访问 Hive Metastore** - **现象**:Hive 表元数据无法读取 - **解决**: - 确保 `hive-site.xml` 中配置了正确的 Metastore 地址: ```xml <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://metastore-host:3306/hive_metastore</value> </property> ``` #### **问题 3:资源不足导致任务失败** - **现象**:Spark 报错 `ExecutorLostFailure` 或 `OutOfMemoryError` - **解决**: - 增加 Executor 内存: ```bash SET spark.executor.memory=4g; ``` - 整动态资源分配: ```bash SET hive.spark.dynamicAllocation.maxExecutors=10; ``` --- ### **5. 性能建议** 1. **Shuffle 分区数**: ```sql SET spark.sql.shuffle.partitions=200; -- 根据数据量整 ``` 2. **内存分配**: ```sql SET spark.executor.memory=8g; SET spark.driver.memory=4g; ``` 3. **压缩与序列化**: ```sql SET spark.sql.compression.codec=snappy; -- 压缩中间数据 SET spark.serializer=org.apache.spark.serializer.KryoSerializer; -- 提升序列化效率 ``` --- ### **6. 完整流程图** ``` Hive CLI/Beeline ↓ Hive Driver (解析SQL)Hive Compiler (生成执行计划)Spark Execution Engine (提交 Spark 任务)Spark Cluster (执行 DAG 任务) ↓ HDFS/YARN (存储与资源) ``` --- ### **总结** Hive on Spark 的核心势在于通过 Spark 引擎加速 Hive 查询,尤其适用于复杂查询和迭代计算。关键步骤包括版本匹配、配置修改、依赖管理及性能。实际生产环境中需结合集群资源和业务需求整参数,例如动态资源分配、Shuffle 分区数等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值