我遇到一个问题,即 PowerShell 脚本从 AWS S3 下载文件所花的时间是批处理文件的 10 倍。
我有一个现有的批处理文件脚本,用于将文件从一个 S3 存储桶移动到另一个 S3 存储桶,移动 1000 个文件大约需要 30 秒。
该脚本如下所示 aws s3 mv s3://bucket/folder/s3://bucket/%destKey%/%subDestKey%/ --recursive --include "*.json" -profile etl
我宁愿在 PowerShell 中执行此操作,因为我想应用更多的逻辑,而且我更喜欢在 PowerShell 中执行此操作。
我的 Powershell 脚本执行相同的操作,如下所示
$files = Get-S3object -BucketName bucket | where {$_.Key -like "*.json" -and
$_.Key -notlike "inprogress*"}
foreach ($file in $files){
Copy-S3Object -BucketName bucket -Key $file.Key -DestinationKey
"$date/$($file.key)" -DestinationBucket newbucket
Remove-S3Object -BucketName bucket -Key $file.Key -Force
}
但是在 PowerShell 中,此脚本需要大约 300 秒才能移动 1000 个文件,其他人有同样的经历吗?希望答案是我在这里采取了错误的方法,因为我很想能够使用 PowerShell 来完成这项任务!
答案1
这里造成性能差异的原因有两个:
- Powershell 在单个线程中上传
- 您正在按顺序复制每个文件
AWS CLI 速度更快,因为它使用多个线程(默认最多 10 个),因此可以同时执行多个操作。
您可以通过更改脚本来使用该-parallel
选项,限制并发操作的数量,从而加快速度。
foreach 将如下所示:
foreach -parallel -throttlelimit 10 ($file in $files){
Copy-S3Object -BucketName bucket -Key $file.Key -DestinationKey "$date/$($file.key)" -DestinationBucket newbucket Remove-S3Object -BucketName bucket -Key $file.Key -Force
}
根据您的系统,Windows 可能会限制您仅使用 5 个并行进程,但这仍然可以为您提供合理的速度。
答案2
aws s3
我的猜测是移动通过一个重复用于所有文件的 HTTPS 连接。
另一方面,每个PowerShell 的 Copy-S3Object
并Remove-S3Object
调用打开一个新的 HTTPS 连接,进行 SSL 握手等。如果您必须执行 1000 次,那么这将是一个巨大的开销。
这是我的猜测:)