【问题标题】:how to move multiple blobs in one transaction?如何在一个事务中移动多个 blob?
【发布时间】:2019-11-24 12:53:48
【问题描述】:

我们如何在一个事务中移动多个 blob?

我目前一次移动 1 个 blob,如下所示:

    public static async Task MoveBlobInSameStorageAccount(string name, string from, string to, string connection)
    {
        CloudStorageAccount.TryParse(connection, out CloudStorageAccount storageAccount);
        var blobClient = storageAccount.CreateCloudBlobClient();
        var sourceContainer = blobClient.GetContainerReference(from);
        var sourceBlob = sourceContainer.GetBlockBlobReference(name);
        var destinationContainer = blobClient.GetContainerReference(to);
        var destinationBlob = destinationContainer.GetBlockBlobReference(name);
        await destinationBlob.StartCopyAsync(sourceBlob);
        await sourceBlob.DeleteAsync();
    }

但是,我需要能够一次移动 5 到 10 个斑点。

我们如何将一个事务中的多个 blob 从源容器移动到目标容器?

【问题讨论】:

  • 你的意思是复制一个容器或者只是在容器中拾取一些 blob 来移动?
  • 我想传入一个指向特定 blob 的 uri 列表,并且该函数应在同一上下文/连接/事务中复制所有这些 blob

标签: c# .net azure-functions azure-blob-storage


【解决方案1】:

您可以使用Microsoft Azure Storage Data Movement Library。我最近在一个项目中使用它,效果很好。

具体来说,你要使用:

复制目录异步

GitHub repo 中有一个示例文件夹,您可以参考。我不需要示例中的大部分代码,因此我进行了修改:

BlobDirectoryCopySample

我还在示例文件夹中使用了Utils 类。您也可以设置 ParallelOperations,它“获取或设置一个值,指示要同时处理多少工作项”。

namespace DataMovementSamples
{
    using System;
#if !DOTNET5_4
#endif
    using System.Threading.Tasks;
    using Microsoft.Azure.Storage.DataMovement;

    public class Program
    {
        public static async Task Main(string[] args)
        {
            try
            {
                Console.WriteLine();
                Console.WriteLine("Data movement directory copy sample.");
                await BlobDirectoryCopySample();
            }
            finally
            {
                Console.WriteLine();
                Console.WriteLine("Cleanup generated data.");
            }
        }

        private static async Task BlobDirectoryCopySample()
        {
            var sourceBlobDir = await Util.GetCloudBlobDirectoryAsync("sourcecontainer", "dir1");
            var destBlobDir = await Util.GetCloudBlobDirectoryAsync("targetcontainer", "dir2");

            var options = new CopyDirectoryOptions()
            {
                Recursive = true,
            };

            var context = new DirectoryTransferContext();
            context.FileTransferred += FileTransferredCallback;
            context.FileFailed += FileFailedCallback;
            context.FileSkipped += FileSkippedCallback;

            TransferManager.Configurations.ParallelOperations = 50;
            Console.WriteLine("Transfer started");

            try
            {
                Task task = TransferManager.CopyDirectoryAsync(sourceBlobDir, destBlobDir, false, options, context);
                await task;
            }
            catch (Exception e)
            {
                Console.WriteLine("The transfer is cancelled: {0}", e.Message);
            }

            Console.WriteLine("The transfer is completed.");
        }

        private static void FileTransferredCallback(object sender, TransferEventArgs e)
        {
            Console.WriteLine("Transfer Succeeds. {0} -> {1}.", e.Source, e.Destination);
        }

        private static void FileFailedCallback(object sender, TransferEventArgs e)
        {
            Console.WriteLine("Transfer fails. {0} -> {1}. Error message:{2}", e.Source, e.Destination, e.Exception.Message);
        }

        private static void FileSkippedCallback(object sender, TransferEventArgs e)
        {
            Console.WriteLine("Transfer skips. {0} -> {1}.", e.Source, e.Destination);
        }
    }
}

【讨论】:

  • 非常感谢,这真的很好。我希望能够将 3 个不同的 blob 传递给我的函数,结果是它们都将被上传到同一个“流”或任何你称之为的东西中
  • 据我所知,CopyDirectoryAsync 是在一个事务中移动一组 blob 的唯一方法。您可以使用 CopyAsync,但仍会一次处理一个,这不能满足您的要求。
  • 再次感谢!切线...我担心竞争条件,假设我有 2 个独立的进程将文件从同一个容器中移开...我如何确保它们不会相互踩踏?
  • 我也有类似的担忧,最终使用了一个进程来处理这个问题。我不认为 TransferManager.CopyDirectoryAsync 是线程安全的。你必须自己管理。用锁应该很容易。
猜你喜欢
  • 1970-01-01
  • 2022-01-11
  • 2017-08-29
  • 2020-03-31
  • 2015-03-27
  • 2014-03-05
  • 2017-03-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多