Complete a 3 Question Survey and Earn a re:Post Badge
Help improve AWS Support Official channel in re:Post and share your experience - complete a quick three-question survey to earn a re:Post badge!
如何解決 Amazon EMR 上 Apache Spark 作業的「裝置上沒有剩餘空間」階段失敗?
當我將 Apache Spark 應用程式提交到 Amazon EMR 叢集時,該應用程式失敗,並顯示「裝置上沒有剩餘空間」階段失敗。
簡短描述
您的 Apache Spark 應用程式可能會因為以下原因而遇到裝置上沒有剩餘空間錯誤:
- 由於存在隨機聯結,因此在隨機過程中會產生大量中間資料
- 資料分區和執行程式工作負載分配不均
- 分區大小和數量不正確
- 磁碟和記憶體等資源的可用性不足
Apache Spark 使用核心和任務節點上的本機儲存來儲存中間 (隨機) 資料。如果執行個體上的磁碟空間不足,則作業會失敗並顯示裝置上沒有剩餘空間錯誤。
解決方法
本文說明裝置空間不足錯誤的常見原因和解決方案。您必須找出根本原因才能實施適當的修正。
**注意:**如果您在執行 AWS Command Line Interface (AWS CLI) 命令時收到錯誤訊息,請參閱對 AWS CLI 錯誤進行疑難排解。此外,請確定您使用的是最新的 AWS CLI 版本。
重新分區
根據叢集中的核心節點和任務節點的數量,您可能需要增加 Spark 分區的數量。若要新增更多 Spark 分區,請執行下列命令:
val numPartitions = 500 val newDF = df.repartition(numPartitions)
**注意:**將 500 替換為適合您使用案例的分區數。
調整 Spark 組態
分區管理
在隨機過程中出現過多的磁碟溢出或在分區間資料分配不均時,請調整下列參數:
spark.default.parallelism=${NUM_CORES * 2} #no. of partitions in RDDs spark.sql.shuffle.partitions=${NUM_CORES * 2} #no. of shuffle partitions spark.sql.files.maxPartitionBytes=256MB #max. no. of bytes in a partition when reading files spark.sql.files.maxRecordsPerFile=10000000
如果符合以下情況之一,請增加平行量和分區數量:
- 任務持續時間差異大於平均持續時間的 3 倍
- 每個任務的溢出量大於 20%
如果平均分區大小小於 50 MB 或小檔案太多,則減少平行量和分區數量。
若要計算最佳分區計數,請使用下列公式:
Initial Partitions = Number of Cores * 2 Optimal Partitions = max( Total Input Size / Target Partition Size, Initial Partitions )
根據資料量進行調整
以下是不同大小資料集的組態參數:
小型資料集 (小於 100 GB):
spark.sql.files.maxPartitionBytes=128MB spark.sql.shuffle.partitions=NUM_CORES * 2 spark.sql.files.maxRecordsPerFile=5000000
中型資料集 (100 GB 至 1 TB):
spark.sql.files.maxPartitionBytes=256MB spark.sql.shuffle.partitions=NUM_CORES * 3 spark.sql.files.maxRecordsPerFile=10000000
大型資料集 (大於 1 TB):
spark.sql.files.maxPartitionBytes=512MB spark.sql.shuffle.partitions=NUM_CORES * 4 spark.sql.files.maxRecordsPerFile=20000000
記憶體與儲存空間最佳化
若要最佳化記憶體和儲存空間,請更新您的組態參數:
spark.memory.fraction=0.8 # Higher for compute-intensive jobs spark.memory.storageFraction=0.3 # Lower for shuffle-heavy workloads spark.executor.memoryOverhead=0.2 # 20% of executor memory spark.memory.offHeap.enabled=true spark.memory.offHeap.size=${EXECUTOR_MEMORY * 0.2}
若要計算 Spark 執行程式容器的總記憶體分配,需要組合以下四個記憶體元件:
- 執行程式記憶體 (spark.executor.memory)
- 記憶體負荷 (spark.executor.memoryOverhead)
- 堆外記憶體 (spark.memory.offHeap.size)
- PySpark 記憶體 (spark.executor.pyspark.memory)
執行程式容器總記憶體 = spark.executor.memory + spark.executor.memoryOverhead + spark.memory.offHeap.size + spark.executor.pyspark.memory
以下計算決定了 Spark 的內部記憶體分配:
Storage Memory = Executor Memory * memory.fraction * memory.storageFraction Execution Memory = Executor Memory * memory.fraction * (1 - memory.storageFraction) Off-Heap Memory = Executor Memory * 0.2
檔案和磁碟管理
如果存在分區偏斜或分區數量過高或過低,則需要調整檔案管理組態。將 maxPartitionNum 設定為核心總數的 2 倍,將 minPartitionNum 設為 1,除非您的使用案例需要不同的值。
# File Management spark.sql.files.minPartitionNum=${NUM_CORES} spark.sql.files.maxPartitionNum=${NUM_CORES * 4} spark.shuffle.file.buffer=64k
如果 maxPartitionNum 設定得太低,則可能會限制平行性,並且可能無法防止所有偏斜情況。
AQE 和偏斜處理
Spark 中的 AQE (自適應查詢執行) 是一種執行時期最佳化,可根據即時統計資料調整查詢計劃。
在 Amazon EMR 5.30.0 版及更新版本中,AQE 預設為啟用狀態。Spark 中的 AQE 可以自動最佳化連線策略和隨機。它還可以通過動態分區分割有效處理資料偏斜。這可改善負載平衡和查詢效能。
# Skew Management spark.sql.adaptive.enabled=true spark.sql.adaptive.skewJoin.enabled=true spark.sql.adaptive.skewJoin.skewedPartitionFactor=10 spark.sql.adaptive.skewJoin.skewedPartitionThresholdInBytes=256MB
如果您使用不支援 AQE 的舊版 Spark,請使用下列其中一種方法來管理資料偏斜:
- 調整廣播聯結的 spark.sql.autoBroadcastJoinThreshold 閾值。當聯結中的一個資料集明顯小於另一個資料集時,這很有用。
- 在程式碼中使用 repartition() 或 coalesce() 來改善資料分配。
- 將偏斜提示套用至較大或偏斜的資料表,並廣播較小的資料表。偏斜提示會通知 Spark 最佳化程式資料表有偏斜資料,並有助於最佳化聯結策略。
以下是 Spark SQL 查詢中的偏斜提示範例:
-- Using SKEW hint in Spark SQL SELECT /*+ SKEW('t1') */ t1.key, t2.value FROM table1 t1 JOIN table2 t2 ON t1.key = t2.key -- Using MAPJOIN hint along with SKEW SELECT /*+ SKEW('t1'), MAPJOIN(t2) */ t1.key, t2.value FROM table1 t1 JOIN table2 t2 ON t1.key = t2.key
用於動態擴展儲存空間的 Bootstrap 動作
您可以透過 Amazon CloudWatch 監控和 Lambda 自動化,使用 Bootstrap 動作來自動擴展 Amazon EMR 叢集的儲存空間。當可用磁碟空間低於設定的閾值時,Amazon CloudWatch 會啟動 AWS Lambda 函數。此功能會將新的 Amazon Elastic Block Store (Amazon EBS) 磁碟區附加到叢集節點。然後,函數會執行指令碼來格式化、安裝磁碟區,並將其整合到 Hadoop 分散式檔案系統 (HDFS) 中。
這種自動化方法可防止因儲存限制而導致的叢集失敗,並僅在需要時增加容量來維持成本效益。該實作需要適當的身分與存取管理 (IAM) 角色、Amazon CloudWatch 警示、AWS Lambda 組態,以及用於磁碟區管理的自訂指令碼。如需詳細資訊,請參閱動態向上擴展 Amazon EMR 叢集上的儲存空間。
增加更多 Amazon EBS 容量
對於新叢集,請使用較大的 EBS 磁碟區
啟動 Amazon EMR 叢集,然後選擇具有較大 EBS 磁碟區的 Amazon Elastic Compute Cloud (Amazon EC2) 執行個體類型。如需詳細資訊,請參閱執行個體的預設 Amazon EBS 儲存空間。
對於執行中的叢集,請新增更多 EBS 磁碟區
請完成下列步驟:
-
如果較大的 EBS 磁碟區無法解決問題,請附加更多 EBS 磁碟區至核心和任務節點。
-
格式化並掛載附加的磁碟區。請務必使用正確的磁碟編號 (例如,/mnt1 或 /mnt2 而非 /data)。
-
建立 /mnt2/yarn 目錄,然後將目錄的所有權設為 YARN 使用者:
sudo mkdir /mnt2/yarn sudo chown yarn:yarn /mnt2/yarn
-
將 /mnt2/yarn 目錄新增至 /etc/hadoop/conf/yarn-site.xml 的 yarn.nodemanager.local-dirs 屬性。
範例:<property> <name>yarn.nodemanager.local-dirs</name> <value>/mnt/yarn,/mnt1/yarn,/mnt2/yarn</value> </property>
-
重新啟動 NodeManager 服務:
Amazon EMR 4.x 至 5.29.0 發行版本sudo stop hadoop-yarn-nodemanager sudo start hadoop-yarn-nodemanager
Amazon EMR 5.30.0 及更新的發行版本
sudo systemctl stop hadoop-yarn-nodemanager sudo systemctl start hadoop-yarn-nodemanager
相關資訊
如何對 Amazon EMR 上 Spark 作業的階段失敗進行疑難排解?
AWS 開放資料分析網站上的最佳做法

相關內容
- 已提問 15 天前
- 已提問 8 個月前
- 已提問 7 個月前
- AWS 官方已更新 8 個月前