我们在spark / yarn上运行ETL平台,该平台可创建数千个较小的工作。当前,这些作业使用默认的内存规范来覆盖最坏的情况,从而导致内存严重浪费。
我正在尝试使用Spark历史记录服务器确定各种作业的更好的内存和执行程序/核心设置等,并提出了这个非常粗糙的公式以达到每个作业内存的起点:
- 从“火花历史记录阶段”标签中获取数据
- 取前x个阶段(x是每个容器的执行器核心数)的MAX(输入字节,输出字节)+ MAX(随机读取,随机写入)并相加。逻辑是并行运行的阶段的潜力,其中每个执行者使用多个内核
- 如果根据默认的spark.memory.fraction设置为随机播放和缓存所需的内存分配,则表示75%,因此/ 75 * 100可获得100%的内存需求
- + 30%作为安全费用
- + 300Mb *每个执行者为保留的火花存储器执行的人数
- 向上舍入到下一个512Mb整齐
- 将总数除以执行者人数
然后申请:
- 由于300Mb x 1.5的因素,一个执行器最低512Mb会立即导致故障
- 除法后,一个执行器必须足够大,可以执行给定的前x个阶段
- 驱动程序至少与任何收集或获取操作输出字节一样大
最后:
- 对执行者和执行者核心进行按摩,以使运行时处于可接受的值以下(对x的更改反馈回上述内容)
我已经尝试过了,它大大减少了总体内存占用,有0个失败/重试的作业。但是我想知道这里是否存在任何有缺陷的逻辑,尤其是围绕对这75%区域中的缓存和随机播放的理解。
谢谢