多部分上傳失敗

了解如何解決多部分上傳失敗。

寫的亞當Pavlacka

最後發布時間:2022年3月4日

問題

你觀察到一個作業失敗,但有以下例外:

sdkclientexception:無法完成多部分上傳。單個部分上傳失敗:Unable to execute HTTP request: Timeout waiting for connection from pool org.apache.http.conn.ConnectionPoolTimeoutException: Timeout waiting for connection from pool…com.amazonaws.http.AmazonHttpClient RequestExecutor.executeOneRequest美元(AmazonHttpClient.java: 1190)

導致

此錯誤源於Amazon SDK內部實現多部分上傳,它接收所有多部分上傳請求,並將它們作為Futures提交到線程池。

這裏沒有背壓控製。所有的作品都是並行提交的。因此,對實際執行並行性的唯一限製是線程池本身的大小。在本例中,線程池為BlockingThreadPoolExecutorServiceS3A內部的一個類,它在池達到最大線程容量時對請求進行排隊,而不是拒絕它們。

這裏有兩個並行度限製:

  • S3A使用的線程池的大小
  • 的大小HTTPClient內部連接池AmazonS3Client

如果S3A線程池小於HTTPClient連接池,那麼我們可以想象這樣一種情況,線程在試圖從連接池中獲取連接時變得饑餓。如果數百個正在運行的命令最終出現抖動,我們就可以看到這種情況。

解決方案

您可以調優S3A線程池的大小和HTTPClient連接池。一個合理的方法是將S3A線程池的大小減小到小於HTTPClient池的大小。然而,這並非沒有風險:在hadoop - 13826據報道,在多部分上傳時,池的大小太小可能會導致死鎖。在AWS Java SDK本身有一個相關的錯誤:問題/ 939.鑒於此,我們不建議減小這個池的大小。相反,我們建議您增加HTTPClient池大小匹配S3A池中的線程數(目前是256)。的HTTPClient連接池最終由fs.s3a.connection.maximum現在被硬編碼為200。

為了解決這個問題,設置如下Spark配置屬性.這些屬性將應用於集群中運行的所有作業:

spark.hadoop.fs.s3a.multipart。閾值2097152000 spark.hadoop.fs.s3a.multipart。大小104857600 spark.hadoop.fs.s3a.connection。最大500個spark.hadoop.fs.s3a.connection。超時600000


這篇文章有用嗎?