在Python中高效地将大量图像上载到Azure存储

在Python中高效地将大量图像上载到Azure存储,python,azure,performance,azure-storage,Python,Azure,Performance,Azure Storage,我需要找到一种最佳的方式来上传大量平均每幅图像大小约6MB的图像(多达几千张)。我们的服务是用Python编写的 我们有以下流程: 有一个服务创建了一个BlobServiceClient。我们正在使用CertificateCredentials进行身份验证 服务在Linux上的容器中运行,并用Python代码编写 服务正在接收一条消息,每条消息都有6到9个图像作为Numpy ndarray+JSON元数据对象 每次收到消息时,我们都会使用最大线程数为20的ThreadPoolExecutor将所

我需要找到一种最佳的方式来上传大量平均每幅图像大小约6MB的图像(多达几千张)。我们的服务是用Python编写的

我们有以下流程:

  • 有一个服务创建了一个BlobServiceClient。我们正在使用CertificateCredentials进行身份验证
  • 服务在Linux上的容器中运行,并用Python代码编写
  • 服务正在接收一条消息,每条消息都有6到9个图像作为Numpy ndarray+JSON元数据对象
  • 每次收到消息时,我们都会使用最大线程数为20的ThreadPoolExecutor将所有文件和JSON文件发送到存储器
  • 我们没有使用库的异步版本
  • 经过裁剪和简化的代码如下所示(下面的代码不起作用,只是一个示例,azurestorageclient是Azure Python SDK的外包装器。它有一个BlobServiceClient实例,我们用来创建容器和上载Blob):

    我们观察到,在信号强度波动较大的慢速网络中上载文件时,此类服务的性能非常差

    我们现在正试图找到并衡量如何提高性能的不同选项:

  • 我们将首先将文件存储到硬盘,然后不时将其上传到更大的块中
  • 我们认为上传一个大文件的性能应该更好(例如,将100个文件上传到zip/tar文件中)
  • 我们认为,在连接不好时减少并行作业的数量也应该更好
  • 我们考虑使用AZPoT代替Python 对于如何在这样的场景中工作,有没有其他的建议或Python代码示例?或者我们应该改变一个用来上传数据的服务?例如,使用ssh连接到VM并以这种方式上载文件(我怀疑它会更快,但得到了这样的建议)


    Mike

    根据您的情况,我建议您将一些文件压缩为一个大文件,并将大文件分块上传。关于如何分块上传文件,您可以使用方法
    BlobClient.stage\u block
    BlobClient.commit\u block\u list
    来实现它

    比如说

    block_list=[]
    chunk_size=1024
    with open('csvfile.csv','rb') as f:
       
       while True:
            read_data = f.read(chunk_size)
            if not read_data:
                break # done
            blk_id = str(uuid.uuid4())
            blob_client.stage_block(block_id=blk_id,data=read_data) 
            block_list.append(BlobBlock(block_id=blk_id))
            
    
    blob_client.commit_block_list(block_list)
    

    这是我们考虑的一个选项,但是,我们需要在存储上单独的文件,所以我们需要触发一个后台进程,它将解压缩并在那里做其他工作。我们还没有计算成本…@Kokos如果是的话,我认为你可以将每个文件分小块上传,而不是直接将整个文件内容上传到azure blob。另外,azcopy是个不错的选择。嗯,很有趣。我的想法正好相反(增加块大小,以便一次发送所有文件)。此外,我认为,当网络条件不好时,我们应该减少并行性——同时连接太多。你觉得怎么样?@Kokos它可能有用。根据情况,azcopy是一个更好的选择。
    block_list=[]
    chunk_size=1024
    with open('csvfile.csv','rb') as f:
       
       while True:
            read_data = f.read(chunk_size)
            if not read_data:
                break # done
            blk_id = str(uuid.uuid4())
            blob_client.stage_block(block_id=blk_id,data=read_data) 
            block_list.append(BlobBlock(block_id=blk_id))
            
    
    blob_client.commit_block_list(block_list)