[英]How to avoid Spark executor from getting lost and yarn container killing it due to memory limit?
我有以下代碼,它在大多數情況下觸發hiveContext.sql()
。 我的任務是我想創建幾個表並在處理完所有hive表分區后插入值。
所以我首先激活show partitions
並在for循環中使用它的輸出,我調用一些創建表的方法(如果它不存在)並使用hiveContext.sql
插入它們。
現在,我們不能在執行hiveContext
中執行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);
}
}
通常,您應該始終深入了解日志以獲得真正的異常(至少在Spark 1.3.1中)。
TL;博士
在Yarn下安裝Spark的安全配置
spark.shuffle.memoryFraction=0.5
- 這將允許shuffle使用更多的已分配內存
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的內存。
這是我的假設:您的群集上必須具有有限的執行程序,並且作業可能在共享環境中運行。
正如您所說,您的文件大小很小,您可以設置較少數量的執行程序並增加執行程序核心,並在此處設置memoryOverhead
屬性非常重要。
使用上面的屬性我相信你會避免任何執行程序內存不足而不影響性能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.