Spark广播DataFrame后的总数据量及内存释放时机问题
广播变量总数据量问题
答案是否,总数据量不会恰好是120MB,原因如下:
- 你提到的20MB通常是该DataFrame在外部存储中的压缩后逻辑大小,Spark在内存中存储的是反序列化后的计算对象,相同数据的内存占用一般是磁盘存储大小的2~5倍,具体数值和你配置的序列化器(Java序列化/Kryo序列化)、压缩策略直接相关。
- 即便你所说的20MB是广播传输阶段的序列化压缩后大小,总占用也不是简单的6份×20MB:driver端会同时持有序列化和反序列化两份数据副本,executor端使用默认
MEMORY_ONLY存储级别时,会存储反序列化后的对象用于计算,单副本内存占用远高于20MB。 - 额外补充:单台executor上即使同时运行多个用到该广播变量的任务,也只会存储一份副本,不会重复占用内存。
广播数据清除时机问题
不会在join完成后立即清除,默认等待GC触发或者主动销毁,具体逻辑:
- Spark广播变量默认采用懒清除策略:只有当driver端的
Broadcast对象超出作用域被GC回收,或者你主动调用unpersist()方法时,才会触发全集群对应广播块的删除指令。 - 如果没有主动调用
unpersist(),广播数据会一直驻留在driver和所有用到该数据的executor内存中,直到整个作业结束,或者driver端的广播对象被回收后,executor端的块才会在收到指令后或者自身GC周期中被清除。 - 最佳实践:如果确认后续作业不会再用到该广播变量,主动调用
broadcastVar.unpersist()可以及时释放内存,避免资源浪费。
内容的提问来源于stack exchange,提问作者Rushabh Gujarathi
相关产品推荐
相关产品推荐

