18

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

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

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

现在发生这种情况是因为 YARN 由于内存过载而杀死了我的执行程序。我不明白为什么,因为我为每个配置单元分区都有一个非常小的数据集,但它仍然会导致 YARN 杀死我的执行程序。

以下代码会并行执行所有操作并尝试同时容纳内存中的所有配置单元分区数据吗?

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); 
   } 
}
4

2 回答 2

19

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

tl; Dr.
Yarn 下 Spark 的安全配置
spark.shuffle.memoryFraction=0.5- 这将允许 shuffle 使用更多分配的内存
spark.yarn.executor.memoryOverhead=1024- 以 MB 为单位设置。当 Yarn 的内存使用量更大时,纱线会杀死执行程序(executor-memory + executor.memoryOverhead)

更多信息

通过阅读您的问题,您提到您得到 shuffle not found 异常。

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

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

于 2015-10-14T06:52:01.393 回答
0

这是我的假设:您的集群上的执行程序必须有限,并且作业可能在共享环境中运行。

正如您所说,您的文件很小,您可以设置较少数量的执行器并增加执行器核心,memoryOverhead此处设置属性很重要。

  1. 设置执行者数量 = 5
  2. 设置执行核心数 = 4
  3. 设置内存开销 = 2G
  4. shuffle partition = 20(根据执行程序和核心使用最大并行度)

使用上述属性,我相信您将在不影响性能的情况下避免任何执行程序内存不足的问题。

于 2019-06-22T21:36:32.953 回答