如何并行下载S3目录?TransferManager小文件下载性能优化求助
解决S3小文件目录并行下载的问题
你猜的没错!TransferManager.downloadDirectory() 默认情况下确实不会为每个小文件单独分配线程并行下载——它的多线程配置主要是针对大文件的分片(MultiPart)下载场景设计的,小文件因为达不到分片阈值(默认是100MB),会被逐个串行处理,所以你设置的50线程池根本没发挥作用。
下面给你两个简便的解决方案,适配不同的SDK版本:
方案1:AWS SDK v1 下开启文件级并行下载
你需要给TransferManager配置DownloadDirectoryConfiguration,专门开启文件间的并行下载控制,配合线程池就能让小文件批量并行下载了。代码示例如下:
// 1. 创建固定线程池,控制并发数 ExecutorService executor = Executors.newFixedThreadPool(50); // 2. 配置下载目录的并行策略 DownloadDirectoryConfiguration downloadConfig = new DownloadDirectoryConfiguration(); // 设置文件级别的并发数,和线程池大小匹配即可 downloadConfig.setFileDownloadConcurrency(50); // 小文件不需要分片,保持默认100MB的分片阈值即可 // downloadConfig.setMinimumPartSize(1024 * 1024 * 100); // 3. 构建带配置的TransferManager TransferManager transferManager = TransferManagerBuilder.standard() .setS3Client(s3client) .setExecutorFactory(() -> executor) .build(); // 4. 执行目录下载,传入自定义配置 MultipleFileDownload download = transferManager.downloadDirectory( "你的Bucket名称", "S3上的目录路径", new File("本地目标路径"), downloadConfig ); // 等待所有文件下载完成 download.waitForCompletion(); // 记得关闭资源 transferManager.shutdownNow(); executor.shutdown();
核心就是setFileDownloadConcurrency()方法,它专门控制不同文件之间的并行下载数量,这样9000个小文件就会以50个并发的速度同时下载,性能会有明显提升。
方案2:升级到AWS SDK v2,体验更简洁的并行下载
如果有机会升级到AWS SDK for Java 2.x,推荐使用S3TransferManager,它的设计更贴合现代并发模型,默认就支持小文件的并行下载,代码更简洁:
// 创建S3TransferManager,默认自带合理的并发逻辑 S3TransferManager transferManager = S3TransferManager.create(); // 配置下载请求,指定线程池控制并发 DownloadDirectoryRequest downloadRequest = DownloadDirectoryRequest.builder() .bucket("你的Bucket名称") .prefix("S3上的目录路径") .destination(new File("本地目标路径")) .downloadFileRequestTransformer(req -> req .overrideConfiguration(o -> o.executor(Executors.newFixedThreadPool(50)))) .build(); // 执行下载并等待完成 transferManager.downloadDirectory(downloadRequest).completionFuture().join(); // 关闭资源 transferManager.close();
v2的S3TransferManager会自动处理小文件的并行调度,不需要额外配置文件级并发,只需要指定线程池即可,体验更流畅。
额外优化小建议
- 线程池大小别盲目调大:AWS S3有请求速率限制(默认账户每秒5500个GET请求),50个并发完全在限制内,但过高的并发可能触发限流,反而降低性能。
- 开启Transfer Acceleration:如果你的下载地点和Bucket区域距离较远,可以开启S3的Transfer Acceleration,通过AWS全球加速网络提升下载速度,只需要在请求中配置
enableTransferAcceleration(true)即可。
内容的提问来源于stack exchange,提问作者Eric Zhang
相关产品推荐
相关产品推荐

