其他
【大数据哔哔集20210115】Spark算子调优五大策略
算子调优一:mapPartitions
普通的 map 算子对 RDD 中的每一个元素进行操作,而 mapPartitions 算子对 RDD 中每一个分区进行操作。如果是普通的 map 算子,假设一个 partition 有 1 万条数据,那么 map 算子中的 function 要执行 1 万次,也就是对每个元素进行操作。算子调优二:foreachPartition 优化数据库操作
在生产环境中,通常使用 foreachPartition 算子来完成数据库的写入,通过 foreachPartition 算子的特性,可以优化写数据库的性能。如果使用 foreach 算子完成数据库的操作,由于 foreach 算子是遍历 RDD 的每条数据,因此,每条数据都会建立一个数据库连接,这是对资源的极大浪费,因此,对于写数据库操作,我们应当使用 foreachPartition 算子。与 mapPartitions 算子非常相似,foreachPartition 是将 RDD 的每个分区作为遍历对象,一次处理一个分区的数据,也就是说,如果涉及数据库的相关操作,一个分区的数据只需要创建一次数据库连接:对于我们写的 function 函数,一次处理一整个分区的数据
对于一个分区内的数据,创建唯一的数据库连接
只需要向数据库发送一次 SQL 语句和多组参数
算子调优三:filter 与 coalesce 的配合使用
在 Spark 任务中我们经常会使用 filter 算子完成 RDD 中数据的过滤,在任务初始阶段,从各个分区中加载到的数据量是相近的,但是一旦进过 filter 过滤后,每个分区的数据量有可能会存在较大差异:每个 partition 的数据量变小了,如果还按照之前与 partition 相等的 task 个数去处理当前数据,有点浪费 task 的计算资源;
每个 partition 的数据量不一样,会导致后面的每个 task 处理每个 partition 数据的时候,每个 task 要处理的数据量不同,这很有可能导致数据倾斜问题。
针对第一个问题,既然分区的数据量变小了,我们希望可以对分区数据进行重新分配,比如将原来 4 个分区的数据转化到 2 个分区中,这样只需要用后面的两个 task 进行处理即可,避免了资源的浪费。
针对第二个问题,解决方法和第一个问题的解决方法非常相似,对分区数据重新分配,让每个 partition 中的数据量差不多,这就避免了数据倾斜问题。
A > B(多数分区合并为少数分区)
A < B(少数分区分解为多数分区)
算子调优四:repartition 解决 SparkSQL 低并行度问题
在第一节的常规性能调优中我们讲解了并行度的调节策略,但是,并行度的设置对于 Spark SQL 是不生效的,用户设置的并行度只对于 Spark SQL 以外的所有 Spark 的 stage 生效。Spark SQL 的并行度不允许用户自己指定,Spark SQL 自己会默认根据 hive 表对应的 HDFS 文件的 split 个数自动设置 Spark SQL 所在的那个 stage 的并行度,用户自己通 spark.default.parallelism 参数指定的并行度,只会在没 Spark SQL 的 stage 中生效。由于 Spark SQL 所在 stage 的并行度无法手动设置,如果数据量较大,并且此 stage 中后续的 transformation 操作有着复杂的业务逻辑,而 Spark SQL 自动设置的 task 数量很少,这就意味着每个 task 要处理为数不少的数据量,然后还要执行非常复杂的处理逻辑,这就可能表现为第一个有 Spark SQL 的 stage 速度很慢,而后续的没有 Spark SQL 的 stage 运行速度非常快。为了解决 Spark SQL 无法设置并行度和 task 数量的问题,我们可以使用 repartition 算子。算子调优五:reduceByKey 本地聚合
reduceByKey 相较于普通的 shuffle 操作一个显著的特点就是会进行 map 端的本地聚合,map 端会先对本地的数据进行 combine 操作,然后将数据写入给下个 stage 的每个 task 创建的文件中,也就是在 map 端,对每一个 key 对应的 value,执行 reduceByKey 算子函数。reduceByKey 算子的执行过程如图:本地聚合后,在 map 端的数据量变少,减少了磁盘 IO,也减少了对磁盘空间的占用
本地聚合后,下一个 stage 拉取的数据量变少,减少了网络传输的数据量
本地聚合后,在 reduce 端进行数据缓存的内存占用减少
本地聚合后,在 reduce 端进行聚合的数据量减少
【大数据哔哔集20210113】Hive的动态分区和静态分区
【大数据哔哔集20210112】Sorry,Hbase的LSM Tree真的可以为所欲为!