数仓治理-计算资源治理

注:文章参考:

数据治理实践 | 网易某业务线的计算资源治理从计算资源治理实践出发,带大家清楚认识计算资源治理到底该如何进行,并如何应用到其他项目中icon-default.png?t=N7T8https://mp.weixin.qq.com/s/w6d5zhDaaavNhW_DMEkPsQ

目录

一、计算资源治理的背景

二、计算资源问题复盘

三、计算资源治理前的思考与行动

3.1 治理前的思考

3.2 治理行动

四、治理效果

 五、小结

前言

    业务成熟期,数仓经常会收到集群资源满载、任务产出延时等消息/邮件,有时候下游数分及其他周边部门也会询问任务运行慢的原因。遇到这类问题,第一想到的是加资源解决,但有些情景,任务运行慢的原因不一定是缺少资源,而是需要优化当前的问题任务。本文章阐述计算资源治理的实施内容。

一、计算资源治理的背景

  • 运行时长过长、资源消耗大

        问题代码运行时产生了数据倾斜,大量相同key的数据会被发往同一个reduce,进而导致该reduce所需的时间远超过其他reduce,成为整个任务的瓶颈。

  • 任务调度时间规划不合理,部分时间段资源消耗较高任务(集群资源打满)

        大量的任务堆积在凌晨xx点执行,核心任务和非核心任务没有做资源级别划分,数据产出延迟被业务方投诉。

  • 存在空跑任务/未引用模型对应任务/无效监控任务

二、计算资源问题复盘

       在做计算治理之前,团队内部盘点了当前计算资源存在的问题(重灾区):

    (1)30+高消耗任务(任务执行时间过长):由于前中期业务扩张,数仓要覆盖下游大量的场景应用,为快速响应需求,开发代码后未经审核就上线,故数仓存在较多问题代码,这些代码运行时可能会发生数据倾斜,消耗大量的资源,最终产出时间很久。

   (2)任务调度安排的不合理:多数任务堆积在凌晨2-5点执行,该区间CPU满载(内存空闲,但是CPU爆满),导致该时间段的资源消耗变成了重灾区,所有核心/非核心任务都在争抢资源,部分核心任务不能按时产出,一直处于等待阶段;

   (3)线上无效DQC&监控配置的资源过少:存在空跑无意义的DQC浪费资源的情况、有些DQC分配的资源过少,导致任务运行时间过长;

        ps:数据质量监控DQC:线上任务执行后会触发对应的DQC规则,DQC分为基础DQC(ods  -> dwd -> dws ->ads每一层都要配置,对核心表/字段进行监控)和业务dqc(ads层配置)

   (4)存在模型未被引用的任务/无效监控任务:早期为快速需求,数仓开发了很多烟囱式数据模型、因为业务迭代或业务下线等,部分模型不再被引用,无用的烟囱模型会带来额外的计算资源开销。

   (5)任务缺少调优参数& 计算引擎为mr/spark2:任务缺少调优参数导致资源无法弹性伸缩,以适配任务进行动态调整。有些线上任务仍然使用mr/spark2计算引擎,导致运行效率很低,产出延迟。

三、计算资源治理前的思考与行动

3.1 治理前的思考

         经过与团队多次沟通,对当前计算资源治理的优先级、改动成本、治理难度、对下游的影响等因素综合评估后,得出治理的顺序可以是:参数调优&任务引擎切换 --> DQC治理-->高消耗任务治理--> 调度安排 --> 下线无用模型 --> 沉淀公共指标

3.2 治理行动

      (1)添加调优参数&计算引擎切换至Spark3

             参数层面例如: set spark.sql.adaptive.enabled=true; 该参数代表:是否开启调整partition功能,如果开启,spark.sql.shuffle.partitions设置的partition可能会被合并到一个reducer里运行,该参数能更好利用的单个executor的性能,还能缓解小文件问题。平台默认是开启的。

          任务执行引擎统一从mr/spark2切换至Spark3进行加速。

  •       (2)DQC治理

                  无效DQC下线:查看DQC任务是否与线上任务一一匹配,将无效DQC任务下线。

                 DQC分配的计算资源调整:由于之前DQC配置资源为集群默认参数,效率极低导致所有DQC运行时长均超过10min。之后调整Driver内存为2048M,Executor个数为2,Executor内存为4096M。

             DQC数量缩减:线上的基础DQC只需要对核心字段进行配置就OK,无关的DQC在不影响下游报表的前提下直接下线处理。

     (3)高消耗任务调优(怎么去优化任务?数据倾斜该怎么调优?)

               高消耗任务:例如:资源消耗连续7天排行前10。调优存在两个难点:1.优化效果不可控;2.高消耗任务调整到何种程度算合适(调优上限不可知)。针对这些难点,我们取所有核心任务的耗时均值,保障单个任务消耗小于平均消耗。此外,我们针对当前高消耗任务列举出以下的优化方案:

  • 参数层面
set hive.auto.convert.join = true; -->是否自动转化成Map Join
set hive.groupby.skewindata=true; --> 当数据出现倾斜时,如果该变量设置为true,hive会自动进行负载均衡
set hive.map.aggr=true; -->是否在map端进行聚合,默认为true;

  • map阶段
1.剪裁列和剪裁行
  剪裁列:select * from tableA 转换成 select column1 , column2 from tableA;
  剪裁行:分区限制,where时间及条件限制,减少非必要的数据输入
          select column1 , column2 from tableA; 转换成
          select column1 , column2 from tableA where ds ='${lst1date}' and xxx > yyy;
2.distribute by  rand(): 
  代码结尾添加distribute by rand(),控制map输出结果的分发,即map端如何拆分数据给reduce端;
  当distribute by 后边定义的列是rand()时,默认采用hash算法,根据reduce个数进行数据分发,保障每 
  个分区的数据基本一致。
  • reduce阶段
1.笛卡尔积优化
  多对多关联发生数据膨胀,很可能出现笛卡尔积,根据实际业务,尽量避免
2.sql语句中distinct切换成group by
3.map join :大表join小表
   map join 会把小表全部加载到内存中,在map阶段直接拿另外一个表的数据和内存中表的数据做匹配关联,由于在map阶段已经进行了join操作,省去reduce阶段,任务整体运行的效率会提升很多。

4.大key重组计算(key字段出现空值或单个reduce中的key很多,热点key)   
4.1 column1存在空值
  select 
       column1,
       sum(column2) as  column2_amt
  from tableA
  where column1 is not null
  group by column1;
-----------------------------------------
  select 
       ifnull(column1,name) as column1_name,
       sum(column2) as  column2_amt
  from tableA
  group by column1;
------------------------------------------
4.2 column1 数据很多(column1是热点key)
 方式一:分段,分而治之
  select 
       column1,
       sum(column2) as  column2_amt
  from tableA
  where ds = '${lst1date}' and column1 <> 'c'
  group by column1;
  union all
  select 
       column1,
       sum(column2) as  column2_amt
  from tableA
  where ds = '${lst1date}'and column1 = 'c'
  group by column1;

 方式二:对热点key加盐打散后再分组聚合
 select 
     split_part(column1_rn,'_',1) as column1,
	 sum(column2_amt) as column2_amt
from (select column1_ct,
            sum(column2) as column2_amt
      from(select 
                concat(column1,'_',floor(rand()*N)) as column1_rn,
                sum(column2) as  column2_amt
          from tableA
          where ds = '${lst1date}') t1
       group by column1_rn)t2
group by split_part(column1_rn,'_',1)
-- rand()*N 生成0~N的随机数,floor下向取整

5.过滤逻辑尽可能在子查询中就处理好(t0大表 join 中表t1)
SELECT t0.column1,
       tmp.column2_amt
from  t0
left join (select 
                  column1,
                  sum(column2_amt) as column2_amt
           from t1
           where ds = '${lst1date}'
            group by column1) tmp
on t0.column1= tmp.column1
  • 其他层面
spark aqe特性
1.aqe是spark sql的一种动态优化机制,是针对查询执行计划的优化;
2.aqe工作原理:当查询任务提交后,shuffle过程会将任务划分为多个查询阶段。在执行过程中,上一个查询执行完之后,系统会将查询结果保存下来,下一个查询就可以基于上一个查询的结果继续进行计算了;
3.引入aqe机制后,spark可以在任务运行过程中实时统计任务的执行情况,并通过自适应计划将统计结果反馈给优化器,从而对任务再次进行优化,这种边执行、边优化的方式极大提高了sQL的执行效率。
数据倾斜:通常是指参与计算的数据分布不均,即某个key或者某些key的数据量远超其他key,导致在shuffle阶段,大量相同的key的数据会被发往同一个reduce,进而导致该reduce所需的时间远超过其他reduce,成为整个任务的瓶颈。

     (5)任务调度时间合理规划

              将堆积在凌晨2-5点的600+任务进行梳理,由于任务间错综复杂的依赖关系,修改后可能会级联影响下游报表,因此按照以下步骤逐步实施:

  • 找到所有表的输出输入点,即起始ODS,末尾ADS;
  • 划分核心表/非核心表,整理对应的任务开始时间与结束时间;
  • 划分核心任务/非核心任务,设置任务执行的优先级,将非核心的任务调度延后;
  • 把非核心任务穿插在集群资源的低峰时期运行(2点前,5点后),把核心任务调度提前,保障CDM层(dwd明细层、dws汇总数据层)任务及时产出;
  • 梳理部分时间段资源消耗较高的任务,提前/延后该任务的调度时间,保障资源合理分配; 

    (6)烟囱任务下沉&无用任务下线

            对于烟囱任务,可以将公共指标下沉到到DWS以提高复用性;无用任务/无效监控项任务及时下线(这里建议能拿到报表层级的数据血缘,防止任务下线后影响下游报表的数据呈现),降低资源损耗。

四、治理效果

         计算资源治理后的可量化指标如下(举例):

      (1)将Hive与Spark2任务升级至Spark3,总计升级任务xxx个,升级后任务执行效率提升xx%,cpu资源消耗降低xx%,内存资源消耗降低xx%。

      (2)下线无效DQC任务总计50+,调整DQC运行资源,治理后时长由10min优化至3min内。

      (3)完成线上x+任务优化,x+任务下线,x+表的指标下沉,节省任务耗时xxx分钟。

      (4)任务调度重新分配后,凌晨2-5点的资源使用率由90%降低至50%+,日用资源的趋势图没有大幅度的波动。

      (5)整体治理后为部门减少1/3费用,由原来的xx万元降低至xx万元。

 五、小结

       计算资源治理的核心在于降本增效,用有限资源去运行更多任务。计算资源治理是一项长期工程,不能等到集群资源紧张才去治理优化,而是将计算资源治理的意识贯彻到日常开发中。可通过周/月的资源扫描内容及时推送给数仓部门,让每个任务都有源可循,有方案可优化。

       待补充~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

代码随想录算法训练营第15天| Leetcode 104.二叉树的最大深度、559.n叉树的最大深度、111.二叉树的最小深度、222.完全二叉树的节点个数

目录 Leetcode 104.二叉树的最大深度 Leetcode 559.n叉树的最大深度 Leetcode 111.二叉树的最小深度 Leetcode 222.完全二叉树的节点个数 Leetcode 104.二叉树的最大深度 题目链接&#xff1a;Leetcode 104.二叉树的最大深度 题目描述&#xff1a;给定一个二叉树&#xff0c;…

【驱动系列】C#获取电脑硬件显卡核心代号信息

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是《驱动系列》文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点…

Python笔记12-多线程、网络编程、正则表达式

文章目录 多线程网络编程正则表达式 多线程 现代操作系统比如Mac OS X&#xff0c;UNIX&#xff0c;Linux&#xff0c;Windows等&#xff0c;都是支持“多任务”的操作系统。 进程&#xff1a; 就是一个程序&#xff0c;运行在系统之上&#xff0c;那么便称之这个程序为一个运…

Linux进程间通信(IPC)机制之一:管道(Pipes)详解

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;Nonsense—Sabrina Carpenter 0:50━━━━━━️&#x1f49f;──────── 2:43 &#x1f504; ◀️ ⏸ ▶️ …

关于session每次请求都会改变的问题

这几天在部署一个前后端分离的项目&#xff0c;使用docker进行部署&#xff0c;在本地测试没有一点问题没有&#xff0c;前脚刚把后端部署到服务器&#xff0c;后脚测试就出现了问题&#xff01;查看控制台报错提示跨域错误&#xff1f;但是对于静态资源请求&#xff0c;包括登…

数据结构.线性表

1.静态分配 #include<iostream> using namespace std; const int N 10; typedef struct {int data[N];int length;}SqList; void InitList(SqList &L) {for (int i 0; i < N; i){L.data[i] 0;}L.length 0; }int main() {SqList L;InitList(L);return 0; }2.动…

2024年AI全景预测

欢迎来到 2024 年人工智能和技术的可能性之旅。 在这里&#xff0c;每一个预测都是一个潜在的窗口&#xff0c;通向充满创新、变革、更重要的是类似于 1950 年代工业革命的未来。 20 世纪 50 年代见证了数字计算的兴起&#xff0c;重塑了行业和社会规范。 如今&#xff0c;人工…

运行adprep /forestprep扩展Active Directory架构

运行 adprep /forestprep 是为了扩展Active Directory架构&#xff0c;以便为整个林添加新版本Windows Server所支持的新类、属性和其他目录对象。在升级到更高版本的Windows Server并提升林功能级别之前&#xff0c;通常需要执行此操作。 以下是详细步骤&#xff1a; 确认环境…

flask框架制作前端网页作为GUI

一、语法和原理 &#xff08;一&#xff09;、文件目录结构 需要注意的问题&#xff1a;启动文件命名必须是app.py。 一个典型的Flask应用通常包含以下几个基本文件和文件夹&#xff1a; app.py&#xff1a;应用的入口文件&#xff0c;包含了应用的初始化和配置。 requirem…

【C++入门到精通】特殊类的设计 |只能在堆 ( 栈 ) 上创建对象的类 |禁止拷贝和继承的类 [ C++入门 ]

阅读导航 引言一、特殊类 --- 不能被拷贝的类1. C98方式&#xff1a;2. C11方式&#xff1a; 二、特殊类 --- 只能在堆上创建对象的类三、特殊类 --- 只能在栈上创建对象的类四、特殊类 --- 不能被继承的类1. C98方式2. C11方法 总结温馨提示 引言 在面向对象编程中&#xff0…

Nginx与keepalived实现集群

提醒一下&#xff1a;下面实例讲解是在mac虚拟机里的Ubuntu系统演示的&#xff1b; Nginx与keepalived实现集群实现的效果 两台服务器都安装Nginx与keepalived&#xff1a; master服务器的ip(192.168.200.2) backup服务器的ip(192.168.200.4) 将 master服务器Nginx与keepalive…

【Mybatis的一二级缓存】

缓存是什么&#xff1f; 缓存其实就是存储在内存中的临时数据&#xff0c;这里的数据量会比较小&#xff0c;一般来说&#xff0c;服务器的内存也是有限的&#xff0c;不可能将所有的数据都放到服务器的内存里面&#xff0c;所以&#xff0c; 只会把关键数据放到缓存中&#x…

C# 命名管道NamedPipeServerStream使用

NamedPipeServerStream 是 .NET Framework 和 .NET Core 中提供的一个类&#xff0c;用于创建和操作命名管道的服务器端。命名管道是一种在同一台计算机上或不同计算机之间进行进程间通信的机制。 命名管道允许两个或多个进程通过共享的管道进行通信。其中一个进程充当服务器&…

RNN预测下一句文本简单示例

根据句子前半句的内容推理出后半部分的内容&#xff0c;这样的任务可以使用循环的方式来实现。 RNN&#xff08;Recurrent Neural Network&#xff0c;循环神经网络&#xff09;是一种用于处理序列数据的强大神经网络模型。与传统的前馈神经网络不同&#xff0c;RNN能够通过其…

独享http代理安全性是更高的吗?

不同于共享代理&#xff0c;独享代理IP为单一用户提供专用的IP&#xff0c;带来了一系列需要考虑的问题。今天我们就一起来看看独享代理IP的优势&#xff0c;到底在哪里。 我们得先来看看什么是代理IP。简单来说&#xff0c;代理服务器充当客户机和互联网之间的中间人。当你使用…

C/C++ - 面向对象编程

面向对象 面向过程编程&#xff1a; 数据和函数分离&#xff1a;在C语言中&#xff0c;数据和函数是分开定义和操作的。数据是通过全局变量或传递给函数的参数来传递的&#xff0c;函数则独立于数据。函数为主导&#xff1a;C语言以函数为主导&#xff0c;程序的执行流程由函数…

复式记账的概念特点和记账规则

目录 一. 复式记账法二. 借贷记账法三. 借贷记账法的记账规则四. 复试记账法应用举例4.1 三栏式账户举例4.2 T型账户记录举例4.3 记账规则验证举例 \quad 一. 复式记账法 \quad 复式记账法是指对于任何一笔经济业务都要用相等的金额&#xff0c;在两个或两个以上的有关账户中进…

GIT使用,看它就够了

一、目的 Git的熟练使用是一个加分项&#xff0c;本文将对常用的Git命令做一个基本介绍&#xff0c;看了本篇文章&#xff0c;再也不会因为不会使用git而被嘲笑了。 二、设置与配置 在第一次调用Git到日常的微调和参考&#xff0c;用得最多的就是config和help命令。 2.1 gi…

4核16G幻兽帕鲁服务器性能测评,真牛

腾讯云幻兽帕鲁服务器4核16G14M配置&#xff0c;14M公网带宽&#xff0c;限制2500GB月流量&#xff0c;系统盘为220GB SSD盘&#xff0c;优惠价格66元1个月&#xff0c;277元3个月&#xff0c;支持4到8个玩家畅玩&#xff0c;地域可选择上海/北京/成都/南京/广州&#xff0c;腾…

第十六章 Spring cloud stream应用

文章目录 前言1、stream设计思想2、编码常用的注解3、编码步骤3.1、添加依赖3.2、修改配置文件3.3、生产3.4、消费3.5、延迟队列3.5.1、修改配置文件3.5.2、生产端3.5.2、消息确认机制 消费端 前言 https://github.com/spring-cloud/spring-cloud-stream-binder-rabbit 官方定…