一、内存模型
spark运行使用内存主要包含driver和executor,通过driver-memory和executor-memory进行设置,通过运行机制得知,driver负责提交注册,接受executor反向注册,stage划分和task任务分发等工作,默认内存大小为1G,在使用collect算子时,需要注意oom,因为collect算子将数据拉取到driver,spark的主要作业发生在executor中,当服务器允许的情况下,为保证spark的运行效率,可以尽量提高。
spark在1.6以前(不包含1.6)使用的是静态内存模型(executor部分),
分为两部分:包括execution:用来进行shuffle操作,storage:用来存储广播变量和缓存
分为四部分:如上图所示,图中占比为默认值。
缺点:分配比例固定,如果spark作业缓存多shuffle操作少,或者缓存少shuffle操作多,或造成内存浪费,有限的资源不能得到充分的利用。
对应task的内存分配模式为:
缺点:内存分配为平均分配,缺少灵活性
为了解决内存分配的固化,从spark1.6版本后采用统一内存模型
图中比例分配为2.x版本的分配比例(其中1.6版本比例分配为,spark.memory.fraction=0.75,spark.memory.storageFraction =0.5),其中不再严格界定storage和execution内存,在缓存较多,shuffle较少时,storage占比会增大,满足需求;当缓存较少,shuffle较多时,execution内存占比会增大。
当内存不足时:
<1>在缓存较多,shuffle较少 -->shuffle需求增加--->storage返还借用的内存,自身缓存内容写入磁盘
<2>当缓存较少,shuffle较多时-->缓存需求增加-->execution不会返还借用的内存,storage将缓存文件写入磁盘
对应task的内存分配模式:
每个task内存分配站决定于task的个数N,N越少,分配的内存越多,反之越少。内存使用更加灵活。有利于高效完成任务
对应task内部不同操作的内存分配(1.6+):