hive 调优记录

2023-11-04

数据倾斜总结

在做Shuffle阶段的优化过程中,遇到了数据倾斜的问题,造成了对一些情况下优化效果不明显。主要是因为在Job完成后的所得到的Counters是整个Job的总和,优化是基于这些Counters得出的平均值,而由于数据倾斜的原因造成map处理数据量的差异过大,使得这些平均值能代表的价值降低。Hive的执行是分阶段的,map处理数据量的差异取决于上一个stage的reduce输出,所以如何将数据均匀的分配到各个reduce中,就是解决数据倾斜的根本所在。规避错误来更好的运行比解决错误更高效。在查看了一些资料后,总结如下。

1数据倾斜的原因
1.1操作:

关键词

情形

后果

Join

其中一个表较小,

但是key集中

分发到某一个或几个Reduce上的数据远高于平均值

大表与大表,但是分桶的判断字段0值或空值过多

这些空值都由一个reduce处理,灰常慢

group by

group by 维度过小,

某值的数量过多

处理某值的reduce灰常耗时

Count Distinct

某特殊值过多

处理此特殊值的reduce耗时

1.2原因:

1)、key分布不均匀

2)、业务数据本身的特性

3)、建表时考虑不周

4)、某些SQL语句本身就有数据倾斜

1.3表现:

任务进度长时间维持在99%(或100%),查看任务监控页面,发现只有少量(1个或几个)reduce子任务未完成。因为其处理的数据量和其他reduce差异过大。

单一reduce的记录数与平均记录数差异过大,通常可能达到3倍甚至更多。 最长时长远大于平均时长。

2数据倾斜的解决方案

2.1参数调节:

hive.map.aggr = true

Map 端部分聚合,相当于Combiner

hive.groupby.skewindata=true

有数据倾斜的时候进行负载均衡,当选项设定为 true,生成的查询计划会有两个 MR Job。第一个 MR Job 中,Map 的输出结果集合会随机分布到 Reduce 中,每个 Reduce 做部分聚合操作,并输出结果,这样处理的结果是相同的 Group By Key 有可能被分发到不同的 Reduce 中,从而达到负载均衡的目的;第二个 MR Job 再根据预处理的数据结果按照 Group By Key 分布到 Reduce 中(这个过程可以保证相同的 Group By Key 被分布到同一个 Reduce 中),最后完成最终的聚合操作。

2.2 SQL语句调节:

如何Join:

关于驱动表的选取,选用join key分布最均匀的表作为驱动表

做好列裁剪和filter操作,以达到两表做join的时候,数据量相对变小的效果。

大小表Join:

使用map join让小的维度表(1000条以下的记录条数) 先进内存。在map端完成reduce.

大表Join大表:

把空值的key变成一个字符串加上随机数,把倾斜的数据分到不同的reduce上,由于null值关联不上,处理后并不影响最终结果。

count distinct大量相同特殊值

count distinct时,将值为空的情况单独处理,如果是计算count distinct,可以不用处理,直接过滤,在最后结果中加1。如果还有其他计算,需要进行group by,可以先将值为空的记录单独处理,再和其他计算结果进行union。

group by维度过小:

采用sum() group by的方式来替换count(distinct)完成计算。

特殊情况特殊处理:

在业务逻辑优化效果的不大情况下,有些时候是可以将倾斜的数据单独拿出来处理。最后union回去。

3典型的业务场景

3.1空值产生的数据倾斜

场景:如日志中,常会有信息丢失的问题,比如日志中的 user_id,如果取其中的 user_id 和 用户表中的user_id 关联,会碰到数据倾斜的问题。

解决方法1: user_id为空的不参与关联(红色字体为修改后)

select * from log a
  join users b
  on a.user_id is not null
  and a.user_id = b.user_id
union all
select * from log a
  where a.user_id is null;

解决方法2 :赋与空值分新的key值

select *
  from log a
  left outer join users b
  on case when a.user_id is null then concat(‘hive’,rand() ) else a.user_id end = b.user_id;

结论:方法2比方法1效率更好,不但io少了,而且作业数也少了。解决方法1中 log读取两次,jobs是2。解决方法2 job数是1 。这个优化适合无效 id (比如 -99 , ’’, null 等) 产生的倾斜问题。把空值的 key 变成一个字符串加上随机数,就能把倾斜的数据分到不同的reduce上 ,解决数据倾斜问题。

3.2不同数据类型关联产生数据倾斜

场景:用户表中user_id字段为int,log表中user_id字段既有string类型也有int类型。当按照user_id进行两个表的Join操作时,默认的Hash操作会按int型的id来进行分配,这样会导致所有string类型id的记录都分配到一个Reducer中。

解决方法:把数字类型转换成字符串类型

select * from users a
  left outer join logs b
  on a.usr_id = cast(b.user_id as string)

3.3小表不小不大,怎么用 map join 解决倾斜问题

使用 map join 解决小表(记录数少)关联大表的数据倾斜问题,这个方法使用的频率非常高,但如果小表很大,大到map join会出现bug或异常,这时就需要特别的处理。 以下例子:

select * from log a
  left outer join users b
  on a.user_id = b.user_id;

users 表有 600w+ 的记录,把 users 分发到所有的 map 上也是个不小的开销,而且 map join 不支持这么大的小表。如果用普通的 join,又会碰到数据倾斜的问题。

解决方法:

select /*+mapjoin(x)*/* from log a
  left outer join (
    select  /*+mapjoin(c)*/d.*
      from ( select distinct user_id from log ) c
      join users d
      on c.user_id = d.user_id
    ) x
  on a.user_id = b.user_id;

假如,log里user_id有上百万个,这就又回到原来map join问题。所幸,每日的会员uv不会太多,有交易的会员不会太多,有点击的会员不会太多,有佣金的会员不会太多等等。所以这个方法能解决很多场景下的数据倾斜问题。

4总结

使map的输出数据更均匀的分布到reduce中去,是我们的最终目标。由于Hash算法的局限性,按key Hash会或多或少的造成数据倾斜。大量经验表明数据倾斜的原因是人为的建表疏忽或业务逻辑可以规避的。在此给出较为通用的步骤:

1、采样log表,哪些user_id比较倾斜,得到一个结果表tmp1。由于对计算框架来说,所有的数据过来,他都是不知道数据分布情况的,所以采样是并不可少的。

2、数据的分布符合社会学统计规则,贫富不均。倾斜的key不会太多,就像一个社会的富人不多,奇特的人不多一样。所以tmp1记录数会很少。把tmp1和users做map join生成tmp2,把tmp2读到distribute file cache。这是一个map过程。

3、map读入users和log,假如记录来自log,则检查user_id是否在tmp2里,如果是,输出到本地文件a,否则生成<user_id,value>的key,value对,假如记录来自member,生成<user_id,value>的key,value对,进入reduce阶段。

4、最终把a文件,把Stage3 reduce阶段输出的文件合并起写到hdfs。

如果确认业务需要这样倾斜的逻辑,考虑以下的优化方案:

1、对于join,在判断小表不大于1G的情况下,使用map join

2、对于group by或distinct,设定 hive.groupby.skewindata=true

3、尽量使用上述的SQL语句调节进行优化

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

hive 调优记录 的相关文章

  • “源兼容性”和“目标兼容性”有什么区别?

    之间有什么关系 区别sourceCompatibility and targetCompatibility 当它们设置为不同的值时会发生什么 根据工具链和兼容性 https docs gradle org current userguide
  • 在Windows Server 2003下如何在本地系统帐户下运行jvisualvm.exe?

    我在带有 Java 1 6 u 20 的 Windows Server 2003 下将 GlassFish 3 0 1 作为 Windows 服务运行 总体上我很满意 我希望能够在这个 JVM 上使用 VisualVM 并使用无法在 Tom
  • 我们可以有条件地声明 spring bean 吗?

    有没有一种方法可以有条件地声明 Spring bean 例如
  • 通过Zuul上传大文件

    我在通过 zuul 上传大文件时遇到问题 我正在使用 apache commons 文件上传 https commons apache org proper commons fileupload https commons apache o
  • 使用 OkHttp 下载损坏的文件

    我编写的下载文件的方法总是会产生损坏的文件 public static String okDownloadToFileSync final String link final String fileName final boolean te
  • JOOQ 忽略具有默认值的数据库列

    看来JOOQ完全忽略了数据库列的默认值 既不会更新 ActiveRecord 对象 也不会在 INSERT 时跳过此列 相反 它尝试将其设置为 NULL 这在 NOT NULL 列上失败 Example CREATE TABLE bug f
  • 将类转换为 JSONObject

    我有好几堂这样的课 我想将类转换为 JSONObject 格式 import java io Serializable import com google gson annotations SerializedName public cla
  • Java AES 256 加密

    我有下面的 java 代码来加密使用 64 个字符密钥的字符串 我的问题是这会是 AES 256 加密吗 String keyString C0BAE23DF8B51807B3E17D21925FADF273A70181E1D81B8EDE
  • ThreeTen 向后移植与 JSR-310 的比较

    由于某些原因 我们现在无法使用 java 8 我们仍然停留在 java 7 上 不过 我想使用新的JSR 310 date time APIs现在 使用官方向后移植 ThreeTen http www threeten org threet
  • 在光标所在行强制关闭!

    嘿 我正在尝试创建一个应用程序来查找存储在 SQlite 数据库中的 GPS 数据 但我面临一个问题 我构建了一个 DbAdapter 类来创建数据库 现在我尝试使用以下函数从另一个类获取所有数据上的光标 public Cursor fet
  • 在 Spring 中为 @Pathvariable 添加类级别验证

    在发布这个问题之前 我已经做了很多研究并尝试了很多可用的解决方案 这是我陷入的棘手情况 我有一个 Spring 控制器 它有多个请求映射 它们都有 PathVariables 控制器如下所示 Controller EnableWebMvc
  • 为什么在将 String 与 null 进行比较时会出现 NullPointerException?

    我的代码在以下行中出现空指针异常 if stringVariable equals null 在此语句之前 我声明了 stringVariable 并将其设置为数据库字段 在这个声明中 我试图检测该字段是否有null值 但不幸的是它坏了 有
  • 无需递归即可对可观察结果进行分页 - RxJava

    我有一个非常标准的 API 分页问题 您可以通过一些简单的递归来处理 这是一个捏造的例子 public Observable
  • Tomcat 6 未从 WEB-INF/lib 加载 jar

    我正在尝试找出我的 tomcat 环境中的配置问题 我们的生产服务器正在运行 tomcat 安装并从共享 NFS 挂载读取战争 然而 当我尝试使用独立的盒子 及其配置 进行同样的战争时 我收到下面发布的错误 有趣的是 如果我将 WEB IN
  • 我们如何使用 thymeleaf 绑定对象列表的列表

    我有一个表单 用户可以在其中添加任意数量的内容表对象这也可以包含他想要的列对象 就像在 SQL 中构建表一样 我尝试了下面的代码 但没有任何效果 并且当我尝试绑定两个列表时 表单不再出现 控制器 ModelAttribute page pu
  • java实现excel价格、收益率函数[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 在 Java 中通过 D-Bus MPRIS 访问 Clementine 实例

    我使用 Clementine 作为音乐播放器 它可以通过 D Bus 命令进行控制 在命令行上 使用 qdbus 我可以 Start Stop 暂停播放器 强制它跳过播放列表中的歌曲 检查播放列表的长度 检查播放列表中当前播放的曲目及其元数
  • Android ScrollView,检查当前是否滚动

    有没有办法检查标准 ScrollView 当前是否正在滚动 方向是向上还是向下并不重要 我只需要检查它当前是否正在滚动 ScrollView当前形式不提供用于检测滚动事件的回调 有两种解决方法可用 1 Use a ListView并实施On
  • 检测到 JVM 正在关闭

    我有一个使用 addShutdownHook 处理 Ctrl C 的 Swing 应用程序 它工作正常 直到我的关闭任务之一调用一个在正常情况下更改 JLabel 文本的函数 此时它挂起 我认为问题是 Swing EDT 已终止或正在等待某
  • 使用 DBCP 配置 Tomcat

    在闲置一段时间 几个小时 后 我们收到了 CommunicationsException 来自 DBCP 错误消息 在异常中 位于这个问题的末尾 但我没有看到任何配置文件中定义的 wait timeout 我们应该看哪里 在 tomcat

随机推荐

  • Java元注解

    目录 什么是注解 注解的重要性 Target Retention Documented 很少 Inherited 极少 什么是注解 注解其实就是代码里的特殊标记 这些标记可以在编译 类加载 运行时被读取 并执行相应的处理 通过使用注解 程序
  • 虚拟员工—RPA机器人助力创业者迈向成功

    RPA 人工智能等技术的蓬勃发展 催生了新的服务方式和流程运营方法 如何应用数字化技术转型升级 降本增效 提升核心竞争力 已成为国内企业的重要命题 眼下RPA行业火热 需求旺盛 但商业落地仍有待进一步加速 为此 来也科技举办了 UiBot百
  • 如何解决WIN11的EDGE浏览器页面的“嗯...无法访问此页面”,怎么办?记录一下

    解决网络连接不上的问题 方法概括 1 第一步 2 第二步 3 第三步 总步骤 方法概括 控制面板 网络和internet internet选项 连接 局域网设置 在 为LAN使用代理服务器 这一栏打上勾 最后点击确定退出即可 1 第一步 2
  • SourceTree解决冲突的三种情形

    SourceTree解决冲突的三种情形 解决冲突的时候 操作已暂存文件 不操作未暂存文件 开始的时候 这两个区域的文件是一样的 并且都带有感叹号提示 使用他人版本解决冲突 会自动将当前分支对应文档更改成他人文档内容 此时该文档从未暂存文件中
  • anaconda在虚拟环境中安装jupyter notebook

    目录 在虚拟环境中安装jupyter notebook 解决jupyter notebook中不存在虚拟环境的问题 修改jupyter notebook的启动路径 在虚拟环境中安装jupyter notebook 在安装anaconda的时
  • 黑马程序员node.js学习笔记

    1 初识 Node js 1 1 Node js 简介 Node js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境 Node js 的官网地址 https nodejs org zh cn 1 2 Node js
  • C语言中unsigned long long数据类型

    unsigned long long类型是目前C语言中精度最高的数据类型 可以用来表示20以内的阶乘数据 20以外的自测 还有是unsigned long long的精度64位 double或者long double 虽然也占有8个字节 但
  • java中子类可以继承父类的私有属性

    1 父类的私有属性可以被子类继承 父类的私有属性i1和i2 子类的对象中父类的私有属性i1和i2 2 子类虽然可以继承父类的私有属性 但是不能直接访问私有属性 除非父类开放了私有属性的访问接口
  • linux安装php-fpm,安装php(php-fpm)

    这里安装php7 2版本 首先到php官网下载安装包 下载到 usr local src 目录下 wget http jp2 php net get php 7 2 13 tar gz from this mirror 解压下载好的文件包
  • 地区查询python

    def file to dict area file 接收一个表示文件名的字符串为参数 将文件中的数据保存到字典中 返回字典 area in dict with open area file r encoding utf 8 as data
  • Failed to execute ‘createObjectURL‘ on ‘URL‘: Overload resolution failed.

    vue使用二进制流下载文件 使用 link href window URL createObjectURL blob 报错 Failed to execute createObjectURL on URL Overload resoluti
  • 关于分布式websocket踩的坑及解决方案

    关于websocket知识点 首先了解下websocket与http协议 1 WebSocket是HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议 使得客户端和服务器之间的数据交换变得更加简单 允许服务端主动向客户端推送
  • python绘制网络关系图

    import networkx as nx 数据准备 G nx DiGraph 单边有向图 G add edges from 1 2 x y 2 3 一次性添加多条边 nx draw G 简单画一下 改变样式 一次性画 pos nx spr
  • 安装eclipse出现Failed to load the JNIshared library---我的解决

    在安装eclipse时如果出现Failed to load the JNIshared library这句话 可能是你安装的eclipse的位数和JDK的位数不匹配 首先 我们来查看电脑JDK是多少位的 在搜索框 或windows R 中输
  • Python数据分析实战(2)使用Pandas进行数据分析

    文章目录 一 Pandas的使用 1 Pandas介绍 2 Pandas基本操作 Series的操作 创建DataFrame 常见列操作 常见行操作 DateFrame的基本操作 时间操作 3 Pandas进行数据分析 读取数据 选择数据子
  • 阿里云oss图片缩放

    您可以通过文件URL SDK API方式设置参数 处理图片 本文以文件URL为例进行介绍 关于如何使用SDK和REST API处理图片 请参见图片处理操作方式 本文示例使用的Bucket为杭州地域名为oss console img demo
  • 申请堆区空间

    malloc void malloc size t size 功能 申请 size 个字节的堆区空间 返回值 成功返回堆区空间首地址 失败返回 NULL free void free void ptr 功能 释放堆区空间 memset 对空
  • IPSec 专栏目录锦集(openswan)

    为了方便查阅现有的文章 特准备一个目录页供后续查询使用 专栏序言 1 IPsec理论知识 openswan任务调度基础知识之信号 IPSec协议详细介绍 pdf 一本书 IPSec技术理论介绍 pdf IBM手册 包括IKE协商commit
  • 图像型火灾探测系统

    图像型火灾探测系统是基于视频图像处理 人工智能处理分析 物联网通讯 大数据平台等先进技术实现的可视化早期 火灾探测报警系统 可探测物质燃烧产生的烟雾 火焰 温度等光谱特性 系统主要由图像型火焰火灾探测器 图像型线型 光束感烟火灾探测器 图像
  • hive 调优记录

    数据倾斜总结 在做Shuffle阶段的优化过程中 遇到了数据倾斜的问题 造成了对一些情况下优化效果不明显 主要是因为在Job完成后的所得到的Counters是整个Job的总和 优化是基于这些Counters得出的平均值 而由于数据倾斜的原因