You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure SDK for C++块Blob上传速度慢,如何开启并行/异步上传?

关于Azure SDK for C++块Blob上传优化与异步实现的问题解答

一、开启并行上传提升速度

新版Azure SDK for C++内置并行块上传能力,无需额外开关,可通过以下方式实现:

  1. 使用封装好的并行上传API(推荐)
    UploadFromBuffer/UploadFromFile方法已内置多线程分块上传逻辑,比手动调用StageBlock效率更高。示例代码:

    Azure::Storage::Blobs::BlockBlobClient blobClient = /* 初始化你的Blob客户端 */;
    Azure::Storage::Blobs::UploadBlockBlobOptions options;
    options.ParallelTransferOptions.MaxConcurrency = 8; // 设置并发线程数,可根据带宽调整为8-16
    options.ParallelTransferOptions.BlockSize = 4*1024*1024; // 块大小建议设为4MB-100MB
    
    // 从内存上传
    blobClient.UploadFromBuffer(data, length, options);
    // 从文件上传
    // blobClient.UploadFromFile("local-file-path", options);
    
  2. 手动实现并行StageBlock
    若需手动管理块上传,可借助C++标准库的std::thread或std::async实现并行调用,注意控制并发数、保证块ID唯一:

    std::vector<std::future<void>> futures;
    const int maxConcurrency = 8;
    
    while (buffer_size - buffer.size() < length) {
        int remaining = buffer_size - buffer.size();
        buffer.insert(buffer.end(), data + offset, data + offset + remaining);
        auto block_id = GetBlockId(std::to_string(m_block_count++));
        auto block_content = ::Azure::Core::IO::MemoryBodyStream(buffer.data(), buffer.size());
        uncomitted_blocks_ids.push_back(block_id);
    
        // 控制并发数,避免资源耗尽
        if (futures.size() >= maxConcurrency) {
            auto it = std::find_if(futures.begin(), futures.end(), [](auto& f) {
                return f.wait_for(std::chrono::seconds(0)) == std::future_status::ready;
            });
            if (it != futures.end()) {
                it->get(); // 处理异步任务结果及异常
                futures.erase(it);
            }
        }
    
        // 异步提交块上传任务
        futures.emplace_back(std::async(std::launch::async, [blockClient = blob_client.AsBlockBlobClient(), blockId = block_id, stream = std::move(block_content)]() {
            blockClient.StageBlock(blockId, stream);
        }));
    
        buffer.clear();
        offset += remaining;
        length -= remaining;
    }
    
    // 等待所有异步任务完成
    for (auto& f : futures) {
        f.get();
    }
    client.CommitBlockList(uncomitted_blocks_ids);
    

二、下载速度优化补充

针对下载速度提升有限的问题,可尝试调整以下参数:

  • 增大ParallelTransferOptions.BlockSize:默认块大小较小,建议设为4MB或更大,减少请求次数
  • 确认存储账户区域与客户端的物理距离:跨区域访问会显著影响速度
  • 使用DownloadToFile/DownloadToBuffer的重载版本:内置并行下载逻辑,比手动分块更高效

三、旧版upload_block_async的替代实现

新版SDK无直接对应方法,但可通过异步版StageBlock实现类似逻辑,SDK提供基于Azure::Core::Context的异步API:

// 异步调用StageBlock
auto stageBlockOp = blob_client.AsBlockBlobClient().StageBlockAsync(block_id, block_content, {}, Azure::Core::Context{});
// 等待异步操作完成
stageBlockOp.Get();

若需封装成独立异步方法,可结合std::future实现:

std::future<void> UploadBlockAsync(BlockBlobClient client, std::string blockId, Azure::Core::IO::MemoryBodyStream stream) {
    return std::async(std::launch::async, [client = std::move(client), blockId = std::move(blockId), stream = std::move(stream)]() {
        auto op = client.StageBlockAsync(blockId, stream, {}, Azure::Core::Context{});
        op.Get();
    });
}

内容的提问来源于stack exchange,提问作者John Doe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 12:27:42