问题
你观察工作失败,除了:
com.amazonaws。SdkClientException:无法完成多部分上传。个人部分上传失败:无法执行HTTP请求:org.apache.http.conn超时等待连接池。ConnectionPoolTimeoutException:超时等待连接池……com.amazonaws.http.AmazonHttpClient RequestExecutor.executeOneRequest美元(AmazonHttpClient.java: 1190)
导致
这个错误起源于亚马逊SDK多部分的内部实现上传,所有的多部分上传请求和提交期货到线程池。
这里没有背压控制。所有的作品都是并行提交。因此唯一限制实际并行执行的线程池的大小。在这种情况下,线程池是一种BlockingThreadPoolExecutorService一个类内部S3A队列的请求,而不是排斥它们一旦池已经达到了它的最大线程能力。
这里有两个并行的限制:
- 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.hadoop.fs.s3a.multipart。阈值2097152000 spark.hadoop.fs.s3a.multipart。104857600 spark.hadoop.fs.s3a.connection大小。最大500 spark.hadoop.fs.s3a.connection。超时600000