做电商网站需要注册什么公司名称,路桥网站建设,免费设计签名连笔字,乌兰察布seo文章目录 参数配置优化yarn-site.xml 配置文件优化mapred-site.xml 配置文件优化 分组聚合优化 —— Map-Side优化参数解析优化案例 服务器环境说明
机器名称内网IP内存CPU承载服务master192.168.10.1084NodeManager、DataNode、NameNode、JobHistoryServer、Hive、HiveServer… 文章目录 参数配置优化yarn-site.xml 配置文件优化mapred-site.xml 配置文件优化 分组聚合优化 —— Map-Side优化参数解析优化案例 服务器环境说明
机器名称内网IP内存CPU承载服务master192.168.10.1084NodeManager、DataNode、NameNode、JobHistoryServer、Hive、HiveServer2、MySQLslave1192.168.10.1184NodeManager、DataNode、ResourceManagerslave2192.168.10.1284NodeManager、DataNode、SecondaryNameNode
操作系统均为CentOS 7.5
组件版本
jdk 1.8mysql 5.7hadoop 3.1.3hive 3.1.2
参数配置优化
下面以我的集群配置为例来进行优化请按说明根据实际需求、节点情况进行灵活调整。
yarn-site.xml 配置文件优化
参数一
该参数指定了 NodeManager 可以分配给该节点上的 YARN 容器的最大内存量以 MB 为单位默认 8G。
propertynameyarn.nodemanager.resource.memory-mb/namevalue6144/value
/property我的每台服务器内存为 8 G这里给 NodeManager 分配 6 G 内存我们必须考虑给系统以及其它服务预留内存。
注意该参数不能超过单台服务器的总内存。
参数二
该参数指定了 NodeManager 在 YARN 集群中的每个节点上可以分配给容器的虚拟 CPU 核心数量默认值为 8 。
增加它可以提高容器的并行性和性能但也可能导致 CPU 资源过度分配。减小它可能会限制容器的性能但可以确保更多的容器在集群上同时运行。
propertynameyarn.nodemanager.resource.cpu-vcores/namevalue6/value
/property我的每台服务器物理 CPU 核数为 4 这里虚拟为 6 核提高并发度。
参数三
该参数定义了 YARN 调度器允许的单个容器的最大内存分配。
这有助于确保在集群中合理分配内存资源以防止某个应用程序或容器占用过多的内存导致性能问题或资源争用。
该参数配置一般为 yarn.nodemanager.resource.memory-mb 的四分之一结果最好能被 1024 整除。
propertynameyarn.scheduler.maximum-allocation-mb/namevalue2048/value
/property上面设置 yarn.nodemanager.resource.memory-mb 的配置是 6G6144 / 4 1536显然 1536 无法被 1024 整除所以这里直接设置为 2G向上取整。
参数四
该参数定义了 YARN 调度器允许的单个容器的最小内存分配默认为 1G。
propertynameyarn.scheduler.minimum-allocation-mb/namevalue512/value
/property这里直接调为 512MB 就行了如果内存很多可以往上调。
参数五
分配给单个容器的最小与最大虚拟核心数量。
!-- 容器最小虚拟核心数 --
propertynameyarn.scheduler.minimum-allocation-vcores/namevalue1/value
/property!-- 容器最大虚拟核心数 --
propertynameyarn.scheduler.maximum-allocation-vcores/namevalue2/value
/property根据单节点虚拟总核心数来进行配置最小设为 1 个最大设置为虚拟总核心的四分之一上面设置虚拟核心为 6 个这里向上取整所以最大设置为 2 个。
扩展配置1
设置 NodeManager 是否启用虚拟内存检查默认值true启用虚拟内存检查。
propertynameyarn.nodemanager.vmem-check-enabled/namevaluefalse/value
/property当设置为 true 时默认值NodeManager 将启用虚拟内存检查。这意味着 YARN 应用程序的每个容器将受到虚拟内存限制的限制一旦超过就会直接 kill 掉该容器。
当设置为 false 时NodeManager 将禁用虚拟内存检查。这意味着容器将不会受到虚拟内存的限制容器可以使用尽其所能的虚拟内存但这可能会增加系统的风险因为应用程序可以在不受约束的情况下使用虚拟内存可能导致系统不稳定。
根据当前集群环境用途自行决断吧学习阶段尽量设置为 false不然可能会导致很多任务都跑不了直接被 kill 掉。
扩展配置2
用于设置虚拟内存与物理内存之间的比率默认为 2.1 倍。
这个参数的目的是限制应用程序可以使用的虚拟内存量以避免某个应用程序无限制地占用虚拟内存资源导致其他任务和应用程序受影响。
propertynameyarn.nodemanager.vmem-pmem-ratio/namevalue2.1/value
/property扩展配置应用场景
未关闭虚拟内存检查之前由于虚拟内存不足在运行任务时你可能会看到如下所示的 Hive SQL 报错信息
Execution Errorreturn code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask
在历史服务器中查看详细报错信息如下 [2023-09-01 20:39:05.542]Container [pid64762,containerIDcontainer_1693562800213_0002_01_000006] is running 324684288B beyond the ‘VIRTUAL’ memory limit. Current usage: 237.6 MB of 1 GB physical memory used; 2.4 GB of 2.1 GB virtual memory used. Killing container.
提示虚拟内存超出限制当前容器正在使用 1G 物理内存中的 237.6MB 内存正在使用 2.1G 虚拟内存中的 2.4G 虚拟内存显然这超出了限制那么为什么会出现这种情况呢
这是因为我只给单个 Map 和 Reduce 任务分配了 1G 内存所以这 1G 内存按照默认物理内存与虚拟内存转化率(yarn.nodemanager.vmem-pmem-ratio)来算1024 * 2.1 2150.4所以对应着虚拟内存最大为 2.1G但是由于这个任务需要 2.4G 虚拟内存才可以运行所以导致容器被直接 kill 掉。
这里不建议直接将虚拟内存比率调大可以直接关闭虚拟内存检查来进行解决实战别关实战内存一般都很大关了反而会影响系统稳定性。
mapred-site.xml 配置文件优化
参数一
定义了单个 Map 与 Reduce 任务使用的最大内存分配量以 MB 为单位默认值都为 1024。
注意这两项参数都不可以超过单个容器的最大内存分配量(yarn.scheduler.maximum-allocation-mb)避免单个 Mapper 或者 Reduce 任务使用超过 YARN 调度器允许的最大内存导致任务运行异常。
propertynamemapreduce.map.memory.mb/namevalue1024/value
/propertypropertynamemapreduce.reduce.memory.mb/namevalue1024/value
/property前面我们设置单个容器的最大内存分配量为 2G所以这里设置为默认值 1G 更合理如果有条件设置为 2G 更好。
其实实际比例应该设置为 8:1【单个容器最大内存分配量】 : 【单个 Map 与 Reduce 任务使用的最大内存分配量】。但是说回来没有绝对的比例设置为 2G 也够用了根据实际情况来吧。
参数二
定义了单个 Map 与 Reduce 任务使用的最大虚拟核心数默认值都为 1。
注意这两项参数都不可以超过单个容器的最大虚拟核心数(yarn.scheduler.maximum-allocation-vcores)避免单个 Mapper 或者 Reduce 任务使用超过 YARN 调度器允许的最大虚拟核心数导致任务运行异常。
propertynamemapreduce.map.cpu.vcores/namevalue1/value
/propertypropertynamemapreduce.reduce.cpu.vcores/namevalue1/value
/property前面我们设置单个容器的最大虚拟核心数为 2所以这里设置为默认值 1 更合理根据实际条件向上调吧。
分组聚合优化 —— Map-Side
在 Hadoop MapReduce 中Map-Side 聚合是一种优化技术用于在 Map 任务阶段进行部分数据聚合以减少数据传输到 Reducer 任务的量。
Map-Side 聚合是一种有效的性能优化技术可以减少 MapReduce 作业中的数据传输和磁盘写入/读取从而提高作业的执行速度。
优化参数解析
以下是在 Hive 中设置 Map-Side 聚合相关的关键参数以及它们的详细解释
1. hive.map.aggr 默认值true 用于启用 Map-Side 聚合功能默认开启。Hive 会尝试在 Map 任务中执行一些简单的聚合操作例如 SUM、COUNT 等以减少 Map 输出的数据量。这可以降低作业的整体负载提高查询性能特别是对于一些聚合型的查询。
这可能会降低 Reducer 的负载但同时会增加 Map 任务的计算负担。如果查询需要更复杂的聚合操作或跨多个分组键的聚合可能无法完全受益于 Map-Side 聚合。
2. hive.map.aggr.hash.min.reduction 默认值0.5 这个参数的值是一个浮点数表示 Map-Side 聚合的最小减少量的阈值。阈值的范围是 0 到 1 之间0 表示不启用 Map-Side 聚合1 表示始终启用 Map-Side 聚合。
如果设置为 0.5表示只有当 Map 任务中的聚合操作可以减少至少 50% 的数据量时才会启用 Map-Side 聚合。
如果设置为 1表示无论聚合操作能否减少数据量都始终启用 Map-Side 聚合。
如果设置为 0表示禁用 Map-Side 聚合不管聚合操作是否有助于减少数据传输到 Reducer 的数量。
要注意的是过大的阈值可能导致 Map-Side 聚合不经常发生从而减少其性能优势。过小的阈值可能导致频繁的 Map-Side 聚合增加了 Map 任务的计算开销。因此合适的阈值应该基于具体查询和数据集的特点进行调整和测试。
3. hive.groupby.mapaggr.checkinterval 默认值100000 控制 Map-Side 聚合的检查条数用于验证任务是否满足聚合条件。
通俗来说就是在开启 Map-Side 聚合操作后当我们执行了聚合操作在 Map 阶段系统会自动取前 100000 条数据取进行判断此时会出现下面两种情况 如果其中的聚合键值大部分都一样那么就会执行 Map-Side 聚合操作。 如果大部分聚合键值都不一样那么就不会进行 Map-Side 聚合操作。
这个判断很容易会受到数据的分布影响假设前 100000 行数据前面都不一样只是因为数据量大但其实后面有很多聚合键值都一样的数据所以这就会造成判断不符合 Map-Side 聚合操作。
这种情况我们就需要根据实际情况进行判断了如果聚合后数据量确实少了一半我们可以强制开启 Map-Side 聚合操作。
4. hive.map.aggr.hash.force.flush.memory.threshold 默认值0.9 用于控制 Map-Side 聚合的内存阈值指定 Map 任务在进行 Map-Side 聚合时何时强制将内存中的数据写入磁盘以释放内存。
当 Map 任务的内存中数据占用达到或超过这个阈值时Map 任务将强制将内存中的数据写入磁盘以释放内存从而避免 OOM内存溢出错误。
优化案例
未开启 Map-Side 聚合执行
set hive.map.aggr false;执行如下 Hive SQL数据量大约 1000w 行
selectproduct_id,count(1)
from order_detail
group by product_id;执行计划
STAGE DEPENDENCIES:Stage-1 is a root stageStage-0 depends on stages: Stage-1STAGE PLANS:Stage: Stage-1Map ReduceMap Operator Tree:TableScanalias: order_detailStatistics: Num rows: 13066777 Data size: 11760099340 Basic stats: COMPLETE Column stats: NONESelect Operatorexpressions: product_id (type: string)outputColumnNames: product_idStatistics: Num rows: 13066777 Data size: 11760099340 Basic stats: COMPLETE Column stats: NONEReduce Output Operatorkey expressions: product_id (type: string)sort order: Map-reduce partition columns: product_id (type: string)Statistics: Num rows: 13066777 Data size: 11760099340 Basic stats: COMPLETE Column stats: NONEExecution mode: vectorizedReduce Operator Tree:Group By Operatoraggregations: count()keys: KEY._col0 (type: string)mode: completeoutputColumnNames: _col0, _col1Statistics: Num rows: 6533388 Data size: 5880049219 Basic stats: COMPLETE Column stats: NONEFile Output Operatorcompressed: falseStatistics: Num rows: 6533388 Data size: 5880049219 Basic stats: COMPLETE Column stats: NONEtable:input format: org.apache.hadoop.mapred.SequenceFileInputFormatoutput format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormatserde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
Stage: Stage-0Fetch Operatorlimit: -1Processor Tree:ListSink从执行计划中可以看出这段代码在 Map 阶段并没有进行聚合操作在进行 Reduce 操作前数据量并未发生任何变化。
执行结果运行 43 秒 开启 Map-Side 聚合执行
set hive.map.aggr true;
# 其余参数都保持默认执行同上 Hive SQL
selectproduct_id,count(1)
from order_detail
group by product_id;执行计划
STAGE DEPENDENCIES:Stage-1 is a root stageStage-0 depends on stages: Stage-1STAGE PLANS:Stage: Stage-1Map ReduceMap Operator Tree:TableScanalias: order_detailStatistics: Num rows: 13066777 Data size: 11760099340 Basic stats: COMPLETE Column stats: NONESelect Operatorexpressions: product_id (type: string)outputColumnNames: product_idStatistics: Num rows: 13066777 Data size: 11760099340 Basic stats: COMPLETE Column stats: NONEGroup By Operatoraggregations: count()keys: product_id (type: string)mode: hashoutputColumnNames: _col0, _col1Statistics: Num rows: 13066777 Data size: 11760099340 Basic stats: COMPLETE Column stats: NONEReduce Output Operatorkey expressions: _col0 (type: string)sort order: Map-reduce partition columns: _col0 (type: string)Statistics: Num rows: 13066777 Data size: 11760099340 Basic stats: COMPLETE Column stats: NONEvalue expressions: _col1 (type: bigint)Execution mode: vectorizedReduce Operator Tree:Group By Operatoraggregations: count(VALUE._col0)keys: KEY._col0 (type: string)mode: mergepartialoutputColumnNames: _col0, _col1Statistics: Num rows: 6533388 Data size: 5880049219 Basic stats: COMPLETE Column stats: NONEFile Output Operatorcompressed: falseStatistics: Num rows: 6533388 Data size: 5880049219 Basic stats: COMPLETE Column stats: NONEtable:input format: org.apache.hadoop.mapred.SequenceFileInputFormatoutput format: org.apache.hadoop.hive.ql.io.HiveSequenceFileOutputFormatserde: org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe
Stage: Stage-0Fetch Operatorlimit: -1Processor Tree:ListSink从执行计划中可以看到我们虽然已经开启了 Map-Side 聚合操作在 Mape 阶段出现了 Group By 聚合操作可是我们进入 Reduce 阶段前的数据量并没有变少和之前一样。
这是因为在上面提到的数据分布影响造成的问题因为 hive.groupby.mapaggr.checkinterval 默认只检查前 100000 行来验证是否进行 Map-Side 聚合操作由于这里数据量比较大导致前 100000 行的聚合键值大部分不相同它觉得即使对这 100000 行数据进行了聚合操作也达不到数据量减少 50% 的程度所以它才没有进行 Map-Side 聚合操作在这种情况下需要强制开启 Map-Side 聚合操作。
set hive.map.aggr.hash.min.reduction 1;执行结果运行 29 秒 可见速度的确得到大幅提升
从历史服务器中查看执行该任务的一个 Map 中可以看出在 Map 阶段的确发生了 Map-Side 聚合操作。 Map 阶段数据量前后对比少了很多这就是 Map-Side 的玩法。