1. 前言
在离线数据研发中,随着业务的疾速倒退以及业务复杂度的一直进步,数据量的一直增长,尤其得物这种业务的高速增长,必然带来数据逻辑复杂度的晋升,数据量越大,复杂度越高,对工作的性能的要求就越高,因而,工作性能的优化就成了大家必然的话题,在离线数仓招聘中,这简直成了必考题目。
大数据畛域,为了进步超大数据量的计算性能,几代人一直在致力,一直榨取着计算机的 CPU、内存、磁盘每一个模块的性能,从晚期的纵向扩大(晋升计算机性能,如 IBM、ORACLE 晚期推崇的服务器到小型机到大型机的演进)到目前的大规模横向扩大(分布式集群模式),都是旨在晋升大数据的性能。
本文重点从在分布式计算模式下,如何来优化工作,大家耳熟能详的常见优化如:mapjoin skewjoin distribute by 等就不多做赘述,本文次要摸索技巧、策略及办法。
2. 工作优化策略
2.1 优化方向
补充阐明:目前得物大数据在阿里云的 dataworks 环境下,集群层面做了比拟多的工作,IO、网络、机架感应等临时无需过多关注,如有自建集群时,可重点关注,咱们重点关注 JOIN 和 REDUCE 层面,优化细节也重点基于这两个方向做细节开展。
2.2 优化伎俩
对于优化伎俩优化办法,咱们大多数习惯性从技术手段登程,更多的从算子、逻辑兼容等来解决,然而在某些业务场景下,如埋点日志, 数据量个别比拟大,这种状况无论技术手段如何干涉,都无奈解决存储和计算带来的资源耗费,这时候如果要晋升 SLA,就得从业务场景登程,做好业务的分类分级以及外围数据分流,因而,本文的优化伎俩会从技术手段和业务伎俩两方面开展。
- 技术手段
聚焦于技术手段来解决工作,加入上述单点工作优化方向,次要是 SQL 逻辑、模型标准、算子优化及可能存在的集群优化
- 业务伎俩
聚焦于业务个性、业务逻辑来进行解决,基于不同的业务个性及重要水平,从生产、采集、模型、数据生产全链路进行梳理和架构优化,同时造成一套数据链路上的告诉及束缚机制,防止上游变更带来的上游数据故障及复原问题。
3. 优化实际案例
优化策略中,定义好优化方向、优化伎俩,接下来,咱们选取一些比拟无效的积淀进去的计划,开展讲讲如何来做工作优化。
前文讲述,目前的得物的数据平台个性(dataworks),咱们在 IO、网络、RPC 通信机制等临时涉入不深,且对于面向业务的数据研发来言,大部分人不会过多关注底层的实现原理,暂不做过多深入探讨。
咱们基于下面方向中的技术手段讲述几个日常常见的优化案例
3.1 数据重散发(Distribute &Rand)
3.1.1 数据重散发的要点
日常数据研发中,最常见的且应用较多的就是数据歪斜或数据量带来的数据重散发(打散或随机),对于数据的重散发,次要分以下几点:
- 优化小文件
- 数据歪斜
- 排序 & 随机
小文件过多带来的 MAP 端资源损耗和数据歪斜是咱们日常开发过程中最为常见的性能问题,而这两点大多跟 rand()随机数有肯定的关系,通过数据散发和打散和躲避掉大部分此场景下的问题。
数据重散发个别代码操作如下所示
select c1,c2... from tablename distribute by c1[,...]
select c1,c2... from tablename distribute by rand([,seed])[,...]
对于 rand() 咱们要留神几点,可让咱们在优化工作时,知其然,更知其所以然。
- rand() 随机数的生成法则跟数学概率有莫大的关系,尤其在算法中,会被经常性问到,给定随机生成的 N 个数,结构等概率事件的发生器,跑题了,持续说回在 hive 或 odps 场景下,rand() 函数是随机生成的 0 -1 的 double 类型的数字。
- rand(int seed) 函数能够依据种子参数,结构一个稳固的随机值,加上种子参数,失去的后果是绝对稳固的,尤其在解决小文件过程中,这一步很重要。
- Hive 和 odps 场景中,随机函数多与 pmod()、mod()、floor()、ceil() 等函数联合应用,能够依据不同的业务场景,来结构任意范畴内的随机整数,比方在解决数据重散发解决数据歪斜的问题时,同时放心影响这种重散发带来过多的小文件,随机数能够这样来取 floor(rand())*N/ceil(rand())+1, 取 1 -N 之间的整数。
比方在流量数据外面,因为大量空值时,联合 rand 函数,解决数据歪斜问题:
select *
from a
left join b on a.order_id = nvl(b.order_id ,concat('hive',rand()))
-- b 中的 order_id 存在大量空值 的时候
3.1.2 数据重散发的作用
对于数据重散发,咱们次要是用来对解决数据后果进行小文件合并以及对数据处理中的歪斜问题进行优化。在大多数的解决中,咱们习惯于应用 Distribute by Rand() *N 的形式,其实这个形式可能存在问题,在解决相似问题时候,咱们能够抉择基于 seed 种子的 Rand 函数,来维持随机数的稳定性。这里须要通晓,distribute by 实际上做了一次 shuffle 的散发,默认是依照给定 key 进行的 hash 操作(能够了解为一次 repartion 从新分区),这外面是能够进行定制分区逻辑的,能够通过重写 hive 当中 partition 的接口,实现不同策略的重散发。
- 解决小文件合并
应用形式一:指定固定散发列,做一次 shuffle 的 merge 操作,DEMO 如下:
SELECT column1, column2,column.... FROM TABLEX WHERE ds = '${bizdate}'DISTRIBUTE BY '${bizdate}',columns1....
应用形式二:指定给定的文件数, 这里要用到 rand()函数了,个别有两种写法:第一种写法(上文探讨过,这种写法在肯定状况下会呈现数据问题):
SELECT column1, column2,column.... FROM TABLEX WHERE ds = '${bizdate}'DISTRIBUTE BY FLOOR(RAND()*N)/CEIL(RAND()*N)
第二种写法(加随机种子,产生稳固的随机序列):
SELECT column1,column2,column.... FROM (SELECT column1, column2,column...., FLOOR(RAND(seed)*N) AS rep_partion FROM TABLEX WHERE ds = '${bizdate}')DISTRIBUTE BY rep_partion
- 解决 JOIN 中的歪斜: 与上述逻辑同理,次要是借助一次散发,使得须要 shuffle 的数据能在一个节点进行数据处理。
3.2 数据收缩(Explode)
在 join 过程中,咱们之前提到了一种基于 BLOOMFILTER 算法的优化办法。在某些状况下,当 join 的表中呈现一个表的量级很大,另外一个表无奈 mapjoin 切热键 key 在概率分布上出现随机性,这个时候就能够在肯定水平上,对较小表中的 join key 进行肯定水平的收缩,因为 join 的产生是在 reduce 阶段,因而能够结构出稳固的多条主键,在不同的 reduce 中对数据进行 jion 操作,进而肯定水平上解决 join 歪斜带来的问题。基本原理如下图所示:
一个小例子,当研发应用数组模式存储数据 (sku_ids) 时,数仓想要拿到数组中每一个 sku_id,应用 lateral view EXPLODE。代码如下:
select order_id
from a
lateral view explode(split(order_ids,',')) v1 as order_id
group by order_id
后果展现:
order_ids order_id
101,102,103 101
101,102,103 102
101,102,103 103
104,105 104
104,105 105
目前,收缩函数曾经有开发进去有现成的 UDTF 函数来反对,能够撑持任意收缩量级的数据进行收缩。只须要结构收缩区间对应的随机函数即可,还是须要用到 Rand()函数来实现。
数据收缩形式带来的问题:
在解决了数据歪斜从新打散的问题之后,在计算层面会减少肯定的数据计算量。此外,如果能基于分桶进行二次索引分片,也能够在引擎侧思考基于该方向的自适应歪斜优化。
3.3 数据分桶(Bucket)
在数据量比拟大的状况下,单表数据做分区会存在上游应用效率上的限度,而数据在某些列上(或者结构业务列)存在高度汇集,或者存在能够优化晋升的微小空间,在此时,咱们就能够对列进行散列分桶,在分区的根底上进行桶表的设计,桶上能够对应索引向量,将极大的晋升数据应用上的效率。
在数据随机抽样、JOIN 场景中,也会极大的晋升整个数据的计算性能和效率。在 hive 中,该性能默认是敞开的,须要 set hive.enforce.bucketing=true 关上反对,odps 下可能无需特地关注,须要留神一般而言,桶的个数将与一次作业中对应的 reduce 数量统一。
其实,基于分桶的逻辑,在引擎侧能够做更多的优化(比方引擎侧能够优化分桶存储的策略)。在 join 中,依据索引进行 join 层面的动静优化,在超大数据 join 过程中,基于桶进行单位数据的本地优化等等都是能够做十分多的优化操作的,因为在目前的业务场景中,较少用到数据分桶,因而这里不做更深刻的拓展,具体的能够自行百度,查看对于桶表的应用,更进一步,正当分桶,加上排序后的索引,能高效优化单表查问应用的效率。
3.4 并发与并行管制
在计算机入门的时候,咱们就常常听到并发与并行,线程与过程等概念。而在数据研发中,咱们发现,其实对于整个作业来说,同样遵循相似的调优规定。个别的,一个作业最大的 map 数是 9999,reduce 数最大是 1000。尽管能够进步单个工作吞吐量,然而会耗费更长的工夫和资源调度上的期待。另一方面,当实现一个同类作业,往往须要多个工作进行,如果工作上面能够多个作业并行处理,单个作业也可能并发执行,那么就可能更大程度地榨取整个集群的资源,从而达到冲破计算瓶颈和上线的目标。目前在开源 HADOOP 体系中,咱们没有脚本模式来反对灵便的工作主动调配和调度,然而能够采纳 SHELL/PYTHON 脚本 +SQL 的形式来实现这一目标,其实借助猛犸调度在肯定范畴内也能达到同样的成果。
3.5 多路输入与物化(Read Once Output More)
这个局部咱们次要谈谈 HIVE(spark)的 CTE 写法(WITH…AS…)以及 From 语法的利用。这两个语法,在日常开发略微简单的工作时候,能够大大清晰整个简单 SQL 的逻辑,同时,在多路读写中,通过物化的形式还能在肯定水平上减速作业的运行。
- CTE(with…. as …)应用
-
- 根本应用非常简单,cte 的语法次要是为了进步代码的可读性,尽管在整个性能的优化上未必达到很好的成果,然而在肯定水平上,能大大提高工作的逻辑清晰度。很多时候,咱们在多个逻辑过程中,通过长期表的形式进行工作的串行,应用 with…as… 能达到相似的成果。同时 with…as… 能够深层嵌套,因而是比拟好的一种抉择形式。无论是线上工作还是视图,都能够应用 CTE 的写法——目前比拟遗憾的是 HIVE 的 CTE 目前不反对递归。
代码示例(能够应用多个 with, 抽出代码片段):
with a as (
select * from test1
where xxx = xxx
)
,
b as (select * from a)
select * from b limit 100;
- 物化设置
因为 with…as… 等同于一个 SQL 片段,下文中会屡次援用该片段的别名,相当于视图的滋味。所以,这外面应用是一个虚构的概念,实际上只是逻辑失效,理论运行是则是翻译成理论的 MR 逻辑去执行,如果上游援用该 SQL 片段较多,这时候 MR 执行会屡次扫描原始数据,执行屡次雷同的 MR 操作逻辑, 此时,就能够在第一次执行中来物化 CTE 写法中定义的 SQL 片段, 从而达到优化的目标。在 hive 之前的版本中,该性能是默认敞开的,能够通过上面参数来开启, 在新的 hive 版本中,该性能是默认开启, 然而默认援用次数是 3 次。
社区版 hive 如下所示,咱们的 ODPS 下,大家无需太多关注,这部分做技术扩大和理解即可。
- FROM 应用(一读多写)
-
- FROM 也是自己在理论研发中遇到多路输入时采纳比拟多的一种伎俩之一。当有多个不同的分区,或者多个不同的指标输入,或者有多个不同的子逻辑的过程中,能够将主逻辑全副开发实现,而后再进行多路输入。多路输入操作的应用限度如下:
- 单条 multi insert 语句中最多能够写 255 路输入。超过 255 路,会上报语法错误。
- 单条 multi insert 语句中,对于分区表,同一个指标分区不容许呈现屡次。
- 单条 multi insert 语句中,对于非分区表,该表不能呈现屡次。
比方在流量业务场景时,须要写动静分区,就能够应用 from,一个代码小例子:
from (select aa,bb,pt,sec_pt from test)
insert OVERWRITE table du_temp.temp_01 partition (pt = 'xx',sec_pt = 'test1')
select aa,bb where sec_pt = 'test1'
insert OVERWRITE table du_temp.temp_01 partition (pt = 'xx',sec_pt = 'test2')
select aa,bb where sec_pt = 'test2'
4. 思考 & 总结
在数据研发畛域,数据的技术手段无论如许丰盛,平台倒退何等欠缺,都不能说能解决业务的所有问题。肯定是先有业务,才会有对应的问题。在面对大数据量,高时效性,高简单计算的场景,咱们须要联合业务的个性,模型的革新,链路的设计,甚至打破常规等形式来产出不同的计划。在另一个方面,数据研发的工作也远远不是单点问题的解决和兜底,相同须要各方的配合与独特的智慧。
文:renren
线下流动举荐:
工夫: 2023 年 6 月 10 日(周六)14:00-18:00主题: 得物技术沙龙总第 18 期 - 无线技术第 4 期 地点: 杭州·西湖区学院路 77 号得物杭州研发核心 12 楼培训教室(地铁 10 号线 &19 号线文三路站 G 口出)
流动亮点: 本次无线沙龙聚焦于最新的技术趋势和实际,将在杭州 / 线上为你带来四个令人期待的演讲话题,包含:《抖音创作工具 -iOS 功耗监控与优化》、《得物隐衷合规平台建设实际》、《网易云音乐 - 客户端大流量流动的日常化保障计划实际》、《得物 Android 编译优化》。置信这些话题将对你的工作和学习有所帮忙,咱们期待着与你独特探讨这些令人兴奋的技术内容!
点击报名: 无线沙龙报名
本文属得物技术原创,来源于:得物技术官网
未经得物技术许可严禁转载,否则依法追究法律责任!