草庐IT

数据治理实践 | 网易某业务线的计算资源治理

语兴 2023-03-28 原文
​本文从计算资源治理实践出发,带大家清楚认识计算资源治理到底该如何进行,并如何应用到其他项目中。

01前言

由于数据治理层面可以分多个层面且内容繁多(包括模型合规、数据质量、数据安全、计算/存储资源、数据价值等治理内容),因此需要单独拆分为6个模块单独去阐述其中内容。

笔者作为数仓开发经常会收到大量集群资源满载、任务产出延时等消息/邮件,甚至下游数分及其他同学也会询问任务运行慢的情况,在这里很多数仓同学遇到这类问题第一想到的都是加资源解决,但事实真不一定是缺少资源,而是需要优化当前问题任务。所以本期从团队做计算资源治理视角出发,带大家清楚认识计算资源治理到底该如何进行。

02问题出现

在做计算治理之前(2022.12)我们团队盘点了下当前计算资源存在的几个问题:

(1)30+高消耗任务:由于数仓前中期业务扩张,要覆盖大量场景应用,存在大量问题代码运行时数据倾斜,在消耗大量集群计算资源下,产出时间也久;

(2)200w+的小文件:当前任务存在未合并小文件、任务Reduce数量过多、上游数据源接入(尤其是API数据接入)会造成过多小文件出现,小文件过多会开启更多数据读取,执行会浪费大量的资源,严重影响性能;

(3)任务调度安排不合理:多数任务集中在凌晨2-5点执行且该区间CPU满载,导致该时间段资源消耗成了重灾区,所有核心/非核心任务都在争抢资源,部分核心任务不能按时产出一直在等待阶段;

(4)线上无效DQC(数据质量监控)&监控配置资源过小:存在部分历史任务没下线表及DQC场景,每日都在空跑无意义DQC浪费资源,同时DQC资源过少导致DQC需要运行过长时间;

(5)重复开发任务/无用任务:早期协助下游做了较多烟囱数据模型,因为种种原因,部分任务不再被使用,烟囱模型分散加工导致资源复用率降低;

(6)任务缺少调优参数&部分任务仍然使用MapReduce/Spark2计算引擎:任务缺少调优参数导致资源不能适配及动态调整,甚至线上仍有早期配置MapReduce/Spark2计算引擎导致运行效率较低。

03思考与行动

3.1 治理前的思考:​

在治理之前我想到一个问题,切入点该从哪里开始最合适?

经过与团队多次脑暴对当前治理优先级/改动成本大小/难度做了一个排序,我们先选择从简单的参数调优&任务引擎切换开始->小文件治理->DQC治理->高消耗任务治理->调度安排->下线无用模型及沉淀指标到其他数据资产,同时在初期我们完成各类元数据接入搭建治理看板以及团队治理产出统计数据模型,并通过网易数帆提供的数据治理平台解决具体细节问题。

(数据治理平台截图)

3.2 治理行动:

(1)大部分任务切换至Spark3计算引擎&补充任务调优参数

补充Spark调优参数(参数内容详见文末),任务统一使用Spark3引擎加速,并充分利用Spark3的AQE特性及Z-Order排序算法特性。

AQE解释:Spark 社区在 DAG Scheduler 中,新增了一个 API 在支持提交单个 Map 阶段,以及在运行时修改 shuffle 分区数等等,而这些就是 AQE,在 Spark 运行时,每当一个 Shuffle、Map 阶段进行完毕,AQE 就会统计这个阶段的信息,并且基于规则进行动态调整并修正还未执行的任务逻辑计算与物理计划(在条件运行的情况下),使得 Spark 程序在接下来的运行过程中得到优化。

Z-Order解释:Z-Order 是一种可以将多维数据压缩到一维的技术,在时空索引以及图像方面使用较广,比如我们常用order by a,b,c 会面临索引覆盖的问题,Z-Order by a,b,c 效果对每个字段是对等的

(2)小文件治理

在这里我们使用内部数据治理平台-数据治理360对存在小文件较多表提供内容展示(本质采集HDFS对应路径下文件数的日志去显示)

当前小文件处理:

对于分区较多使用Spark3进行动态分区刷新,(Spark3具备小文件自动合并功能,如未使用Spark3可配置Spark3/Hive小文件合并参数刷新,参数详见文末),代码如下:

set hive.exec.dynamic.partition.mode=nonstrict;
insert overwrite table xxx.xxx partition (ds)
select column
,ds
from xxx.xxx
对于分区较少或未分区的表采用重建表,补数据方法回刷。

小文件预防:

  • 使用Spark3引擎,自动合并小文件
  • 减少Reduce的数量(可以使用参数进行控制)
  • 用Distribute By Rand控制分区中数据量
  • 添加合并小文件参数 
  • 将数据源抽取后的表做一个任务(本质也是回刷分区合并小文件任务)去处理小文件保障从数据源开始小文件不向下游流去
(3)DQC治理

无效DQC下线:难点在于需要查找所有DQC对应的线上任务,查看该DQC任务是否与线上任务一一匹配,从而找到无效DQC任务下线,内容繁杂耗时较多。

DQC资源:由于之前DQC配置资源为集群默认参数,效率极低导致所有DQC运行时长均超过10min,从而使得整体任务链路运行时长过久,调整Driver内存为2048M,Executor个数为2,Executor内存为4096M

(4)高消耗任务调优

这里存在2个难点:优化效果不可控、高消耗任务调整到何种程度算合适,针对这个这个难点我们取所有核心数据资产任务均值,保障单个任务消耗小于平均消耗,同时我们针对当前高消耗任务列举出如下可优化的方式:

  • 关联表过多,需拆分
  • 关联时一对多,数据膨胀
  • 资源配置过多,运行时资源严重浪费,需要将配置调小(包括Driver内存、Executor个数、Executor内存)
  • 代码结尾添加Distribute By Rand(),用来控制Map输出结果的分发
  • 查询中列和行未裁剪、分区未限定、Where条件未限定
  • SQL中Distinct切换为Group by(Distinct会被hive翻译成一个全局唯一Reduce任务来做去重操作,Group by则会被hive翻译成分组聚合运算,会有多个Reduce任务并行处理,每个Reduce对收到的一部分数据组,进行每组聚合(去重))
  • 关联后计算切换为子查询计算好后再关联
  • 使用Map Join(Map Join会把小表全部读入内存中,在Map阶段直接拿另外一个表的数据和内存中表数据做匹配,由于在Map是进行了Join操作,省去了Reduce运行的效率也会高很多)可用参数代替
(5)任务调度合理优化

对于调度优化一开始会无从下手,统计凌晨2-5点区间下大概600+任务难梳理,同时存在任务依赖,修改起来可能会对下游整体有大的影响,因此我们选择循序渐进先梳理再改善。

  • 找到所有表的输出输入点即启始ODS与末尾ADS
  • 划分其中核心表/非核心表,及对应任务开始时间与结束时间
  • 按照梳理内容把非核心的任务穿插在当前集群资源非高峰时期(2点前与5点后),同时把核心任务调度提前,保障CDM层任务及时产出
  • 对实践后内容再度调优,达到资源最大利用率
(6)烟囱任务下沉&无用任务下线

烟囱表过多,需下沉指标到DWS中提升复用性,对于无用任务也需要及时下线(这里需要拿到元数据血缘最好到报表层级的数据血缘,防止任务下线后导致可视化内容问题产生),减少开发资源消耗。

04治理效果

(1)Hive与Spark2任务升级Spark3.1,总计升级任务137个,升级任务后总体任务执行效率提升43%,cpu资源消耗降低41%,内存资源消耗降低46%

(2)治理小文件数大于10000+以上的数仓表总计30+张,小文件总数由216w下降至67w

(3)下线无效DQC任务总计50+,修改DQC配置资源降低运行时长,由原来10min优化至3min内

(4)完成线上20+个任务优化及10+个任务下线及10+表指标下沉,优化后节省任务耗时146分钟,减少CPU损耗800w+,降低内存消耗2600w+(相当于节省了8个200+字段1亿数据量任务消耗)

(5)调度重新分配后2-5点资源使用率由90+%降低至50+%,保障日用资源趋势图无大突刺波动

05小结

计算资源治理核心在于降本增效,用有限资源去运行更多任务,通过一系列治理操作也让数仓同学积累技术经验同时规范化自身开发标准,让治理反推进组内技术进步。

计算资源治理是一件长久之事,并不能因为资源紧张才去治理,而要将计算治理常态化,可通过周/月资源扫描内容及时推送给每个同学,并为之打分,让每个任务都有源可循,有方法可优化。

参数内容

参数并不是设置越多任务性能越好,根据数据量、消耗、运行时间进行调整达到合理效果。

Hive:

(1)set hive.auto.convert.join = true; (是否自动转化成Map Join)

(2)set hive.map.aggr=true; (用于控制负载均衡,顶层的聚合操作放在Map阶段执行,从而减轻清洗阶段数据传输和Reduce阶段的执行时间,提升总体性能,该设置会消耗更多的内存)

(3)set hive.groupby.skewindata=true; (用于控制负载均衡,当数据出现倾斜时,如果该变量设置为true,那么Hive会自动进行负载均衡)

(4)set hive.merge.mapfiles=true;  (用于hive引擎合并小文件使用)

(5)set mapreduce.map.memory.mb=4096;      (设置Map内存大小,解决Memory占用过大/小)

(6)set mapreduce.reduce.memory.mb=4096;(设置Reduce内存大小,解决Memory占用过大/小)

(7)set hive.exec.dynamic.partition.mode=nonstrict;(动态分区开启)

Spark:

(1)set spark.sql.legacy.parquet.datetimeRebaseModeInRead=LEGACY;(用于spark3中字段类型不匹配(例如datetime无法转换成date),消除sql中时间歧义,将Spark .sql. LEGACY . timeparserpolicy设置为LEGACY来恢复Spark 3.0之前的状态来转化)

(2)set spark.sql.adaptive.enabled=true;(是否开启调整Partition功能,如果开启,spark.sql.shuffle.partitions设置的Partition可能会被合并到一个Reducer里运行。平台默认开启,同时强烈建议开启。理由:更好利用单个Executor的性能,还能缓解小文件问题)

(3)set spark.sql.hive.convertInsertingPartitinotallow=false;(解决数据无法同步Impala问题,使用Spark3引擎必填)

(4)set spark.sql.finalStage.adaptive.advisoryPartitinotallow=2048M;(Spark小文件合并)​

有关数据治理实践 | 网易某业务线的计算资源治理的更多相关文章

  1. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  2. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  3. ruby-on-rails - 使用一系列等级计算字母等级 - 2

    这里是Ruby新手。完成一些练习后碰壁了。练习:计算一系列成绩的字母等级创建一个方法get_grade来接受测试分数数组。数组中的每个分数应介于0和100之间,其中100是最大分数。计算平均分并将字母等级作为字符串返回,即“A”、“B”、“C”、“D”、“E”或“F”。我一直返回错误:avg.rb:1:syntaxerror,unexpectedtLBRACK,expecting')'defget_grade([100,90,80])^avg.rb:1:syntaxerror,unexpected')',expecting$end这是我目前所拥有的。我想坚持使用下面的方法或.join,

  4. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

    当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

  5. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  6. ruby-on-rails - Rails 3,嵌套资源,没有路由匹配 [PUT] - 2

    我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle

  7. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  8. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  9. 叮咚买菜基于 Apache Doris 统一 OLAP 引擎的应用实践 - 2

    导读:随着叮咚买菜业务的发展,不同的业务场景对数据分析提出了不同的需求,他们希望引入一款实时OLAP数据库,构建一个灵活的多维实时查询和分析的平台,统一数据的接入和查询方案,解决各业务线对数据高效实时查询和精细化运营的需求。经过调研选型,最终引入ApacheDoris作为最终的OLAP分析引擎,Doris作为核心的OLAP引擎支持复杂地分析操作、提供多维的数据视图,在叮咚买菜数十个业务场景中广泛应用。作者|叮咚买菜资深数据工程师韩青叮咚买菜创立于2017年5月,是一家专注美好食物的创业公司。叮咚买菜专注吃的事业,为满足更多人“想吃什么”而努力,通过美好食材的供应、美好滋味的开发以及美食品牌的孵

  10. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

随机推荐