当前位置: 首页 > news >正文

(12)Hive调优——count distinct去重优化

   离线数仓开发过程中经常会对数据去重后聚合统计,count distinct使得map端无法预聚合,容易引发reduce端长尾,以下是count distinct去重调优的几种方式。

解决方案一:group by 替代

原sql 如下:

#=====7日、14日的app点击的用户数(user_id去重统计)
selectgroup_id,app_id,
-- 7日内UVcount(distinct case when dt >= '${7d_before}' then user_id else null end)  as 7d_uv, 
--14日内UVcount(distinct case when dt >= '${14d_before}' then user_id else null end) as 14d_uv 
from tbl
where dt >= '${14d_before}'
group by group_id, --渠道app_id;  --app

优化思路:group by两阶段聚合

#=====7日、14日的app点击的用户数(user_id去重统计)
selectgroup_id,app_id,
-- 7日内UVsum(case when 7d_cnt > 0 then 1 else 0 end) as 7d_uv,
--14日内UVsum(case when 14d_uv > 0 then 1 else 0 end) as 14d_uvfrom (selectgroup_id,app_id,-- 7日内各渠道各app下的每个用户的点击量count(case when dt >= '${7d_before}' then user_id else null end)  as 7d_cnt,-- 14日内各渠道各app下的每个用户点击量count(case when dt >= '${14d_before}' then user_id else null end) as 14d_uvfrom tblwhere dt >= '${14d_before}'group by group_id,app_id,user_id) tmp1
group by group_id,app_id;

方案一弊端:数据倾斜风险

  解决方案一通过两阶段group by(分组聚合) 对count (distinct) 进行改造调优,需要注意的是:如果分组字段user_id在tbl 表中存在大量的重复值,group by底层走shuffle,会有数据倾斜的风险,因此方案一还可以进一步优化。

解决方案二:group by调优

1)添加随机数,两阶段聚合(推荐

#===============优化前
insert overwrite table tblB partition (dt = '2022-10-19')
selectcookie_id,event_query,count(*)  as cnt
from tblA
where dt >= '20220718'and dt <= '20221019'and event_query is not null
group by cookie_id, event_query#===============优化后
insert overwrite table tblB partition (dt = '2022-10-19')
selectsplit(tkey, '_')[1] as cookie_id,event_query,#--- 求出最终的聚合值sum(cnt)   as cnt
from (selectconcat_ws('_', cast(ceiling(rand() * 99) as string), cookie_id) as tkey,event_query,#---将热点Key值:cookie_id 进行打散后,先局部聚合得到cntcount(*)  as cntfrom tblAwhere dt >= '20220718'and dt <= '20221019'and event_query is not null#--- 第一阶段:添加[0-99]随机整数,将热点Key值:cookie_id 进行打散( M -->R)group by concat_ws('_', cast(ceiling(rand() * 99) as string), cookie_id),event_query) temp#--- 第二阶段:对拼接的key值进行切分,还原原本的key值split(tkey, '_')[1] =cookie_id ( R -->R)
group by split(tkey, '_')[1], event_que

 优化思路为:

  •   第一阶段:对需要聚合的Key值添加随机后缀进行打散,基于加工后的key值进行初步聚合(M-->R1)
  •   第二阶段:对加工后的key值进行切分还原,对第一阶段的聚合值进行再次聚合,求出最终结果值(R1-->R2)

2)开启Map端聚合

#--开启Map端聚合,默认为true
set hive.map.aggr = true;
#--在Map 端预先聚合操作的条数
set hive.groupby.mapaggr.checkinterval = 100000;

    该参数可以将顶层的聚合操作放在 Map 阶段执行,从而减轻shuffle清洗阶段的数据传输和 Reduce阶段的执行时间,提升总体性能。

3)数据倾斜时自动负载均衡

#---有数据倾斜的时候自动负载均衡(默认是 false)
set hive.groupby.skewindata = true;

  开启该参数后,当前程序会自动通过两个MapReduce来运行,将M->R阶段 拆解成 M->R->R阶段

  • 第一个MapReduce自动进行随机分布到Reducer中(负载均衡),每个Reducer做部分聚合操作,输出结果
  • 第二个MapReduce将上一步聚合的结果再按照业务(group by key)进行处理,保障相同的key分发到同一个reduce做最终聚合。

相关文章:

  • P5732 【深基5.习7】杨辉三角 python解法
  • 自动化测试:电商管理系统元素定位练习​
  • pubg开启之路
  • 防火墙 (iptables)------------------------SNAT与DNAT
  • ADC--模拟量转换成数字量
  • Compose 自定义 - 数据转UI的三阶段(组合、布局、绘制)
  • Mongodb 文本检索
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • html从零开始8:css3新特性、动画、媒体查询、雪碧图、字体图标【搬代码】
  • 【C语言】指针练习篇(下),深入理解指针---指针练习题【图文讲解,详细解答】
  • Python循环语句——for循环的嵌套使用
  • Java学习第十六节之创建对象内存分析和小结类与对象
  • Java实现停车场收费系统 JAVA+Vue+SpringBoot+MySQL
  • Godot 游戏引擎个人评价和2024年规划(无代码)
  • QtApplets-线程池
  • 002-读书笔记-JavaScript高级程序设计 在HTML中使用JavaScript
  • Angularjs之国际化
  • Java比较器对数组,集合排序
  • spring boot下thymeleaf全局静态变量配置
  • Vue ES6 Jade Scss Webpack Gulp
  • 彻底搞懂浏览器Event-loop
  • 初识MongoDB分片
  • 电商搜索引擎的架构设计和性能优化
  • 对象管理器(defineProperty)学习笔记
  • 面试遇到的一些题
  • 7行Python代码的人脸识别
  • Spark2.4.0源码分析之WorldCount 默认shuffling并行度为200(九) ...
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • ​软考-高级-系统架构设计师教程(清华第2版)【第20章 系统架构设计师论文写作要点(P717~728)-思维导图】​
  • $(function(){})与(function($){....})(jQuery)的区别
  • $HTTP_POST_VARS['']和$_POST['']的区别
  • (1)(1.19) TeraRanger One/EVO测距仪
  • (12)Linux 常见的三种进程状态
  • (33)STM32——485实验笔记
  • (pojstep1.3.1)1017(构造法模拟)
  • (备忘)Java Map 遍历
  • (博弈 sg入门)kiki's game -- hdu -- 2147
  • (第61天)多租户架构(CDB/PDB)
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)拼包函数及网络封包的异常处理(含代码)
  • **PHP二维数组遍历时同时赋值
  • ./mysql.server: 没有那个文件或目录_Linux下安装MySQL出现“ls: /var/lib/mysql/*.pid: 没有那个文件或目录”...
  • .NET delegate 委托 、 Event 事件
  • .net 简单实现MD5
  • .net连接oracle数据库
  • @Autowired自动装配
  • [Asp.net mvc]国际化
  • [AutoSar]BSW_OS 01 priority ceiling protocol(PCP)
  • [BUUCTF]-Reverse:reverse3解析
  • [codevs 1288] 埃及分数 [IDdfs 迭代加深搜索 ]
  • [Electron]ipcMain.on和ipcMain.handle的区别
  • [ESP32] 编码旋钮驱动
  • [HJ56 完全数计算]
  • [IE编程] 如何在IE8 下调试BHO控件/工具栏(调试Tab进程)