【问题标题】:Azure Blobs C# client - using multiple filters server sideAzure Blobs C# 客户端 - 使用多个过滤器服务器端
【发布时间】:2021-03-03 17:08:37
【问题描述】:

我正在尝试加载 blob 名称以在我的程序中进行过滤,然后在应用所有过滤器后,我计划下载并处理每个 blob。 目前我们有大约 30k 的 blob 存储在容器中,如下所示: 年/月/日/小时/file.csv(或 file.json 用于未处理的文件)

我的程序需要动态输入开始和结束日期(最长 30 天)以进行下载。使用 Azure.Storage.Blobs.BlobContainerItem 和 GetBlobs 方法允许我使用单个字符串前缀进行服务器端过滤。

如果我的日期是 2020/06/01 和 2020/06/02,程序运行速度非常快,大约需要 2 秒来获取 blob 并将其余过滤器应用于它。但是,如果我有 2020/05/30 和 2020/06/01,那么我无法放置月份前缀,因为它只需要 1 个字符串,所以我的前缀将只是 2020,大约需要 15 秒才能完成。其余的过滤在本地完成,但最大的延迟是 GetBlobs() 函数。

还有其他方法可以在 .NETCore 应用程序中使用服务器端的多个过滤器吗?

以下是相关功能:

        BlobContainerClient container = new BlobContainerClient(resourceGroup.Blob, resourceGroup.BlobContainer);
        var blobs = container.GetBlobs(prefix : CreateBlobPrefix(start, end))
            .Select(item=> item.Name)
            .ToList();
        blobs = FilterBlobList(blobs, filter, start, end);

    private string CreateBlobPrefix(DateTime start, DateTime end)
    {
        string prefix = null;
        bool sameYear = start.Year == end.Year;
        bool sameMonth = start.Month == end.Month;
        bool sameDay = start.Day == end.Day;
        if (sameYear)
        {
            prefix = start.Year.ToString();
            if (sameMonth)
            {
                if(start.Month<10)
                    prefix += "/0" + start.Month.ToString();
                else
                    prefix += "/" + start.Month.ToString();
                if (sameDay) 
                    if(start.Day<10)
                        prefix += "/0" + start.Day.ToString();
                    else
                        prefix += "/" + start.Day.ToString();
            }
        }
        return prefix;

编辑:这就是我最后的做法。因为使用更好的指定前缀发出多个请求会更快,所以我做了以下操作:

  • 在选定的时间窗口中创建不同日期的列表(来自用户输入任何窗口的 UI 应用程序)
  • 对于创建的每个前缀,我都会向 Azure 发送请求以获取 blob
  • 将所有 blob 名称合并到 1 个列表中
  • 对每个 blob 名称使用 blob 客户端处理列表

代码如下:

        foreach (var blobPrefix in CreateBlobPrefix(start, end))
        {
            var currentList = container.GetBlobs(prefix: blobPrefix)
                .Select(item => item.Name)
                .ToList();
            blobs = blobs.Concat(currentList).ToList();
        }

【问题讨论】:

  • 这个问题怎么样?下面的答案是否解决了您的问题,如果是,您可以接受它作为答案,这样它可以帮助遇到相同问题的其他社区成员,我们可以存档这个帖子,谢谢。
  • 我有点忘记在阅读您的答案后重新访问该页面。是的,它帮助我找到了类似于您所写内容的良好解决方案。谢谢
  • 我已经添加了我使用的代码,但请分享你的!
  • 您介意添加 CreateBlobPrefix(start, end) 的实现吗?

标签: azure .net-core blob azure-storage azure-blob-storage


【解决方案1】:

您可以多次过滤,找出日期之间的共同点:

首先使用字符串前缀按开始月份和年份 2020/05 进行筛选,然后在本地筛选确切日期。

然后您可以逐渐增加日/月过滤器,直到达到范围的末尾。

步进的粒度实际上取决于为给定的平均结果数调用 Azure 所需的时间。 另一个优点是您可以并行运行这些子查询。

我用过这段代码:

    var prefixDateFilters = Enumerable.Range(0, 1 + endDateInclusive.Subtract(startDateInclusive).Days)
                                      .Select(offset => startDateInclusive.AddDays(offset))
                                      .Select(date => $"{date.ToString(BlobFileDateTimeFormat)}").ToList();

    prefixFilters.AsParallel()
                 .Select(filter => containerClient.GetBlobs(prefix: filter))

【讨论】:

    猜你喜欢
    • 2022-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-04
    相关资源
    最近更新 更多