共计 2775 个字符,预计需要花费 7 分钟才能阅读完成。
Hive on Spark 是指应用 Spark 代替传统 MapReduce 作为 Hive 的执行引擎,在 HIVE-7292 提出。Hive on Spark 的效率比 on MR 要高不少,然而也须要正当调整参数能力最大化性能,本文简略列举一些调优项。为了符合实际状况,Spark 也采纳 on YARN 部署形式来阐明。
Driver 参数
spark.driver.cores
该参数示意每个 Executor 可利用的 CPU 外围数。其值不宜设定过大,因为 Hive 的底层以 HDFS 存储,而 HDFS 有时对高并发写入解决不太好,容易造成 race condition。依据咱们的实际,设定在 3~6 之间比拟正当。
假如咱们应用的服务器单节点有 32 个 CPU 外围可供使用。思考到零碎根底服务和 HDFS 等组件的余量,个别会将 YARN NodeManager 的yarn.nodemanager.resource.cpu-vcores参数设为 28,也就是 YARN 可能利用其中的 28 核,此时将spark.executor.cores设为 4 最合适,最多能够正好调配给 7 个 Executor 而不造成节约。又假如yarn.nodemanager.resource.cpu-vcores为 26,那么将spark.executor.cores设为 5 最合适,只会残余 1 个核。
因为一个 Executor 须要一个 YARN Container 来运行,所以还需保障spark.executor.cores的值不能大于单个 Container 能申请到的最大外围数,即yarn.scheduler.maximum-allocation-vcores的值。
spark.executor.memory/spark.yarn.executor.memoryOverhead
这两个参数别离示意每个 Executor 可利用的堆内内存量和堆外内存量。堆内内存越大,Executor 就能缓存更多的数据,在做诸如 map join 之类的操作时就会更快,但同时也会使得 GC 变得更麻烦。Hive 官网提供了一个计算 Executor 总内存量的教训公式,如下:
yarn.nodemanager.resource.memory-mb * (spark.executor.cores / yarn.nodemanager.resource.cpu-vcores)
其实就是按外围数的比例调配。在计算出来的总内存量中,80%~85% 划分给堆内内存,残余的划分给堆外内存。
假如集群中单节点有 128G 物理内存,yarn.nodemanager.resource.memory-mb(即单个 NodeManager 可能利用的主机内存量)设为 120G,那么总内存量就是:120 1024 (4 / 28) ≈ 17554MB。再按 8:2 比例划分的话,最终spark.executor.memory设为约 13166MB,spark.yarn.executor.memoryOverhead设为约 4389MB。大数据培训
与上一节同理,这两个内存参数相加的总量也不能超过单个 Container 最多能申请到的内存量,即yarn.scheduler.maximum-allocation-mb。
spark.executor.instances
该参数示意执行查问时一共启动多少个 Executor 实例,这取决于每个节点的资源分配状况以及集群的节点数。若咱们一共有 10 台 32C/128G 的节点,并依照上述配置(即每个节点承载 7 个 Executor),那么实践上讲咱们能够将spark.executor.instances设为 70,以使集群资源最大化利用。然而实际上个别都会适当设小一些(举荐是理论值的一半左右),因为 Driver 也要占用资源,并且一个 YARN 集群往往还要承载除了 Hive on Spark 之外的其余业务。
spark.dynamicAllocation.enabled
下面所说的固定调配 Executor 数量的形式可能不太灵便,尤其是在 Hive 集群面向很多用户提供剖析服务的状况下。所以更举荐将spark.dynamicAllocation.enabled参数设为 true,以启用 Executor 动态分配。
Driver 参数
spark.driver.cores
该参数示意每个 Driver 可利用的 CPU 外围数。绝大多数状况下设为 1 都够用。
spark.driver.memory/spark.driver.memoryOverhead
这两个参数别离示意每个 Driver 可利用的堆内内存量和堆外内存量。依据资源充裕水平和作业的大小,个别是将总量管制在 512MB~4GB 之间,并且沿用 Executor 内存的“二八调配形式”。例如,spark.driver.memory能够设为约 819MB,spark.driver.memoryOverhead设为约 205MB,加起来正好 1G。
Hive 参数
绝大部分 Hive 参数的含意和调优办法都与 on MR 时雷同,但仍有两个须要留神。
hive.auto.convert.join.noconditionaltask.size
咱们晓得,当 Hive 中做 join 操作的表有一方是小表时,如果hive.auto.convert.join和hive.auto.convert.join.noconditionaltask开关都为 true(默认即如此),就会主动转换成比拟高效的 map-side join。而hive.auto.convert.join.noconditionaltask.size这个参数就是 map join 转化的阈值,在 Hive on MR 下默认为 10MB。
然而 Hive on MR 下统计表的大小时,应用的是数据在磁盘上存储的近似大小,而 Hive on Spark 下则改用在内存中存储的近似大小。因为 HDFS 上的数据很有可能被压缩或序列化,使得大小减小,所以由 MR 迁徙到 Spark 时要适当调高这个参数,以保障 map join 失常转换。个别会设为 100~200MB 左右,如果内存富余,能够更大点。
hive.merge.sparkfiles
小文件是 HDFS 的天敌,所以 Hive 原生提供了合并小文件的选项,在 on MR 时是hive.merge.mapredfiles,然而 on Spark 时会改成hive.merge.sparkfiles,留神要把这个参数设为 true。至于小文件合并的阈值参数,即hive.merge.smallfiles.avgsize与hive.merge.size.per.task都没有变动。