Azure Storage Data Movement Library复制远慢于AzCopy的问题咨询
优化C# Azure Blob批量小文件上传速度,对齐AzCopy性能
测试场景
- 测试环境:
- 一个Azure Blob存储测试账户
- 本地文件夹包含约3000个小文件(单文件大小200字节)
- AzCopy执行结果:
运行以下命令耗时约2秒:azcopy copy --recursive "c:\localDir\*" "https://BLOBConnectionString" - 现有C#代码执行结果:
以下代码耗时约1分钟:ServicePointManager.Expect100Continue = false; ServicePointManager.DefaultConnectionLimit = 32; TransferManager.Configurations.ParallelOperations = 32; var account = CloudStorageAccount.Parse("https://BLOBConnectionString"); CloudBlobClient client = account.CreateCloudBlobClient(); CloudBlobContainer container = client.GetContainerReference("container"); await container.CreateIfNotExistsAsync(); CloudBlobDirectory destinationBlob = container.GetDirectoryReference("data"); await TransferManager.UploadDirectoryAsync(@"c:\localDir\", destinationBlob);
优化方案及代码示例
核心问题
旧版TransferManager属于Legacy Azure Storage SDK,和AzCopy基于的最新SDK在性能优化上差距显著,且默认并行度设置偏低,未针对小文件上传做特殊适配。
优化后的代码
改用最新的Azure.Storage.Blobs SDK,并调整并行策略与HTTP配置:
using Azure.Storage.Blobs; using Azure.Storage.Blobs.Models; using System.Net; using System.IO; // 优化HTTP连接参数,适配小文件传输 ServicePointManager.Expect100Continue = false; ServicePointManager.DefaultConnectionLimit = 100; ServicePointManager.UseNagleAlgorithm = false; // 关闭Nagle算法,减少TCP延迟 string connectionString = "https://BLOBConnectionString"; BlobServiceClient blobServiceClient = new BlobServiceClient(connectionString); BlobContainerClient containerClient = blobServiceClient.GetBlobContainerClient("container"); await containerClient.CreateIfNotExistsAsync(); string localDirPath = @"c:\localDir\"; string[] allFiles = Directory.GetFiles(localDirPath, "*", SearchOption.AllDirectories); // 设置高并行度,匹配AzCopy的批量处理能力 ParallelOptions parallelOpts = new ParallelOptions { MaxDegreeOfParallelism = 100 }; await Parallel.ForEachAsync(allFiles, parallelOpts, async (filePath, cancellationToken) => { // 计算文件相对路径,保持目录结构 string relativePath = Path.GetRelativePath(localDirPath, filePath); BlobClient blobClient = containerClient.GetBlobClient($"data/{relativePath}"); // 小文件直接单请求上传,禁用分块避免额外开销 await blobClient.UploadAsync( filePath, new BlobUploadOptions { TransferOptions = new StorageTransferOptions { MaximumConcurrency = 1, InitialTransferSize = 4 * 1024 * 1024 // 小文件用单请求完成 } }, cancellationToken); });
关键优化点
- SDK升级:新的
Azure.Storage.Blobs和AzCopy共享底层实现,自带连接池优化、请求复用等性能特性,远优于旧版SDK。 - 并行度调整:提升并行操作数到100,适配小文件批量上传场景,最大化利用网络资源。
- 小文件上传策略:禁用分块上传,避免分块带来的多次HTTP请求开销,小文件直接通过单请求完成传输。
- HTTP配置优化:关闭Nagle算法减少小数据包的TCP延迟,提升连接池上限确保并行请求有足够的可用连接。
内容的提问来源于stack exchange,提问作者Denis Orlov
相关产品推荐
相关产品推荐

