使用Azure Java SDK V12和ListBlobs()列出Azure Blobstorage中的Blob非常慢

时间:2020-08-05 14:33:43

标签: java azure azure-blob-storage azure-java-sdk

我需要列出Azure Blobstorage容器中的所有blob。该容器中大约有200,000个Blob,我正在寻找该Blob名称,最后修改日期和Blob大小。

按照Azure Java SDK V12的文档,以下代码应该可以工作:

BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().connectionString(AzureBlobConnectionString).buildClient();
String containerName = "container1";
BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(containerName);
System.out.println("\nListing blobs...");

// List the blob(s) in the container.
for (BlobItem blobItem : containerClient.listBlobs()) {
  System.out.println("\t" + blobItem.getName());
}

但是,执行该应用程序时似乎无限期地挂起。如果我打开Powershell并运行以下命令:

Get-AzStorageBlob -Container container1 -Context $ctx

我在大约3分钟内得到了预期的结果。

我已经给出了一个小时以上的代码示例来执行,但没有任何结果。我试图限制文档中要求的数据,并设置5分钟的超时时间:

BlobServiceClient blobServiceClient = new BlobServiceClientBuilder().connectionString(AzureBlobConnectionString).buildClient();
String containerName = "container1";
BlobContainerClient containerClient = blobServiceClient.getBlobContainerClient(containerName);
System.out.println("\nListing blobs...");

ListBlobsOptions options = new ListBlobsOptions()
        .setMaxResultsPerPage(10)
        .setDetails(new BlobListDetails()
                .setRetrieveDeletedBlobs(false)
                .setRetrieveSnapshots(true));
Duration duration = Duration.ofMinutes(5);
containerClient.listBlobs(options, duration).forEach(blob ->
        System.out.printf("Name: %s, Directory? %b, Deleted? %b, Snapshot ID: %s%n",
                blob.getName(),
                blob.isPrefix(),
                blob.isDeleted(),
                blob.getSnapshot()));

但是这导致超时,但例外:

Exception in thread "main" reactor.core.Exceptions$ReactiveException: java.util.concurrent.TimeoutException: Did not observe any item or terminal signal within 300000ms in 'flatMap' (and no fallback has been configured)
at reactor.core.Exceptions.propagate(Exceptions.java:366)
at reactor.core.publisher.BlockingIterable$SubscriberIterator.hasNext(BlockingIterable.java:168)
at java.lang.Iterable.forEach(Iterable.java:74)
at AzureManagement.AzureControl.listAllBlobs(AzureControl.java:42)
at Main.main(Main.java:8)

我了解过去曾经有一种名为“ listBlobsSegmented”的方法,但是,Azure SDK for Java V12中似乎没有这种方法。

如果有人对如何有效,高效地获取容器中的斑点列表有任何想法,我将不胜感激!

谢谢。

1 个答案:

答案 0 :(得分:0)

任何永久挂起的操作都面临着完全相同的问题。实际上,您在列出Blob的方式上没有问题。

原来是依赖性冲突问题,请确保与Azure SDK的依赖性没有冲突。看起来很奇怪,但是我们在将Azure SDK版本从12降级到较旧版本时发现了这一点,而不是将其挂起,抛出诸如method not found in class ...

这样的异常

在我的情况下,冲突来自hadoop-hdfs,它强制使用旧版本的netty。而Azure SDK需要更新的netty版本。

当我删除HDFS依赖项时: group: 'org.apache.hadoop', name: 'hadoop-hdfs', version: '3.2.0' 我可以列出文件和Blob,而不会出现挂起问题。