我在本地模式下使用spark,简单的连接花费的时间太长 . 我已经获取了两个数据帧:A(8列和230万行)和B(8列和120万行)并使用 A.join(B,condition,'left')
连接它们并最终调用一个动作 . 它创建了一个具有三个阶段的单个作业,每个阶段用于两个数据帧提取,一个用于连接 . 令人惊讶的是,提取数据帧A的阶段大约需要8分钟,而数据帧B的需要花费1分钟 . 并在几秒钟内加入 . 我的重要配置设置是:
-
spark.master local [*]
-
spark.driver.cores 8
-
spark.executor.memory 30g
-
spark.driver.memory 30g
-
spark.serializer org.apache.spark.serializer.KryoSerializer
-
spark.sql.shuffle.partitions 16
唯一的执行者是驱动程序本身 . 在提取数据帧时,我已将其分区为32个(也尝试过16,64,50,100,200)个部分 . 我已经看到随机数据帧A提取的洗牌写入内存为100 MB . 因此,为避免混乱,我为数据帧和广播数据帧B(较小)制作了16个初始分区,但它没有帮助 . 仍然有随机写入内存 . 我为此使用了 broadcast(B)
语法 . Am I doing something wrong? Why shuffling is still there? 此外,当我看到事件时间表时,它显示只有四个核心正在处理任何时间点 . 虽然我有一台2核* 4处理器的机器 . Why is that so?
1 回答
简而言之,"Join" <=> Shuffling,这里的一个重要问题是您的数据在分区上的统一分布情况(例如参见https://0x0fff.com/spark-architecture-shuffle/,https://www.slideshare.net/SparkSummit/handling-data-skew-adaptively-in-spark-using-dynamic-repartitioning和谷歌问题) . 提高效率的可能性很小:
更多地考虑您的数据(A和B)以及明智地划分数据;
分析,您的数据是否有偏差?
进入UI并查看任务时间;
为分区选择这样的密钥,在"join"期间,只有少数几个分区来自数据集A,其中几个分区为B;