Hive on Tez/Spark在银行大数据场景的性能调优需围绕执行引擎切换、资源分配与参数优化展开。
Tez调优核心:
1)调整
tez.grouping.max-size和Reducer数量平衡并行度;2)合理配置容器内存与JVM堆占比(建议0.7-0.8);
3)启用矢量化查询、CBO优化及MapJoin加速。
Spark调优重点:
1)按YARN资源动态分配Executor内存与核心数;
2)优化
spark.sql.shuffle.partitions减少小文件;3)调整MapJoin阈值并开启动态分区裁剪。
通用建议:区分ETL与即席查询场景,优先监控资源使用与GC情况,通过测试验证后上线。
Hive on Tez
在银行大数据场景中,配置 Hive on Tez 并做好性能调优,是提升海量数据查询效率的关键一步。核心流程包括基础配置 和参数调优两大块。
核心配置:让Hive跑在Tez上
最关键的步骤是将 Hive 的执行引擎设置为 Tez。
-
设置执行引擎 :在 Hive 的配置文件
hive-site.xml中,将hive.execution.engine属性的值修改为tez。如果使用 Cloudera 或阿里云 EMR 这类管理平台,可以在 Hive 服务的配置界面直接修改这个参数,并重启服务生效。 -
Tez环境准备(手动部署时需要) :如果非平台自动化部署,需要将 Tez 的安装包上传到 HDFS 指定位置,并在
hive-env.sh中设置TEZ_CONF_DIR和TEZ_JARS等环境变量,让 Hive 能够找到 Tez 的库文件。
关键性能调优参数
调优可以从任务并行度、内存、IO 和并发控制这几个维度入手。
1. 控制Mapper和Reducer数量
-
tez.grouping.max-size(默认: 1GB):控制 Mapper 处理的最大数据量。增大此值,每个 Mapper 处理的数据更多,Mapper 数量减少,适合减少任务调度开销;减小此值,Mapper 数量增加,并行度提高,适合处理大量小文件或需要更高并行度的场景。 -
tez.grouping.min-size(默认: 16MB):控制 Mapper 处理的最小数据量。 -
hive.exec.reducers.bytes.per.reducer(默认: 256MB):每个 Reducer 处理的数据量大小。减小此值会增加 Reducer 数量,提高并行度;增大此值则减少 Reducer 数量。银行场景建议:需根据集群资源和查询数据量谨慎调整,避免Reducer数量过多导致小任务过多,或过少导致单个任务处理压力过大。
2. 内存与运行时参数调优
内存参数调优不当,可能会导致频繁的 Full GC,严重影响任务执行效率,类似社区反馈的 15分钟 处理 165MB 数据的极端情况。
-
hive.tez.container.size:指定 Tez 任务申请的 YARN Container 内存大小(如 8192 MB)。 -
tez.container.max.java.heap.fraction:控制 Container 内存中分配给 JVM 堆内存的比例。建议设置为 0.7-0.8。 -
mapreduce.map.java.opts:设置 Map 任务的 JVM 堆内存大小(如-Xmx4096m),通常设为hive.tez.container.size的 70%-80%。
3. 通用性能优化开关
这些是建议优先开启的"常规武器":
-
hive.vectorized.execution.enabled:启用矢量化查询,以 1024 行为一批进行处理,能大幅减少 CPU 开销,对 ORC 格式效果尤其明显。 -
hive.cbo.enable:启用基于成本的优化器,让 Hive 智能选择最优执行计划。 -
hive.exec.parallel:开启查询阶段并行执行,互不依赖的阶段可同时运行,缩短整体耗时。 -
hive.auto.convert.join:自动将合适的 Join 转换为 MapJoin,在 Map 端完成小表加载,加速查询。
4. 并发与资源控制
银行系统常有高并发查询需求,这部分配置至关重要。
-
hive.server2.tez.sessions.per.default.queue:控制 HiveServer2 为每个 YARN 队列预创建的 Tez 会话(Application Master, AM)数量。适当增加此值,可以减少查询启动时的 AM 创建开销,提升并发响应速度,但也会占用更多集群资源。 -
hive.server2.tez.initialize.default.sessions:设置为true时,HiveServer2 启动时会预先创建好 Tez 会话,避免首次查询时的等待时间。 -
tez.am.container.reuse.enabled:启用 Tez AM 的容器复用,避免每个任务都重新申请容器,减少与 YARN 交互的开销。
银行场景调优总结与建议
针对银行数据量大、稳定性要求高的特点,可以参考以下思路:
-
场景区分 :ETL批处理任务 ,可以适当增大
tez.grouping.max-size和hive.exec.reducers.bytes.per.reducer,减少任务数,降低调度开销;即席查询/交互式分析 ,建议适当减小上述参数,提高并行度,并开启hive.exec.parallel和矢量化执行来加速响应。 -
内存先行 :遇到任务慢、GC频繁的问题,第一时间检查内存配置。确保
hive.tez.container.size、堆内存比例和mapreduce.map.java.opts设置合理。 -
监控是关键:充分利用 YARN ResourceManager UI 和 Tez UI 查看每个任务的资源使用和执行细节,定位具体瓶颈。
在进行任何参数调整前,建议先在测试环境进行充分验证,确保调优效果符合预期,再谨慎推广到生产环境。
即席查询(Ad Hoc Query)是指用户根据自身即时需求,灵活、动态地自定义查询条件,以获取特定数据结果的操作方式。
它的核心特点是:
临时性:查询不是预先规划好的,而是由突发的分析需求驱动。
灵活性:查询条件可随时调整,没有固定格式。
交互性:通常要求系统能快速响应,支持"所见即所得"的数据探索。
在银行等数据平台中,它通常由业务分析师或数据科学家发起,用于探索性分析或验证临时想法,对底层引擎(如Hive on Tez/Spark)的查询响应速度 和并发能力要求较高。
Hive on Spark
与 Hive on Tez 类似,Hive on Spark 的配置同样围绕执行引擎切换,但其调优重点更多集中在 Spark 特有的资源模型(Executor 和 Driver)与内存管理上。核心配置和关键调优参数整理如下。
核心配置:让Hive跑在Spark上
配置的关键是确保 Hive 能找到并使用正确版本的 Spark,并最终将执行引擎切换过来。
-
设置执行引擎 :在
hive-site.xml中,将hive.execution.engine的值设置为spark。对于 Hive 1.1.0 及更早版本,可能还需要额外将hive.enable.spark.execution.engine设为true。 -
Spark环境准备:
-
版本兼容性:Hive 与 Spark 有严格的版本对应关系。例如,Hive 3.0.x 版本对应 Spark 2.3.0,而 Hive 2.3.x 对应 Spark 2.0.0。务必查阅官方文档确认版本匹配。
-
部署Spark:Hive on Spark 默认运行在 YARN 模式,即 Spark 作为 YARN 上的一个应用运行。
-
添加Spark依赖:
-
对于 Hive 2.2.0 之前的版本 ,需要将 Spark 的
spark-assembly-*.jar文件链接或复制到 Hive 的 lib 目录下。 -
对于 Hive 2.2.0 及之后版本 ,需要将
$SPARK_HOME/jars目录下的所有 jar 包上传到 HDFS 路径,并在hive-site.xml中通过spark.yarn.jars属性指向该路径,这样 YARN 就能缓存这些依赖,避免每次任务启动时重复分发。
-
-
配置Hive :在
hive-site.xml中设置spark.home指向 Spark 安装目录,并根据需要设置spark.master(如yarn-client或yarn-cluster)等参数。
-
关键性能调优参数
Hive on Spark 的性能调优主要围绕 Spark 的资源模型展开,核心目标是合理分配内存和CPU,同时避免因参数不当导致的GC(垃圾回收)性能问题或资源浪费。
1. Executor 与 Driver 资源配置(重中之重)
这部分参数的设置直接影响任务运行的并行度和内存安全,是调优的核心。调优思路可以参考此表:
| 参数 | 说明与调优建议 |
|---|---|
spark.executor.cores |
每个 Executor 使用的 CPU 核心数。推荐设置在 5-7 之间 。具体数值需要结合 YARN 集群的 yarn.nodemanager.resource.cpu-vcores(单节点可用总核心数)来设定,原则是让所有 Executor 正好用完或尽可能少浪费核心。例如,若总核心数为 28,设为 4 最佳(正好 7 个 Executor);若为 26,设为 5 更优(5个Executor,余1核)。 |
spark.executor.memory |
每个 Executor 的堆内内存。并非越大越好,过大会导致 JVM GC 压力剧增。建议按以下公式计算 : yarn.nodemanager.resource.memory-mb * (spark.executor.cores / yarn.nodemanager.resource.cpu-vcores)。 计算出的总内存中,建议将 80%-85% 分配给 spark.executor.memory,剩余部分留给堆外内存 spark.yarn.executor.memoryOverhead。 |
spark.yarn.executor.memoryOverhead |
每个 Executor 的堆外内存,用于 VM 开销、内部字符串等。建议设置为 spark.executor.memory 的 15%-20%。 |
spark.executor.instances |
固定分配的 Executor 数量。如果集群资源完全被 Hive 独占,可按资源算满。但更推荐启用动态分配,由系统按需创建和回收,避免资源浪费。 |
spark.driver.memory |
Driver 进程的堆内内存。通常用于收集任务结果和调度。官方建议至少 4GB,可根据任务复杂度适当调整。 |
spark.dynamicAllocation.enabled |
启用动态资源分配 。在生产环境中强烈推荐设为 true,这样 Spark 可以根据任务负载动态增减 Executor,提升集群整体利用率和响应速度。 |
2. 其他重要调优参数
-
spark.sql.shuffle.partitions:Shuffle 操作(如group by,join)后的分区数。默认值通常较小(如200),对于海量数据处理,可适当调大以增加并行度。 -
hive.auto.convert.join.noconditionaltask.size:自动 MapJoin 的阈值。在 Spark 引擎下,该参数统计的是表在内存中的大小 (而非 HDFS 存储大小)。因此,从 MR 迁移到 Spark 时,需要将此值调大(如从默认的10MB调到100-200MB),以确保更多小表 Join 能转为高效的 MapJoin。 -
hive.merge.sparkfiles:强烈建议设为true。这会在 Spark 任务结束时合并输出的小文件,避免在 HDFS 上产生大量小文件,影响后续任务性能。 -
hive.spark.dynamic.partition.pruning:动态分区裁剪。设为true可以显著优化分区表 Join 的性能,通过跳过不必要的数据分区来减少扫描量。
总结与建议
和 Tez 的调优思路类似,对于 Hive on Spark 的调优也建议循序渐进:
-
资源先行 :首先需要吃透 Spark on YARN 的资源模型 。
spark.executor.cores和spark.executor.memory的计算方法是性能调优的基础。 -
区分场景 :对于耗时较长的 ETL 批处理任务,可适当调大
spark.sql.shuffle.partitions以提升并行度;对于要求快速响应的即席查询,则应重点优化内存和开启动态分区裁剪等特性。 -
关注小文件 :银行系统数据规模庞大,任务输出很容易产生大量小文件。务必开启
hive.merge.sparkfiles,这是保证 HDFS 和后续任务健康稳定运行的重要一环。 -
监控驱动调优 :充分利用 Spark UI 和 YARN ResourceManager UI,从 Detailed View 中观察每个 Stage 的 Shuffle Read/Write 数据量、GC 耗时等,这是定位瓶颈最直接的方法。