前言
写标题的时候是2021-07-04 22:22,在那之前我以前一直是想琢磨怎么去扯数仓优化这玩意好点,总是觉得应该来个万字长文啥的才写下来,现在不那样折腾了,想到啥就写点啥,大不了未来再多搞几篇就是了。
为啥数仓需要优化
这个问题其实在不同的人看是不一样的
人员 | 视角 |
高层领导 | 成本过高 |
业务 | 产出慢,无法支撑业务 |
bi | 乱七八糟的,不知道用啥表 |
开发人员 | 这玩意性能不行 |
数仓人员 | 一样的数据多套,关键还是错的 |
运维同学 | 这个配置不大对,改改会更快 |
这个问题其实是不同角色关注点不同,但是核心诉求都是简洁、高效、低能耗!!从不同视角我来扯一扯数仓的优化策略。
人员优化
人多力量大,人多路子野,其实这个是重中之重,一方面需要大量招人,一方面需要高手,不要吝啬钱财,事实上大数据的优化人员成本带来的收益绝对是划算的,这点不管任何时候都是需要引起重视的。
调度优化
我这里的调度优化主要是作业调度系统的优化,事实上,在hadoop不流行的时代,离线批量处理就一直是软件系统领域的重要一环,调度的需求也随着时代在发展,由原有的定时天调度,到后来的准实时,分钟,甚至的实时调度,一直在备受挑战着。更有甚者,包括处理线上漂移,财务日切等一系列的强业务的需求不断提出,传统的定时调度其实远远满足不了当下的需求了,当然常用的掉度优化也有几个:
高频作业准实时化
频繁调度容易带来的任务积压其实是比较严重的,常用的手段直接cache中间数据,采用一些类似sts数据常驻内存的手段,直接构造成准实时化的作业,加快效率。
作业优先定级
这个话题可能看起来比较简单,作业不都是有优先级么,事实上,作业是否真正需要高优先级是需要商榷的,所有的业务都会说自己的任务是高优先级,这种时候分不出谁才是大哥了。这里立足一点就是从调度层面去核实作业的优先情况,具体来说主要是以下的手段:
1.下游节点多的应当提前执行,一有资源就优先调度
2.高优先级、低消耗优先调度
3.高频作业按业务量降频
4.高延时高消耗作业延后
5.固定表剔除调度,例如固定维表,不需要调度
6.日切漂移节点统一根入口,不需要挂多个
正常状态下资源充足肯定没问题,调度的调整主要在高峰的时候,我们追求一个合理的状态,一般来说一个调度平台的作业都是上万甚至几十万的,必然所谓的高优先级很多,这种时候就需要去进行打标识别了,再进行优先分配。
作业健身
作业健身其实就是任务优化,用一些技术手段加快任务,这个话题其实很多都可以做,这里总结一些比较常见的手段:
历史数据分离
在大数据发展的过程,业务也是不断发展,在初期引入大数据的时候,大部分数据都是全量存储,一天一个快照的,积累了一定程度的时候,发现很多核心的表,数据都是全量扫描,消耗大量的资源。实际的业务其实就是关注一段时间,甚至一天的数据浪费大量的资源,只要找到时间条件,从在集团的公共数据层面做剥离,可以带来巨大的收益。
冷热数据分离
数据其实是访问频率不一样,尤其是出现的越来越高频的线上调度,这种时候带来大量资源消耗不说,而且容易造成rpc请求热点,整个集群都受影响;另一方面,大量数据抽取到集群中实际上很多数据很低频率访问的,这种时候我们按照hdfs 3倍5倍副本存储就不合适了,一般就是 高频读取数据Cache,或者用ssd等介质存储,低频的则走一个极限压缩就行。
谓词下推有效化等价汰换
谓词下推其实是引擎的一些手段,hive、spark、presto其实都有这类的操作,一方面我们可以直接获益。我们的优化目的是为了更加完善。首先,我们为了让引擎生效,需要经历使用简单条件,例如直接udf<=和var<=情况可能就不一样,其次,现代列式的存储例如orc会为文件做索引元数据的操作,可以直接下推到文件层级,但是有些复杂类型,其实就效果不好了,尽量把数据类型简单化。数字类型的不要定义成字符串,不光是下推需要生效,更加是计算上面需要准确。
小表广播
小表广播主要有两层含义:小表自动广播、拆分小表逻辑 。一方面广播带来的效益其实是非常巨大,另一方面,我们广播的配置是有限制的,默认64M的样子,但是100M左右的广播也是可以的,需要自己调整广播阈值。如果类似join的操作,我们如果可以拆分成广播其实也是可以的。
增量计算
增量计算有两大好处:提前调度+减少merge成本,我们实际很多数据都是全量,增量计算带来的计算一方面可以依赖的ODS是提前很多的,另一反面资源会小很多。但是需要把计算调整为增量。具体来说也是两大类:
合并类=当天变化数据+昨日未变化的数据
select key1,col1,col2 from delta union all select key1,col1,col2 from yesterday x left anti join delta y on x.key1=y.key1;
聚合类=当天数据变化聚合值+昨日的历史值
select key1,index1+index_t as index1 from ( select key1,sum(col1) as from delta group by key1 ) x left outer join ( select key1,index1 from yesterday ) y on x.key1=y.key2;
Bucket对齐
这个主要有几大好处:
合理分桶=>索引,分桶合理的话数据会安装指定的key进行均匀的分布,在存储和读写性能都有很好的提升;
Shuffle 复用,一般是指上游产出的数据给下游使用可以加快下游,如果下游复用多的话节省的资源也是非常大;
粒度对齐=>remove shuffle,在做group by,row_number这种操作以及join操作都有机会不走shuffle,这种情况下带来的优化其实是非常爆炸的。
数据倾斜
数据倾斜其实是很基础的话题,基本现在做大数据的面试必考的,主要原因就是大数据技术一出现其实就受这个问题困扰,不管从组件,还是etl处理都不断在探索方案,常用的方式我也总结如下
过滤倾斜数据:热点的key,例如流量处理时候很多空字符串,或者其他乱七八糟的数据,直接过滤就可以解决倾斜问题;
倾斜部分数据单独运算:和其他部分结果union:其实是直接把倾斜的部分单独运算,剩下的数据就不再倾斜了;
小表join广播
倾斜数据分组,减少倾斜度
AE:这个其实是自适应的一种做法,在新出的引擎会动态采集元数据判断下一个stage需要怎样处理,是一种优化的手段。
拓扑优化(数仓优化)
数仓优化自然是做数据的人做的,etl链路历史上都是无序扩张的情况,这种时候需要规范统一建模手段去进行重构,数仓优化主要有以下手段:
高内聚、低耦合实现数据复用
路径缩短,简化链路
DWD/DWS/ADM建设,数仓的目的
数据加工复用、指标口径统一这个带来的是业务价值
快慢链路,是常用手段,兼顾实效和数据覆盖的方式
维度建模,数仓的方法论
拉链式存储,其实是常用降低存储的手段
中间过程视图化,减少计算,一步到位
后记
大数据优化的手段其实还有很多,从大数据发展的历程来看,这些方法其实是遇到了问题再提出解决方案,总归来说问题很多,但是办法总归是有的。我们的大数据还在往前不断发展,涉及到提炼,加工、以及使用,未来数据量其实还会更加庞大,我们的方式还会受到挑战,到那时我们如何去应对又会是一个新话题了!!