如何避免Spark执行器丢失和纱线容器由于内存限制而导致它被杀死?

Ume*_*cha 16 memory executors hadoop-yarn apache-spark apache-spark-sql

我有以下代码,hiveContext.sql()大部分时间都会触发.我的任务是我想创建几个表并在处理完所有hive表分区后插入值.

所以我首先show partitions在for循环中触发并使用它的输出,我调用一些创建表的方法(如果它不存在)并使用它插入它们hiveContext.sql.

现在,我们不能hiveContext在执行程序中执行,所以我必须在驱动程序的for循环中执行它,并且应该逐个串行运行.当我在YARN集群中提交这个Spark作业时,几乎所有的时间我的执行程序都因为shuffle未找到异常而丢失.

现在这种情况正在发生,因为YARN因为内存过载而杀死了我的执行程序.我不明白为什么,因为我为每个hive分区设置了一个非常小的数据集,但它仍然导致YARN杀死我的执行程序.

以下代码是否会并行执行所有操作并尝试同时容纳内存中的所有hive分区数据?

public static void main(String[] args) throws IOException {   
    SparkConf conf = new SparkConf(); 
    SparkContext sc = new SparkContext(conf); 
    HiveContext hc = new HiveContext(sc); 

    DataFrame partitionFrame = hiveContext.sql(" show partitions dbdata partition(date="2015-08-05")"); 
  
    Row[] rowArr = partitionFrame.collect(); 
    for(Row row : rowArr) { 
        String[] splitArr = row.getString(0).split("/"); 
        String server = splitArr[0].split("=")[1]; 
        String date =  splitArr[1].split("=")[1]; 
        String csvPath = "hdfs:///user/db/ext/"+server+".csv"; 
        if(fs.exists(new Path(csvPath))) { 
            hiveContext.sql("ADD FILE " + csvPath); 
        } 
        createInsertIntoTableABC(hc,entity, date); 
        createInsertIntoTableDEF(hc,entity, date); 
        createInsertIntoTableGHI(hc,entity,date); 
        createInsertIntoTableJKL(hc,entity, date); 
        createInsertIntoTableMNO(hc,entity,date); 
   } 
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*475 18

通常,您应该始终深入了解日志以获得真正的异常(至少在Spark 1.3.1中).

文艺青年最爱的
安全配置下纱火花
spark.shuffle.memoryFraction=0.5-这将使洗牌使用更多分配的内存
spark.yarn.executor.memoryOverhead=1024-这是在MB设置.当内存使用量大于(executor-memory + executor.memoryOverhead)时,Yarn会终止执行程序

更多信息

从阅读你的问题,你提到你没有发现洗牌异常.

如果 org.apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle 你应该增加spark.shuffle.memoryFraction,例如增加到0.5

纱线杀死执行器的最常见原因是内存使用超出了预期.为了避免增加spark.yarn.executor.memoryOverhead,我将其设置为1024,即使我的执行程序仅使用2-3G的内存.