剖析需求,熟悉业务
熟悉需求以及业务接口
开发一个Spark的任务和开发其他需求是一样的,要知道这个任务主要用来做什么,输入时什么,输出是什么,中间需要哪些操作。最好能根据确认原始的需求,从用户的角度出发,而不是根据中间人的转述做设计和开发。举个例子,可能某个数据产品说,有个需求,需要这么做这么做,这种说话,仿佛产品已经帮你想好了技术思路,你只需要实现就好了,其实这样很有问题。因为首先你不知道这个事情原始的需求是什么,其次解决这个需求的方案你没有参与,而是直接接受了别人的方案。我觉得比较好的方式,可以这么来,谁提出了一个需求,那么找他确认一下具体的需求,然后多人讨论下该如何做。说多了。
确认和保证数据的SLA
简单一点就是,提供数据的时间粒度,什么时间准备好,最晚延迟多久,保证可用性比例有多高。是否有监控和告警功能,是否能够自动重试,是否有补数据的脚本。
熟悉数据大小和走向
对于一个数据处理的任务,作为开发,要了解,我要处理的数据格式是什么样的,数据量有多大,数据是实时还是离线,数据分区是什么,数据上游是哪里。数据的分布怎么样?这个对于任务应该怎么写,很重要。比如,如果我需要设置一下我的并行度,以及内存的大小,那么我必须知道,我这个数据的分区情况,以及最大最小值等。很多数据倾斜的问题,可以在这一步发现并解决。
合理使用算子
目前来看,很多算法性能不高,有两个原因,要么是不知道有一些比较好的算子,要么是随便使用算子。
repartition 要了解,推荐用,但不能乱用
repartition 操作主要是对数据进行重新分区,但不是每次都和大家想想的一样,因为需要考虑当前的数据分区数。比如如果当前数据分区是1000,执行repartition(2000),那么这个会执行shuffle操作,也就是一个分区拆分成了两个分区,如果执行repartition(500),那么实际上执行的是coalesce操作,也就是将分区进行了合并。那么什么时候需要合并,什么时候需要进行拆分呢?repartition 一般有这么几个场景,1处理能力不够 2 数据分布不均,进行打散 coalesce 的场景,数据分区很多,但是每个分区数较少,这个时候其实并不太影响执行效率,但是对于一些需要外部链接,或者写入文件的场景来说,这是很浪费资源的。所以类似这样的场景需要进行合并。
join、reduce,reduceByKey等shuffle操作要小心
其实join和reduce等其他操作一样也是shuffle操作,这个时候只要大家指定了key出现倾斜的问题还是比较常见的。这个时候比较好的办法就是分为几个步骤
1、统计倾斜比例
2、判断是否可以过滤倾斜key,否则3
3、进行打散最后在合并,或者继续打散(打散的方法很多,这块可以百度)
使用persist
这个操作目前看代码用的不是很多,这个的功能可以参考
网友评论