详细讲解hive on tez中各个参数作用,以及如何优化sql

最近经常有优化sql的任务,但是自己能力有限,只能凭经验去优化,现整理加学习一波,也欢迎各位学习和讨论。

我们经常用hivesql 的模型就是 join.如下。

insert overwrite table a select * from b left join c 

这里面发生了什么,执行流程是什么,为什么有的insert要几十分钟有的只要几分钟。

CREATE TABLE `cc_test`.`multi_join`
(
    `id`   int,
    `name` string,
    `desc` string
)
    stored as orc;

--造1000w条数据 文件大小为300M

insert overwrite table cc_test.multi_join
select if(row_number() over ()<1000,1,row_number() over ()),
       'cclovezbf'||(row_number() over ()),
       repeat('desc',1000)||(row_number() over ())
from (select explode(split(space(10000000),'')) t)t

已知上面的数据为1000w条

其中 id=1的有1000条 其余id=1000到1000w的依次分布 


1.explain 和 set 

所有的优化和学习离不开explain和set 

set分 set 和set -v 两者差别不清楚,但是有些设置参数需要自己查。

explain就是解析sql的执行顺序和逻辑。

2. 

insert overwrite table cc_test.multi_join_bak
select * from cc_test.multi_join

 执行过程

 这里为啥有2个map?为啥reduce又只有1个呢?

3.distribute by

explain
insert overwrite table cc_test.multi_join_bak
select * from cc_test.multi_join
distribute by  round(rand()*30)

而且大家注意到没有 上面的31个文件为什么有2个5.6M,其他的是11.1M,为什么这么特殊?不是平均分配吗?有人告诉过你这个点吗?我来为你揭秘,这个就是纯属数学概率问题。
已知 rand=0-0.99 例如我们rand()*4 本意是想 数值从1到4或者 0到4平均分配。rand*4=0-3.99

round(rand*4)最终(0-0.49)=0 (0.5-1.49)=1 (1.5-2.49)=2 (2.5-3.49)=3 (3.5-3.99)=4 看到没

最终=0和4的概率会明显小于 =123的概率

其实正确的做法是int(rand*4) 这样分布的概率就会平均

4.reduce的个数

set mapred.reduce.tasks=-1;
set hive.exec.reducers.bytes.per.reducer=67108864  ##默认64M

set mapred.reduce.tasks=40;
insert overwrite table cc_test.multi_join_bak
select * from cc_test.multi_join
distribute by round(rand()*30);

 此时大家猜一猜文件数是40还是30呢?答案是22个。

通过文件的序号可以看到这里应该是有类似merge操作的。此处暂且留下疑问

那么么我们将reudce个数改小呢?

set mapred.reduce.tasks=5;
insert overwrite table cc_test.multi_join_bak
select * from cc_test.multi_join
distribute by round(rand()*30);

可以看到文件数为5

说明该参数set mapred.reduce.tasks与生成的文件数有关,注意不是最终文件数。

再说说为什么reduce=40 distribute30 生成22个文件,根据我测试

reduce=100 distribute30 生成25个文件

reduce=300 distribute30 生成27个文件

reduce=301 distribute30 生成25个文件

reduce=500 distribute30 生成27个文件

文件数和reduce个数好像又成正比,但是reduce:300增加到301的时候文件数为什么变少了?其实聪明的小伙伴此时应该都想到了,可能就是取模。

简单的来说 map阶段获取的数据 在distrbue分为30份为data1/data2/....data30

reduce=300,data1/2/3/4对hash(300)取模后=1,data5到30分布在分区2-27,最终27个文件

reduce=300,data1/2/3/4/5/6对hash(300)取模后=1,data7到30分布到分区2-25,最终25个文件

验证下

reduce=15 distribute30 生成12个文件

reduce=14 distribute30 生成14个文件

 reduce=13 distribute30 生成9个文件

 这说明reduce=13时运气不好 取模后的值大多都在一个分区 如上,都在1/2/6/12号分区,没有取模后=3/5号分区的,所以文件数<reudce个数

 至于reduce=5 30个文件大概率是会均分到5个reduce。

那么我们 怎么合理的使用这两个参数呢?

比如我们的目的是最终生成10个文件,数据尽量分散或者平均。

首先reduce=10毫无疑问,distributeby 如何设置呢? 设置小了文件数可能<10,设置大了就会越分散,并且经过测试 distribute 不会产生额外的mr,只会在map阶段产出一个分区

由此可以得到结论:该参数会影响生成的最后文件,但是不是最终决定文件个数的决定性因数。

比如distribute by 和merge都会影响最后生成的文件个数。

题外话知道为什么该参数默认=-1吗?就是因为你有时候设置了具体的参数,但是结果数不一致,会导致你怀疑人生,所以reduce默认时按照大小生成reduce个数的。这里又涉及到一个知识点,reduce个数设置过大,会导致空转白白浪费资源。

5.map的个数

mapreduce.input.fileinputformat.split.minsize=1

mapreduce.input.fileinputformat.split.maxsize=256000000

细心的小伙伴在实验的时候肯定会发现 map数量少的时候跑的很慢,数量多的时候跑的很快。

那么map数量和什么有关呢?

1.文件数量, 一般来说文件数量=map数,注意这里说的一般来说。

2.文件的总大小。

我上面提到的两个参数又是什么意思呢?是说map阶段读取的文件大小最小是1最大时256M。

例如我们现在的数据为2个180M 

1k<180M <256M 所以刚好使用2个Map

如果我们修改参数

set mapreduce.input.fileinputformat.split.minsize=64000000;
set mapreduce.input.fileinputformat.split.maxsize=64000000;

设置map读取的范围时64M 那么180M如何拆分呢?

注意这里很有意思用了4个map,最后输出文件为4,但是仔细看文件大小 两大121M两小59M 

121+59M=180M 刚好等于之前没拆分的大小。

继续实验

5.多出来的reduce(统计信息)

set hive.stats.autogather=true;

set hive.stats.column.autogather=true;

细心的小伙伴可能会发现之前的执行过程有点奇怪。

map1:读取from 表数据  map1input=1000w output=1000w 没问题

reduce2:插入到insert表的过程 reduce读取map的数据,input=1000w也没问题,output=10?这个10是什么呢?暂时猜测是最终的文件数

reduce3:这个是什么呢?而且reduce3只有一个task,我们可是设置reduce=10了的呀?而且这个的output=0这又是什么呢 ?

这里就用到我们的explain了。

explain
insert overwrite table cc_test.multi_join_bak
select * from cc_test.multi_join_bak
distribute by  int (rand()*3000);

 看到这个大部分人就知道了,这个是hive默认的统计信息,意思就是当你覆盖表信息的时候,hive就要统计下,这个一般不会耗时很久,还是做个实验

可以看到reduce3没有了,这样就能更好的分析执行过程了。。

6.文件合并的优化

#小于该大小的就会被合并

set hive.merge.smallfiles.avgsize=16777216

# 文件合并的最后大小

set hive.merge.size.per.task=268435456
set hive.merge.sparkfiles=false
set hive.merge.tezfiles=false

//reudce阶段合并
set hive.merge.mapredfiles=false

//map阶段合并
set hive.merge.mapfiles=true

有时候我们的目录下面都是小文件,这样会可能会开启很多map任务

 

insert overwrite table cc_test.multi_join_bak
select * from cc_test.multi_join_bak distribute by  int (rand()*3000);
##为什么只有956个呢? 因为3000 hash后也没有均匀分布

6000之后reduce的个数正好就是1009了。

set hive.exec.reducers.max=1009

已知我们读取的表数据有360M  文件数有1009个 那我们读取的时候会有多少个map呢?

insert overwrite table cc_test.multi_join select * from cc_test.multi_join ;

答案是25个? 为什么是25个呢? 这个14.4又是什么呢?所以我们考虑到的事情,比我们优秀的人更早就就考虑到了。下面的是默认参数

set hive.merge.mapfiles=true;

//小文件合并的阈值16M是不是和14.4很像呢?

set hive.merge.smallfiles.avgsize=16777216;

如何证实呢?set hive.merge.smallfiles.avgsize=33554432 这样是不会map会变为12或13呢?

发现还是25个,此时有点想不通了,是参数没起作用还是我理解错了? 这个暂且不说。这问题留到下面讲。

先说ditribute by 这个参数可以让reduce个数更多,但是我们有时候真的需要这么多文件吗?这个对于namenode来说负担很大,还有reduce个数多了,map数也多了,真的好吗?

所以我们需要处理这些小文件,有人又说了 distributeby(rand*6) 这样就只有6个文件了,或者set reduce.task=6也可以。但是我们现在既想任务跑的快,又想文件少。

这个时候就要说

set hive.merge.tezfiles=true;

set hive.merge.mapredfiles=true;  #默认关闭 我们此时打开

set hive.merge.smallfiles.avgsize=16777216; #文件小于这个参数的开始被merge

set hive.merge.size.per.task=268435456;

已知文件个数为1009 每个文件差不多在300K左右。

 insert overwrite table cc_test.multi_join_bak select * from cc_test.multi_join_bak

可以看到mapreduce阶段完了之后 又多了一个file merge阶段,说明参数确实起作用了。

最后形成的文件大小也是接近于256M。

所以这个参数适用于小文件比较多的表,注意最后的merge。

再说说最开始的map数据为什么不变呢?

set mapreduce.input.fileinputformat.split.minsize=1;
set mapreduce.input.fileinputformat.split.maxsize=256000000;

set tez.grouping.min-size=16777216;
set tez.grouping.max-size=134217728;

hive.merge.smallfiles.avgsize=16777216;

hive.merge.mapfiles=true;

7.资源控制(TEZ)

set tez.grouping.min-size=16777216  ##16M

set tez.grouping.max-size=134217728 ##  128这个是我这边集群的 

set tez.grouping.split-waves=1.7  #调整一个比例的,

set hive.merge.smallfiles.avgsize=16777216;
set hive.merge.mapfiles=true;

set mapreduce.input.fileinputformat.split.minsize=1;
set mapreduce.input.fileinputformat.split.maxsize=256000000;

 上面第6项说到了 360M的1000个文件读取的map数是25个?而且设置set hive.merge.smallfiles.avgsize=32M没有任何效果 ,这个很正常,这个参数代表的是小于32M以下的文件会被合并为一个大文件放到一个MAP里,注意这里并没有说这些小文件合并为多大了就不合并了? 1000个100k的小文件是合成100个map还是10个 还是1个,肯定是有参数限制了的。

set hive.merge.mapfiles=false; 

insert overwrite table cc_test.multi_join select * from cc_test.multi_join ;

结果还是25个map,

此时就隐隐约约感觉有点奇怪了?我map阶段都不合并文件了?为啥还是这么多map呢?

答案就是 set tez.grouping.min-size=16777216=16M 这个参数规定了每个map的group里最少是16M,这里的16M是什么呢?就是上文说的14.4。

set tez.grouping.min-size=4194304; #4M

set hive.merge.mapfiles=true;

insert overwrite table cc_test.multi_join select * from cc_test.multi_join ;

可以看到map数量变了16M->4M,map数 25->98, 一个缩小4倍 一个增多4倍;

set tez.grouping.split-waves=1.7  # 这个参数经过测试是会影响map的数量的,但是影响不大,我以前看过源码稍微研究了下,有兴趣的自己看下

7.join优化之mapjoin

set hive.auto.convert.join=true #默认true
set hive.mapjoin.smalltable.filesize=25000000 #默认25M 注意是我这边集群默认
set hive.auto.convert.join.noconditionaltask=true  #默认true
set hive.auto.convert.join.noconditionaltask.size=52428800   #50M

上面所有的示例都没有涉及到join优化,涉及到join优化先得说下mapjoin,mapjoin默认开启。具体有什么好处就不说了。但是我说一点,并不是所有的任务都是mapjoin好,我遇到过mr比mapjoin跑的快的。

未完待续。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/422026.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

医学AI再度得到国自然重大专项青睐,10个立项机会,4000万经费虚位以待|个人观点·24-09-12

小罗碎碎念 昨天国自然基金委公布了几个专项项目&#xff0c;看标题我以为和医学AI无关&#xff0c;多亏了群里的一位小伙伴给我转发指南链接&#xff0c;我才看到与医学AI相关的内容。 项目名称是“重大疾病智慧诊疗”&#xff0c;直接费用总额度约3000-4000万元。计划资助联合…

UE5------光照渲染

自动曝光-------出隧道的一瞬间&#xff0c;外面会非常的亮

【问题回溯】记录处理launcher3滑动卡顿问题

项目问题背景问题描述分析过程初步分析挖根因验证观点修改和验证 结论和反思结论反思 项目 Android14&#xff0c;展锐T606 问题背景 老平台升级Android13升级到Android14&#xff0c;对此问题无影响 问题描述 客户反馈在launcher应用列表中滑动卡顿明显&#xff0c;选中的…

人工智能|集成学习——混合专家模型 (MoE)

随着 Mixtral 8x7B (announcement, model card) 的推出&#xff0c;一种称为混合专家模型 (Mixed Expert Models&#xff0c;简称 MoEs) 的 Transformer 模型在开源人工智能社区引起了广泛关注。在本篇博文中&#xff0c;我们将深入探讨 MoEs 的核心组件、训练方法&#xff0c;…

论文120:Giga-SSL: Self-supervised learning for gigapixel images (2023, CVPR, 开源)

文章目录 1 要点2 方法2.1 算法设计2.2 设计选择 1 要点 题目&#xff1a;用于千兆像素图像的自监督学习 (Giga-SSL: Self-Supervised Learning for Gigapixel Images) 代码&#xff1a;https://github.com/trislaz/gigassl 研究目的&#xff1a; 现有的WSI分类方法依赖于有…

C语言蓝桥杯:语言基础

竞赛常用库函数 最值查询 min_element和max_element在vector(迭代器的使用) nth_element函数的使用 例题lanqiao OJ 497成绩分析 第一种用min_element和max_element函数的写法 第二种用min和max的写法 二分查找 二分查找只能对数组操作 binary_search函数&#xff0c;用于查找…

运动耳机哪个牌子最好用?年度精选五款好用的骨传导耳机推荐

相信大家都已经深有体会&#xff0c;拿那种常规的入耳式无线蓝牙耳机来做运动耳机&#xff0c;很难满足运动需要。如果选择前两年流行的颈挂式无线运动蓝牙耳机&#xff0c;虽然简单轻巧&#xff0c;但也是入耳式设计&#xff0c;长时间佩戴耳朵不舒服。这样看来&#xff0c;运…

vulhub spring 远程命令执行漏洞(CVE-2022-22963)

1.执行以下命令启动靶场环境并在浏览器访问 cd spring/CVE-2022-22963docker-compose up -ddocker ps 2.反弹shell 构造payload 页面刷新抓包&#xff0c;修改内容 POST /functionRouter HTTP/1.1 Host: 192.168.0.107:8080 Accept-Encoding: gzip, deflate Accept: */* Acc…

uni-app实现web-view和App之间的相互通信

双向实时 如果app端部署成网站&#xff0c;则web-view就是iframe&#xff0c;使用也可以双向通讯 https://uniapp.dcloud.net.cn/component/web-view.html APP端代码 index.vue: <template><web-viewid"m-webview":fullscreen"true":src"…

python-确定进制

题目描述 6 942 对于十进制来说是错误的&#xff0c;但是对于 13 进制来说是正确的。即 6(13)​ 9(13)​42(13)​&#xff0c;而 42(13)​4 13^12 13^054(10)​。 你的任务是写一段程序读入三个整数 p,q 和 r&#xff0c;然后确定一个进制 B(2≤B≤16) 使得 p qr 。如果 B 有…

CMS之Wordpress建设

下载 https://cn.wordpress.org/ 宝塔安装Wordpress 创建网站 上传文件、并解压、剪切文件到项目根目录 安装 -> 数据库信息 -> 标题信息 http://wordpress.xxxxx.com 登录 http://wordpress.xxxxxxxxx.com/wp-admin/ 1. 主题(模板) wordpress-基本使用-02-在主题…

VLAN配置学习笔记

1、VLAN的基础配置命令 &#xff08;1&#xff09;创建VLAN [Huawei] vlan vlan-id 通过此命令创建VLAN并进入VLAN视图&#xff0c;如果VLAN已存在&#xff0c;直接进入该VLAN的视图。 vlan-id是整数形式&#xff0c;取值范围是1&#xff5e;4094。 [Huawei] vlan batch {…

docker管理redis集群

1.拉取redis镜像 docker pull redis拉取完成 [rootlocalhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE redis latest a617c1c92774 3 years ago 105MB2.运行redis容器 docker run -itd --name redis-test01 -p 6379:6379…

Apache OFBiz 远程代码执行漏洞复现(CVE-2024-45195)并拿到shell

FOFA&#xff1a;app"Apache_OFBiz" 复现&#xff1a; VPS上准备两个文件 rceschema.xml <data-files xsi:noNamespaceSchemaLocation"http://ofbiz.apache.org/dtds/datafiles.xsd" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"…

c++基类和派生类对象的赋值转换——赋值兼容规则

1.引出 如下场景&#xff1a; 由于b是double类型&#xff0c;所以赋值给int类型的引用前&#xff0c;要先进行隐式类型转换&#xff0c;这中间会生成临时对象&#xff0c;类是对象具有常性&#xff0c;所以int&之前应该加上const。 但是下面的场景&#xff1a; 没有出现报…

Qt进程通信,不推荐使用QSharedMemory和QLocalSocket,而是推荐ZMQ

一、据一位资深的网友说QLocalSocket有问题&#xff0c;共享内存QSharedMemory也有&#xff0c;比如存在多线程问题&#xff0c;不灵活&#xff0c;丢数据等问题都有&#xff0c;而且还占资源。血的教训。后来换成了zmqprotobuf。ZMQ进程内&#xff0c;进程间&#xff0c;机器间…

电脑文件怎么加密?文件加密方法介绍

随着数字化时代的到来&#xff0c;电脑文件的安全性问题日益凸显。为了保护个人隐私和企业数据&#xff0c;文件加密成为了一项重要的安全措施。本文将详细介绍几种常见的电脑文件加密方法&#xff0c;帮助你更好地保护自己的数据安全。 超级加密3000 超级加密3000提供了两种主…

F110批量付款如何Debug BTE增强(后台JOB的调试方法)

F110批量付款如何Debug BTE增强&#xff08;后台JOB的调试方法&#xff09; SAP系统中的F110&#xff08;Automatic Payment&#xff09;是一个常用的付款程序&#xff0c;在实施过程中&#xff0c;也经常会遇到一些运行的错误&#xff0c;而对于此类的错误&#xff0c;通常的…

网络分析仪仪器校准要怎么进行检测?容易出现哪些误差?

当我们使用矢量网络分析仪时&#xff0c;会发现测量数据存在误差。要纠正它&#xff0c;首先要知道矢量网络分析仪的误差来源是什么。 主要有三个方面:漂移误差、随机误差、系统误差。 一、 漂移误差:是由于仪器或测试系统仪器校准之后性能发生变化引起的&#xff0c;主要是温…

uni-app和Node.js使用uni-push2.0实现通知栏消息推送功能

前言 uniapp 提供了 unipush 统一推送服务,但是每次要推送消息的时候都要登陆 Dcloud 开发者后台&#xff0c;有点不方便&#xff0c;运营需要在我们的后台系统就可以完成操作。 效果演示 消息下发流程 名词解释 名词解释通知消息指定通知标题和内容后&#xff0c;由个推 SD…