2023-Hive性能企业级调优

news2024/11/28 4:38:37

Hive作为大数据平台举足轻重的框架,以其稳定性和简单易用性也成为当前构建企业级数据仓库时使用最多的框架之一。

但是如果我们只局限于会使用Hive,而不考虑性能问题,就难搭建出一个完美的数仓,所以Hive性能调优是我们大数据从业者必须掌握的技能。本文将给大家讲解Hive性能调优的一些方法及技巧。

Hive性能调优的方式

为什么都说性能优化这项工作是比较难的,因为一项技术的优化,必然是一项综合性的工作,它是多门技术的结合。我们如果只局限于一种技术,那么肯定做不好优化的。

下面将从多个完全不同的角度来介绍Hive优化的多样性,我们先来一起感受下。

1. SQL语句优化

SQL语句优化涉及到的内容太多,因篇幅有限,不能一一介绍到,所以就拿几个典型举例,让大家学到这种思想,以后遇到类似调优问题可以往这几个方面多思考下。

1. union all

insert into table stu partition(tp) 
select s_age,max(s_birth) stat,'max' tp 
from stu_ori
group by s_age

union all

insert into table stu partition(tp) 
select s_age,min(s_birth) stat,'min' tp 
from stu_ori
group by s_age;

我们简单分析上面的SQl语句,就是将每个年龄的最大和最小的生日获取出来放到同一张表中,union all 前后的两个语句都是对同一张表按照s_age进行分组,然后分别取最大值和最小值。对同一张表相同的字段进行两次分组,这造成了极大浪费,我们能不能改造下呢,当然是可以的,为大家介绍一个语法:from ... insert into ... ,这个语法将from前置,作用就是使用一张表,可以进行多次插入操作:

--开启动态分区 
set hive.exec.dynamic.partition=true; 
set hive.exec.dynamic.partition.mode=nonstrict; 

from stu_ori 

insert into table stu partition(tp) 
select s_age,max(s_birth) stat,'max' tp 
group by s_age

insert into table stu partition(tp) 
select s_age,min(s_birth) stat,'min' tp 
group by s_age;

上面的SQL就可以对stu_ori表的s_age字段分组一次而进行两次不同的插入操作。

这个例子告诉我们一定要多了解SQL语句,如果我们不知道这种语法,一定不会想到这种方式的

2. distinct

先看一个SQL,去重计数:

select count(1) 
from( 
  select s_age 
  from stu 
  group by s_age 
) b;

这是简单统计年龄的枚举值个数,为什么不用distinct?

select count(distinct s_age) 
from stu;

有人说因为在数据量特别大的情况下使用第一种方式能够有效避免Reduce端的数据倾斜,但是事实如此吗?

我们先不管数据量特别大这个问题,就当前的业务和环境下使用distinct一定会比上面那种子查询的方式效率高。原因有以下几点:

  1. 上面进行去重的字段是年龄字段,要知道年龄的枚举值是非常有限的,就算计算1岁到100岁之间的年龄,s_age的最大枚举值才是100,如果转化成MapReduce来解释的话,在Map阶段,每个Map会对s_age去重。由于s_age枚举值有限,因而每个Map得到的s_age也有限,最终得到reduce的数据量也就是map数量*s_age枚举值的个数。

  2. distinct的命令会在内存中构建一个hashtable,查找去重的时间复杂度是O(1);group by在不同版本间变动比较大,有的版本会用构建hashtable的形式去重,有的版本会通过排序的方式, 排序最优时间复杂度无法到O(1)。另外,第一种方式(group by)去重会转化为两个任务,会消耗更多的磁盘网络I/O资源。

  3. 最新的Hive 3.0中新增了 count(distinct ) 优化,通过配置 hive.optimize.countdistinct,即使真的出现数据倾斜也可以自动优化,自动改变SQL执行的逻辑。

  4. 第二种方式(distinct)比第一种方式(group by)代码简洁,表达的意思简单明了,如果没有特殊的问题,代码简洁就是优!

这个例子告诉我们,有时候我们不要过度优化,调优讲究适时调优,过早进行调优有可能做的是无用功甚至产生负效应,在调优上投入的工作成本和回报不成正比。调优需要遵循一定的原则

2. 数据格式优化

Hive提供了多种数据存储组织格式,不同格式对程序的运行效率也会有极大的影响。

Hive提供的格式有TEXT、SequenceFile、RCFile、ORC和Parquet等。

SequenceFile是一个二进制key/value对结构的平面文件,在早期的Hadoop平台上被广泛用于MapReduce输出/输出格式,以及作为数据存储格式。

Parquet是一种列式数据存储格式,可以兼容多种计算引擎,如MapRedcue和Spark等,对多层嵌套的数据结构提供了良好的性能支持,是目前Hive生产环境中数据存储的主流选择之一。

ORC优化是对RCFile的一种优化,它提供了一种高效的方式来存储Hive数据,同时也能够提高Hive的读取、写入和处理数据的性能,能够兼容多种计算引擎。事实上,在实际的生产环境中,ORC已经成为了Hive在数据存储上的主流选择之一。

我们使用同样数据及SQL语句,只是数据存储格式不同,得到如下执行时长:

数据格式CPU时间用户等待耗时
TextFile33分171秒
SequenceFile38分162秒
Parquet2分22秒50秒
ORC1分52秒56秒

注:CPU时间:表示运行程序所占用服务器CPU资源的时间。
用户等待耗时:记录的是用户从提交作业到返回结果期间用户等待的所有时间。

查询TextFile类型的数据表CPU耗时33分钟, 查询ORC类型的表耗时1分52秒,时间得以极大缩短,可见不同的数据存储格式也能给HiveSQL性能带来极大的影响。

3. 小文件过多优化

小文件如果过多,对 hive 来说,在进行查询时,每个小文件都会当成一个块,启动一个Map任务来完成,而一个Map任务启动和初始化的时间远远大于逻辑处理的时间,就会造成很大的资源浪费。而且,同时可执行的Map数量是受限的。

4. 并行执行优化

Hive会将一个查询转化成一个或者多个阶段。这样的阶段可以是MapReduce阶段、抽样阶段、合并阶段、limit阶段。或者Hive执行过程中可能需要的其他阶段。默认情况下,Hive一次只会执行一个阶段。不过,某个特定的job可能包含众多的阶段,而这些阶段可能并非完全互相依赖的,也就是说有些阶段是可以并行执行的,这样可能使得整个job的执行时间缩短。如果有更多的阶段可以并行执行,那么job可能就越快完成。

通过设置参数hive.exec.parallel值为true,就可以开启并发执行。在共享集群中,需要注意下,如果job中并行阶段增多,那么集群利用率就会增加。

set hive.exec.parallel=true; //打开任务并行执行
set hive.exec.parallel.thread.number=16; //同一个sql允许最大并行度,默认为8。

当然得是在系统资源比较空闲的时候才有优势,否则没资源,并行也起不来。

5. 数据倾斜优化

数据倾斜的原理都知道,就是某一个或几个key占据了整个数据的90%,这样整个任务的效率都会被这个key的处理拖慢,同时也可能会因为相同的key会聚合到一起造成内存溢出。

Hive的数据倾斜一般的处理方案

常见的做法,通过参数调优:

set hive.map.aggr=true;  
set hive.groupby.skewindata = ture;

当选项设定为true时,生成的查询计划有两个MapReduce任务。

在第一个MapReduce中,map的输出结果集合会随机分布到reduce中,每个reduce做部分聚合操作,并输出结果。

这样处理的结果是,相同的Group By Key有可能分发到不同的reduce中,从而达到负载均衡的目的;

第二个MapReduce任务再根据预处理的数据结果按照Group By Key分布到reduce中(这个过程可以保证相同的Group By Key分布到同一个reduce中),最后完成最终的聚合操作。

但是这个处理方案对于我们来说是个黑盒,无法把控。

那么在日常需求的情况下如何处理这种数据倾斜的情况呢:

  1. sample采样,获取哪些集中的key;

  2. 将集中的key按照一定规则添加随机数;

  3. 进行join,由于打散了,所以数据倾斜避免了;

  4. 在处理结果中对之前的添加的随机数进行切分,变成原始的数据。

例:如发现有90%的key都是null,数据量一旦过大必然出现数据倾斜,可采用如下方式:

SELECT *
FROM a
 LEFT JOIN b ON CASE 
   WHEN a.user_id IS NULL THEN concat('hive_', rand())
   ELSE a.user_id
  END = b.user_id;

注意:给null值随机赋的值不要与表中已有的值重复,不然会导致结果错误。

6. Limit 限制调整优化

一般情况下,Limit语句还是需要执行整个查询语句,然后再返回部分结果。

有一个配置属性可以开启,避免这种情况:对数据源进行抽样

hive.limit.optimize.enable=true -- 开启对数据源进行采样的功能

hive.limit.row.max.size -- 设置最小的采样容量

hive.limit.optimize.limit.file -- 设置最大的采样样本数

缺点:有可能部分数据永远不会被处理到

7. JOIN优化

1. 使用相同的连接键

当对3个或者更多个表进行join连接时,如果每个on子句都使用相同的连接键的话,那么只会产生一个MapReduce job。

2. 尽量尽早地过滤数据

减少每个阶段的数据量,对于分区表要加分区,同时只选择需要使用到的字段。

3. 尽量原子化操作

尽量避免一个SQL包含复杂逻辑,可以使用中间表来完成复杂的逻辑。

8. 谓词下推优化

Hive中的 Predicate Pushdown 简称谓词下推,简而言之,就是在不影响结果的情况下,尽量将过滤条件下推到join之前进行。谓词下推后,过滤条件在map端执行,减少了map端的输出,降低了数据在集群上传输的量,节约了集群的资源,也提升了任务的性能。

我们看下面这个语句:

select s1.key, s2.key 
from s1 left join s2 
on s1.key > '2';

上面是一个Left Join语句,s1是左表,称为保留行表,s2是右表。

:on条件的s1.key > '2' 是在join之前执行还是之后?也就是会不会进行谓词下推?

:不会进行谓词下推,因为s1是保留行表,过滤条件会在join之后执行。

而下面这个语句:

select s1.key, s2.key 
from s1 left join s2 
on s2.key > '2';

s2表不是保留行,所以s2.key>2条件可以下推到s2表中,也就是join之前执行。

再看下面这个语句:

select s1.key, s2.key 
from s1 left join s2 
where s1.key > '2';

右表s2为NULL补充表。

s1不是NULL补充表,所以s1.key>2可以进行谓词下推。

而下面语句:

select s1.key, s2.key 
from s1 left join s2 
where s2.key > '2';

由于s2为NULL补充表,所以s2.key>2过滤条件不能下推。

那么谓词下推的规则是什么,到底什么时候会进行下推,什么时候不会下推,总结了下面的一张表,建议收藏保存

案例

select a.*  
from a  
left join b on  a.uid = b.uid  
where a.ds='2020-08-10'  
and b.ds='2020-08-10'

上面这个SQL主要犯了两个错误

  1. 右表(上方b表)的where条件写在join后面,会导致先全表关联在过滤分区。

注:虽然a表的where条件也写在join后面,但是a表会进行谓词下推,也就是先执行where条件,再执行join,但是b表不会进行谓词下推!

  1. on的条件没有过滤null值的情况,如果两个数据表存在大批量null值的情况,会造成数据倾斜。

最后

代码优化原则:

  • 理透需求原则,这是优化的根本;

  • 把握数据全链路原则,这是优化的脉络;

  • 坚持代码的简洁原则,这让优化更加简单;

  • 没有瓶颈时谈论优化,这是自寻烦恼。

     

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端周总结

在vue里面引入ts文件报错: An import path cannot end with a .ts extension. Consider importing xx.js instead. 方法一(最快) 把引入的xx.ts后缀删除 方法二 # 在tsconfig.json中加入以下配置 "baseUrl": ".", &quo…

Oracle LiveLabs实验:DB Security - Data Masking and Subsetting (DMS)

概述 本实验介绍了适用于 Enterprise Manager 的 Oracle 数据屏蔽和子集 (DMS) 包的各种特性和功能。 它使用户有机会学习如何配置这些功能,以便在非生产环境中保护他们的敏感数据。 此实验申请地址在这里,时间为60分钟。 本实验也是DB Security Adva…

String AOP

AOP AOP(Aspect Object programmar) 面向切面编程,它是对某一类问题的统一处理,而StringAOP就是AOP思想的一种具体实现就像Ioc和DI。 AOP组成 切面(Aspect) 切⾯(Aspect)由切点(Pointcut)和通知&#x…

论文阅读笔记《Grounded Action Transformation for Robot Learning in Simulation》

Grounded Action Transformation for Robot Learning in Simulation 发表于AAAI 2017 仿真机器人学习中的接地动作变换 Hanna J, Stone P. Grounded action transformation for robot learning in simulation[C]//Proceedings of the AAAI Conference on Artificial Intellig…

Linux中的阻塞机制

我们知道在字符设备驱动中,应用层调用read、write等系统调用终会调到驱动中对应的接口。 可以当应用层调用read要去读硬件的数据时,硬件的数据未准备好,那我们该怎么做? 一种办法是直接返回并报错,但是这样应用层要获得…

linux通配符和正则表达式深层解析...

目录: (一)了解通配符和正则的作用 (二)通配符的使用 (三)正则表达式的使用 (四)扩展正则表达式的使用 (一)了解通配符和正则的作用 (1.1)在我们日常的工作中,我们都会使用到通配符或者正则表达式。通配符是一种特殊语句,主要有星号(*)和问号…

交换机和路由器到底有什么区别???

我:度娘度娘,交换机和路由器的区别是什么呢? 度娘:一个工作在第二层数据链路层,一个工作在第三层网络层。 我:哈?那工作在不同层会有什么区别?为什么要工作在不同层? …

2023五一数学建模A题完整思路

已更新五一数学建模A题思路,文章末尾获取! A题完整思路: A题是一个动力学问题,需要我们将物理学概念运用到实际生活中,我们可以先看题目 问题1: 假设无人机以平行于水平面的方式飞行,在空中投…

Windows11安装sqlserver2012失败后解决方案

首先卸载 WinR打开运行输入services.msc查看所有服务/或者我的电脑管理找到服务列表/任务管理器进入服务列表,停止所有与Sql Server有关的服务,如下: 打开控制面板-卸载sqlserver所有相关软件; 删除SQL Server相关注册表&#…

【观察】中国软件行业进入“重构期”,看浪潮海岳如何“开新局”

众所周知,改开四十多来年,中国软件产业在经历了萌芽与低谷、摸索与转型后,逐步进入了快速发展期。特别是过去几年,在新的发展格局,信创替代的进程中,整个中国软件业更是加速进入了全新的“重构期”。 在此过…

Unity API详解——Quaternion类

Quaternion类又称四元数,由x、y、z和w这4个分量组成,属于struct类型。在Unity中,用Quaternion来存储和表示对象的旋转角度。Quaternion的变换比较复杂,对于GameObject一般的旋转及移动,可以用Transform中的相关方法实现…

CH32V307环境参数在线监测系统(一)

CH32V307环境参数在线监测系统是以CH32V307VCT6为核心,由ESP8266模块、DHT11温湿度传感器模块、TFT LCD显示屏组成。系统实物图如下所示: 系统功能主要有RTC实时时钟、WIFI网络授时、DHT11温度测量、温湿度数据实时上传到onenet平台、屏幕定时刷新等功能…

在Docker上安装和运行MySQL容器(纯步骤)

在Docker上安装和运行MySQL步骤 本文章只有操作步骤,没有原理解释,只是在学习当中提醒自己安装步骤。 第一步:从远程仓库拉取MySQL镜像 1.从远程仓库搜索mysql镜像 docker search mysql2.pull拉取镜像 这里我选择的是mysql的5.7版本 docker…

盘点 5 个 yyds 的 AI 绘画辅助工具

国外著名的 AI 作图工具 Midjourney、Stable Diiffusion 都可以根据你输入的指令生成一张图片。 如果你想输出高质量的图片,需要掌握一些 prompt 指令技巧。本文章便盘点了 5 个 GitHub 上的开源项目,引领你更好的上手 AI 作图。 本期推荐开源项目目录&…

软件杯龙源风电赛题培训!千万分钟数据和全流程基线等你来战

‍‍ “中国软件杯”大学生软件设计大赛是一项面向中国在校学生的公益性赛事,大赛由国家工业和信息化部、教育部、江苏省人民政府共同主办,是全国软件行业规格最高、最具影响力的国家级一类赛事。其中,作为重点赛题的龙源风电赛,上…

我们分析了9.12亿篇博客文章,得出了11条内容营销发现

我们分析了 9.12 亿篇博客文章,想要更好地了解目前的内容营销领域。 具体来说,我们研究了这些文章的内容格式、字数和标题等因素与社交媒体分享和反向链接的关联性。 在我们的数据合作伙伴BuzzSumo的帮助下,我们有了一些非常有趣的发现。 …

Dex-Net使用手册————GQCNN网络

1. Dex-Net Package GitHub - BerkeleyAutomation/dex-net 🎈dex-net Python 包用于打开、读取和编写 HDF5 数据库的 3D 对象模型、平行下颚抓取和掌握鲁棒性指标。 🎈HDF5数据库还可用于生成大量数据集,将点云和抓取的元组与二进制抓取鲁棒…

【Python】【进阶篇】12、搭建Django开发环境

目录 搭建Django开发环境1. 安装Python解释器2. 安装MySQL数据库3. 安装Python包管理器4. 安装 Pycharm IDE 搭建Django开发环境 上一章我们介绍了 Django 框架的重要组件,常言道“工欲善其事,必先利其器”,在正式创建 Django 项目之前&…

AI绘画——Lora模型Niji-Expressive V2 launch(灵动优雅,张力尽显)

目录 Niji-Expressive V2 launch!! 灵动优雅,张力尽显 Vivid and elegant, full of tension 模型演示(多图预警) Niji-Expressive V2 launch!! 灵动优雅,张力尽显 本次升级泛用性,能在更多模型和采样方式上适用 …

《一文带你读懂:云原生时代业务监控》

点击上方蓝字关注我们! 对业务来说,完备的应用健康性和数据指标的监控非常重要,通过采集准确的监控指标、配置合理的告警机制,我们能够提前或者尽早发现问题,并做出响应、解决问题,进而保证产品的稳定性&am…