SparkOutOfMemoryError: Unable to acquire 65536 bytes of memory, got 0

Caused by: org.apache.spark.memory.SparkOutOfMemoryError: Unable to acquire 65536 bytes of memory, got 0

原因:代码逻辑或任务参数配置不合理、数据倾斜等导致OOM。分为driver OOM和executor OOM。

解决方法:
(1)查看代码中是否有coalesce()等函数,该函数相比repartition()不会进行shuffle,处理大分区易造成OOM,如果有则可换成repartition(),尽量减少coalesce()的使用。

(2)是否使用了将各executor上所有数据拉回到driver的collect()函数,尽量避免或谨慎使用collect()与cache()等函数,让各executor分布式拉数据与执行,多节点分担海量数据负载。

(3)代码中是否有超过5个连续join或多层嵌套for循环等不合理的代码逻辑,代码解析与相关对象序列化都是在driver端进行,过于冗余复杂不拆分的代码会造成driver OOM。可以优化代码将过多的连续join语句(超过5个)拆分,每3个左右的连续join语句结果生成一个临时表,该临时表再和后面两三个连续join组合,再生成下一个临时表,并在临时表中提前过滤不必要的数据量,使多余数据不参与后续计算处理。只有在代码逻辑性能和参数合理的前提下,最后才能增加–executor-memory、–driver-memory等资源,不能本末倒置。

(4)代码中是否广播了过大的表,可以合理设置spark.sql.adaptiveBroadcastJoinThreshold参数(以B为单位,默认10485760即10MB);在业务代码逻辑极复杂、扫描文件数和数据量、task数等极端大(如几十万个)且广播阈值设置的再小也依然OOM,可以设置为-1关闭broadcast join。

(5)查看任务提交参数中–executor-cores与–executor-memory的比例是否至少为1:4,一个executor上的所有core共用配置的executor内存,如果有类似2core4G等情况存在,在数据量较大的情况下易OOM,至少应是1core4G或者2core8G等。

(6)个别executor的OOM也是数据倾斜会出现的现象之一,如果是这种情况可参考第11点解决。

(7)在代码逻辑和参数合理的前提下,最后一步才是适度增加资源,例如–executor-memory=8g、–driver-memory=4g等。

https://blog.csdn.net/qq_33588730/article/details/105643030

猜你喜欢

转载自blog.csdn.net/qq_42363032/article/details/120302070