我的输入数据集大约是150g。我正在设置
--conf spark.cores.max=100
--conf spark.executor.instances=20
--conf spark.executor.memory=8G
--conf spark.executor.cores=5
--conf spark.driver.memory=4G
但由于数据并不是均匀地分布在执行者之间,所以我一直
Container killed by YARN for exceeding memory limits. 9.0 GB of 9 GB physical memory used
以下是我的问题:
1. Did I not set up enough memory in the first place? I think 20 * 8G > 150G, but it's hard to make perfect distribution, so some executors will suffer
2. I think about repartition the input dataFrame, so how can I determine how many partition to set? the higher the better, or?
3. The error says "9 GB physical memory used", but i only set 8G to executor memory, where does the extra 1G come from?
谢谢您!
2条答案
按热度按时间vaqhlq811#
9gb由8gb的执行器内存组成,您可以将其作为参数添加,
spark.yarn.executor.memoryOverhead
设置为.1
,因此容器的总内存为spark.yarn.executor.memoryOverhead + (spark.yarn.executor.memoryOverhead * spark.yarn.executor.memoryOverhead)
哪个是8GB + (.1 * 8GB) ≈ 9GB
.您可以使用一个执行器来运行整个流程,但这需要很长时间。要理解这一点,您需要了解分区和任务的概念。分区数由您的输入和操作定义。例如,如果您从hdfs读取一个150gbcsv,而hdfs块大小为128mb,那么您将得到
150 * 1024 / 128 = 1200
分区,直接Map到spark ui中的1200个任务。每一项任务都将由执行者来执行。你不需要在内存中保存所有的150gb。例如,当您只有一个执行器时,您显然不会受益于spark的并行功能,但它只会从第一个任务开始,处理数据,并将其保存回dfs,然后开始处理下一个任务。
您应该检查的内容:
输入分区有多大?输入文件是可拆分的吗?如果单个执行器必须加载大量内存,那么它肯定会耗尽内存。
你在做什么动作?例如,如果使用非常低的基数进行连接,则会得到大量的分区,因为所有具有特定值的行都会在相同的分区中结束。
执行非常昂贵或低效的操作?任何笛卡尔积等。
希望这有帮助。快乐Spark!
fd3cxomn2#
在使用Yarn时,还有另一个设置,用于计算为执行者发出Yarn容器请求的大小:
它默认为0.1*执行器内存设置。它定义了除了指定的执行器内存之外,还需要多少额外的开销内存。先尝试增加这个数字。
另外,一个Yarn容器不会给你一个任意大小的内存。它将只返回分配了内存大小为其最小分配大小倍数的容器,该最小分配大小由以下设置控制:
将其设置为一个较小的数字将降低您“超出”所需金额的风险。
我还通常将follow键设置为大于所需容器大小的值,以确保spark请求控制我的执行器有多大,而不是对它们进行踩踏。这是Yarn将发出的最大容器尺寸。