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

文章介绍了HiveonSpark的大数据技术调优,重点关注Executor的CPU核数、内存配置以及Executor个数的静态和动态分配策略。此外,还讨论了Driver的内存配置,并提供了实际操作步骤,包括修改spark-defaults.conf文件和配置SparkShuffle服务。

摘要生成于 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)


3.1 Executor配置说明

3.1.1 Executor CPU核数配置

      单个Executor的CPU核数,由spark.executor.cores参数决定,建议配置为4-6,具体配置为多少,视具体情况而定,原则是尽量充分利用资源。

      此处单个节点共有16个核可供Executor使用,则spark.executor.core配置为4最合适。原因是,若配置为5,则单个节点只能启动3个Executor,会剩余1个核未使用;若配置为6,则只能启动2个Executor,会剩余4个核未使用。

3.1.2 Executor内存配置

Spark在Yarn模式下的Executor内存模型如下图所示:

         Executor相关的参数有:spark.executor.memory和spark.executor.memoryOverhead。spark.executor.memory用于指定Executor进程的堆内存大小,这部分内存用于任务的计算和存储;spark.executor.memoryOverhead用于指定Executor进程的堆外内存,这部分内存用于JVM的额外开销,操作系统开销等。两者的和才算一个Executor进程所需的总内存大小。默认情况下spark.executor.memoryOverhead的值等于spark.executor.memory*0.1。

        以上两个参数的推荐配置思路是,先按照单个NodeManager的核数和单个Executor的核数,计算出每个NodeManager最多能运行多少个Executor。在将NodeManager的总内存平均分配给每个Executor,最后再将单个Executor的内存按照大约10:1的比例分配到spark.executor.memory和spark.executor.memoryOverhead。

根据上述思路,可得到如下关系:

(spark.executor.memory+spark.executor.memoryOverhead)= yarn.nodemanager.resource.memory-mb * (spark.executor.cores/yarn.nodemanager.resource.cpu-vcores)

经计算,此处应做如下配置:

spark.executor.memory    14G
spark.executor.memoryOverhead    2G

3.1.3 Executor个数配置

此处的Executor个数是指分配给一个Spark应用的Executor个数,Executor个数对于Spark应用的执行速度有很大的影响,所以Executor个数的确定十分重要。

一个Spark应用的Executor个数的指定方式有两种,静态分配动态分配

1)静态分配

可通过spark.executor.instances指定一个Spark应用启动的Executor个数。这种方式需要自行估计每个Spark应用所需的资源,并为每个应用单独配置Executor个数。

2)动态分配

动态分配可根据一个Spark应用的工作负载,动态的调整其所占用的资源(Executor个数)。这意味着一个Spark应用程序可以在运行的过程中,需要时,申请更多的资源(启动更多的Executor),不用时,便将其释放。

在生产集群中,推荐使用动态分配。动态分配相关参数如下:

#启动动态分配
spark.dynamicAllocation.enabled    true
#启用Spark shuffle服务
spark.shuffle.service.enabled    true
#Executor个数初始值
spark.dynamicAllocation.initialExecutors    1
#Executor个数最小值
spark.dynamicAllocation.minExecutors    1
#Executor个数最大值
spark.dynamicAllocation.maxExecutors    12
#Executor空闲时长,若某Executor空闲时间超过此值,则会被关闭
spark.dynamicAllocation.executorIdleTimeout    60s
#积压任务等待时长,若有Task等待时间超过此值,则申请启动新的Executor
spark.dynamicAllocation.schedulerBacklogTimeout    1s
#spark shuffle老版本协议
spark.shuffle.useOldFetchProtocol true

说明:Spark shuffle服务的作用是管理Executor中的各Task的输出文件,主要是shuffle过程map端的输出文件。由于启用资源动态分配后,Spark会在一个应用未结束前,将已经完成任务,处于空闲状态的Executor关闭。Executor关闭后,其输出的文件,也就无法供其他Executor使用了。需要启用Spark shuffle服务,来管理各Executor输出的文件,这样就能关闭空闲的Executor,而不影响后续的计算任务了。

3.2 Driver配置说明

Driver主要配置内存即可,相关的参数有spark.driver.memory和spark.driver.memoryOverhead。

spark.driver.memory用于指定Driver进程的堆内存大小,spark.driver.memoryOverhead用于指定Driver进程的堆外内存大小。默认情况下,两者的关系如下:

spark.driver.memoryOverhead=spark.driver.memory*0.1。两者的和才算一个Driver进程所需的总内存大小。

一般情况下,按照如下经验进行调整即可:假定yarn.nodemanager.resource.memory-mb设置为X。

若X>50G,则Driver可设置为12G,

若12G<X<50G,则Driver可设置为4G。

若1G<X<12G,则Driver可设置为1G。 

此处yarn.nodemanager.resource.memory-mb为64G,则Driver的总内存可分配12G,所以上述两个参数可配置为。

spark.driver.memory    10G
spark.yarn.driver.memoryOverhead    2G

3.3 Spark配置实操

1)修改spark-defaults.conf文件

(1)修改$HIVE_HOME/conf/spark-defaults.conf

spark.master                               yarn
spark.eventLog.enabled                   true
spark.eventLog.dir    hdfs://myNameService1/spark-history
spark.executor.cores    4
spark.executor.memory    14g
spark.executor.memoryOverhead    2g
spark.driver.memory    10g
spark.driver.memoryOverhead    2g
spark.dynamicAllocation.enabled  true
spark.shuffle.service.enabled  true
spark.dynamicAllocation.executorIdleTimeout  60s
spark.dynamicAllocation.initialExecutors    1
spark.dynamicAllocation.minExecutors  1
spark.dynamicAllocation.maxExecutors  12
spark.dynamicAllocation.schedulerBacklogTimeout 1s
spark.shuffle.useOldFetchProtocol    true

2)配置Spark shuffle服务

Spark Shuffle服务的配置因Cluster Manager(standalone、Mesos、Yarn)的不同而不同。此处以Yarn作为Cluster Manager。

(1)拷贝$SPARK_HOME/yarn/spark-3.0.0-yarn-shuffle.jar到

$HADOOP_HOME/share/hadoop/yarn/lib

(2)分发$HADOOP_HOME/share/hadoop/yarn/lib/yarn/spark-3.0.0-yarn-shuffle.jar

(3)修改$HADOOP_HOME/etc/hadoop/yarn-site.xml文件

<property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle,spark_shuffle</value>
</property>

<property>
    <name>yarn.nodemanager.aux-services.spark_shuffle.class</name>
    <value>org.apache.spark.network.yarn.YarnShuffleService</value>
</property>

(4)分发$HADOOP_HOME/etc/hadoop/yarn-site.xml文件

(5)重启Yarn

<think>嗯,用户这次的问题是关于Hive on Spark的并发性能方法。从用户引用的资料来看,ta已经对基础有一定了解,现在需要更深入的并发化方案。用户可能是个大数据工程师,正在处理生产环境中高并发查询的性能瓶颈。 我注意到用户引用的资料很有针对性:引用[1]提到参数的重要性,引用[2]强join化,引用[3]重点讲内存管理,引用[4]则涉及shuffle细节。这些正好构成并发的四个维度:资源分配、执行器配置、查询化和shuffle化。 用户上次询问的是基础配置,这次转向并发场景,说明ta的集群可能面临业务增长压力。需要特别注意:高并发时资源争用是核心矛盾,这和单查询有本质区别。比如spark.executor.cores不是越大越好,要避免YARN容器碎片化。 在回复结构上,我决定按层次展开:先集群资源层(YARN队列/动态分配),再执行器配置(并行度/内存),最后查询层(分区/Join)。每个建议都要带具体参数和计算逻辑,比如执行器核数设置公式$v = \min(4, \lfloor \frac{yarn\_node\_cores}{executor\_count} \rfloor)$就很有实操性。 特别要强反模式:比如spark.dynamicAllocation.maxExecutors设得过高可能压垮集群,或者小文件过多导致元数据瓶颈。用户引用[2]提到的hive.auto.convert.join.noconditionaltask.size也要解释清楚Spark和MR的区别。 最后补充监控方法,因为需要数据支撑。打算用表格对比化前后效果,这样用户能直观看到价值。相关问题设计成递进的,从参数验证到极端场景覆盖。</think>以下是针对 Hive on Spark 并发性能的完整方案,结合资源配置、参数化及执行策略三个维度,重点提升多任务并行处理能力: --- ### 一、资源层化(YARN 队列管理) 1. **动态资源分配** 启用 Spark 动态资源伸缩,避免资源闲置: ```xml <!-- hive-site.xml --> <property> <name>spark.dynamicAllocation.enabled</name> <value>true</value> </property> <property> <name>spark.dynamicAllocation.maxExecutors</name> <value>50</value> <!-- 按集群规模整 --> </property> <property> <name>spark.dynamicAllocation.minExecutors</name> <value>5</value> </property> ``` 动态分配根据负载自动增减 Executor,提高集群利用率[^3]。 2. **队列资源隔离** 在 YARN 中划分独立队列,避免并发任务资源争抢: ```bash # 提交任务时指定队列 SET spark.yarn.queue=prod_high_priority; ``` --- ### 二、Executor 并发配置 1. **Executor 粒度整** 根据数据量和并发数平衡 Executor 数量与核数: ```properties # spark-defaults.conf spark.executor.instances = 20 # 总Executor数 spark.executor.cores = 4 # 每个Executor核数(建议4-6核) spark.executor.memory = 8g # Executor堆内存 spark.executor.memoryOverhead=2g # 堆外内存(避免OOM) ``` **计算逻辑**: 设集群可用核数 $C$,目标并发查询数 $Q$,则: $$ \text{spark.executor.instances} = \min \left( \frac{C}{4}, Q \times 2 \right) $$ 2. **并行度控制** 整分区数匹配并发需求: ```sql -- 手动设置Reduce阶段并行度 SET spark.sql.shuffle.partitions=200; -- 根据数据量动态整(推荐) SET hive.exec.reducers.bytes.per.reducer=256000000; -- 每个Reducer处理256MB ``` **原则**:`shuffle.partitions` ≥ `Executor数 × Executor核数 × 2` --- ### 三、查询层化 1. **小文件合并** 减少Map Task数量,降低度开销: ```sql SET hive.merge.sparkfiles=true; SET hive.merge.smallfiles.avgsize=128000000; -- 128MB SET hive.merge.size.per.task=256000000; -- 256MB ``` 2. **MapJoin 化** 提升小表关联效率,避免Shuffle: ```sql SET hive.auto.convert.join=true; SET hive.auto.convert.join.noconditionaltask.size=30000000; -- Spark下该值需比MR配置更小[^2] ``` 3. **倾斜处理** 解决数据倾斜导致的并发瓶颈: ```sql -- 启用倾斜化 SET spark.sql.adaptive.skewJoin.enabled=true; SET spark.sql.adaptive.skewJoin.skewedPartitionFactor=5; -- 倾斜判定阈值 ``` --- ### 四、Shuffle 稳定性 1. **重试机制增强** 避免网络波动导致任务失败: ```properties spark.shuffle.io.maxRetries=5 # 重试次数提升[^4] spark.shuffle.io.retryWait=30s # 重试间隔延长 ``` 2. **Shuffle 传输化** ```properties spark.reducer.maxSizeInFlight=96m # 提升Reduce拉取数据量 spark.shuffle.file.buffer=128k # 增大Shuffle写缓存 ``` --- ### 五、监控与验证 1. **监控指标** - YARN ResourceManager:观察队列资源使用率 - Spark History Server:分析 `Shuffle Write/Read` 时间 - Hive 日志:关注 `Total MapReduce CPU Time Spent` 2. **压测方法** ```sql -- 模拟并发查询 SET hive.exec.parallel=true; SET hive.exec.parallel.thread.number=16; -- 并发线程数 ``` --- ### 效果对比(示例) | 配置项 | 前 | 后 | 效果 | |----------------|--------------|--------------|--------------| | Executor 数量 | 10 | 20 | 并发提升 2x | | Shuffle 分区 | 100 | 200 | 负载均衡性↑ | | 查询延迟 | 120s | 45s | 响应速度↑ 62%| > **注**:实际效果因数据规模及集群硬件差异而不同,建议逐步整参数并监控稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值