一、数据结构的选择
DataFrame、Dataset和SQL在速度上都是相同的,spark会自动使用优化引擎对它们进行优化,相比于RDD的手动编写优化代码要好,同时避免使用UDF函数也是一个优化策略,UDF是昂贵的,因为它们强制将数据表示为JVM中的对象,有时在查询中要对一个记录执行多次此操作。应该尽可能地使用结构化的API来执行操作,因为他们将以更高效地方式执行转化操作。
二、分桶操作
分桶允许Spark根据可能执行的连接操作或聚合操作对数据进行“预先分区”,帮助数据在分区间持续分布,而不是倾斜到一两个分区。分桶允许Spark根据可能执行的连接操作或聚合操作对数据进行“预先分区”,帮助数据在分区间持续分布,而不是倾斜到一两个分区。
三、分区数
对于所有Spark作业来说,分区数量都很重要。如果你的分区太少,那么只有少量节点在工作,这可能会造成数据倾斜。但是如果你有太多的分区,那么启动每一个任务的需要的开销可能会占据所有的资源。为了更好地平衡,你的Shuffle中为每个输出分区设置至少几十兆字节的数据。spark.sql.shuffle.partitions
用来配置shuffle操作时的分区数量如join或者aggregate,一般减少分区数用coalesce方法,增加分区数用reparation,但reparation是shuffle操作,也有一定的计算开销,不过reparation的数据一般不存在数据倾斜的问题,同时增加了分区数,并行度更高。
四、并行度
通常建议分配集群中每个CPU核心至少有两到三个任