优化使用 Java 的上传和下载性能

当应用程序使用适用于 Java 的 Azure 存储客户端库传输数据时,有几个因素可能会影响请求的速度、内存使用情况,甚至影响请求是否成功。 若要最大程度提高数据传输的性能和可靠性,必须主动根据应用运行的环境来配置客户端库传输选项。

本文将带你详细了解在优化数据传输选项时的几点注意事项。 正确优化后,客户端库可以有效地跨多个请求分发数据,从而提高操作速度、内存使用率和网络稳定性。

针对上传进行性能优化

合理优化数据传输选项是确保可靠的上传性能的关键。 根据这些参数中的值,将存储传输划分为多个子传输。 支持的最大传输大小因操作和服务版本而异,因此请务必查看文档以确定限制。 若要详细了解 Blob 存储的传输大小限制,请参阅 Blob 存储的缩放目标

设置上传的传输选项

可以在 ParallelTransferOptions 中配置值,以提高数据传输操作的性能。 可根据应用需求优化要上传的以下值:

  • maxSingleUploadSize:单个请求上传的最大 blob 大小(以字节为单位)。
  • blockSize:要为每个请求传输的最大块大小。
  • maxConcurrency:作为单个并行传输的一部分,在任何给定时间发出的最大并行请求数。

注意

对于未提供的数据传输选项,客户端库将会使用默认值。 这些默认值通常在数据中心环境中表现良好,但不太可能适合家庭使用者环境。 数据传输优化不当可能会导致操作时间过长,甚至请求超时。 最好主动测试这些值,并根据应用程序和环境的需求优化它们。

maxSingleUploadSize

maxSingleUploadSize 值是单个请求上传的最大 blob 大小(以字节为单位)。 可以使用以下方法设置此值:

如果数据大小小于或等于 maxSingleUploadSize,则通过单个放置 Blob 请求上传 blob。 如果 blob 大小大于 maxSingleUploadSize,或者 blob 大小未知,则使用一系列放置块调用(后跟放置块列表)以区块形式上传 blob。

请务必注意,为 blockSize 指定的值不会限制为 maxSingleUploadSize 定义的值。 参数“maxSingleUploadSize”为一次执行整个操作的初始请求定义了单独的大小限制,没有子传输。 通常情况下,你希望 maxSingleUploadSize 至少与你为 blockSize 定义的值一样大(即便不是更大)。 根据数据传输的大小,这种方法可以更高效,因为传输是通过单个请求完成的,避免了多个请求的开销。

如果不确定什么值最适合你的情况,一个安全的选择是将 maxSingleUploadSize 设置为用于 blockSize 的值。

blockSize

blockSize 值是以区块形式上传块 blob 时传输的最大长度(以字节为单位)。 可以使用以下方法设置此值:

blockSize 值是以区块形式上传块 blob 时传输的最大长度(以字节为单位)。 如前所述,此值不限制 maxSingleUploadSize,后者可以大于 blockSize

为了保持数据高效移动,客户端库可能不会每次传输都达到 blockSize 值。 根据操作的不同,传输大小的最大支持值可能会有所不同。 若要详细了解 Blob 存储的传输大小限制,请参阅 Blob 存储的缩放目标中的图表。

maxConcurrency

maxConcurrency 值是作为单个并行传输的一部分,在任何给定时间发出的最大并行请求数。 可以使用以下方法设置此值:

代码示例

请确保具有以下 import 指令,以便对上传使用 ParallelTransferOptions

import com.azure.storage.blob.models.*;

以下代码示例演示如何设置 ParallelTransferOptions 的值,并将这些选项添加到 BlobUploadFromFileOptions 实例中。 如果不从文件上传,可以使用 BlobParallelUploadOptions 设置类似的选项。 此示例中提供的值不作为建议。 若要正确优化这些值,需要考虑应用的特定需求。

ParallelTransferOptions parallelTransferOptions = new ParallelTransferOptions()
        .setBlockSizeLong((long) (4 * 1024 * 1024)) // 4 MiB block size
        .setMaxConcurrency(2)
        .setMaxSingleUploadSizeLong((long) 8 * 1024 * 1024); // 8 MiB max size for single request upload

BlobUploadFromFileOptions options = new BlobUploadFromFileOptions("<localFilePath>");
options.setParallelTransferOptions(parallelTransferOptions);

Response<BlockBlobItem> blockBlob = blobClient.uploadFromFileWithResponse(options, null, null);

在此示例中,我们使用 setMaxConcurrency 方法将并行传输辅助角色的最大数目设置为 2。 我们还使用 setMaxSingleUploadSizeLong 方法将 maxSingleUploadSize 设置为 8 MiB。 如果 blob 大小小于 8 MiB,则只需一个请求即可完成上传操作。 如果 blob 大小大于 8 MiB,则以区块形式上传 blob,最大区块大小为 4 MiB(我们使用 setBlockSizeLong 方法进行设置)。

上传的性能注意事项

在上传期间,存储客户端库会根据 ParallelTransferOptions 定义的配置选项将给定上传流拆分为多个子上传。 每个子上传都有自己的对 REST 操作的专用调用。 对于 BlobClient 对象,此操作是放置块。 存储客户端库并行管理这些 REST 操作(取决于传输选项),以完成完整上传。

注意

块 blob 的最大块计数为 50,000 个块。 那么,块 blob 的最大大小是 block_size 的 50,000 倍。

上传期间的缓冲

存储 REST 层不支持从你中断的地方继续执行 REST 上传操作;个别传输要么完成,要么丢失。 为了确保流上传的复原能力,存储客户端库会在开始上传之前为每个单独的 REST 调用缓冲数据。 除了网络速度限制之外,这种缓冲行为也是考虑较小的 blockSize 值的原因,即使在按顺序上传时也是如此。 减小 blockSize 的值会减少每个请求和每次重试失败请求时缓冲的最大数据量。 如果在特定大小的数据传输期间遇到频繁超时,则减小 blockSize 的值会减少缓冲时间,并可能提高性能。

针对下载进行性能优化

合理优化数据传输选项是确保可靠的下载性能的关键。 存储传输根据 ParallelTransferOptions 中定义的值分区为多个子传输。

设置下载的传输选项

可根据应用需求针对下载调整以下值:

  • blockSize:要为每个请求传输的最大块大小。 可以使用 setBlockSizeLong 方法设置此值。
  • maxConcurrency:在任何给定时间,作为单个并行传输的一部分发出的最大并行请求数量。 可以使用 setMaxConcurrency 方法设置此值。

代码示例

请确保具有以下 import 指令,以便对下载使用 ParallelTransferOptions

import com.azure.storage.common.*;

下面的代码示例演示如何设置 ParallelTransferOptions 的值,并将这些选项包含在 BlobDownloadToFileOptions 实例中。

ParallelTransferOptions parallelTransferOptions = new ParallelTransferOptions()
        .setBlockSizeLong((long) (4 * 1024 * 1024)) // 4 MiB block size
        .setMaxConcurrency(2);

BlobDownloadToFileOptions options = new BlobDownloadToFileOptions("<localFilePath>");
options.setParallelTransferOptions(parallelTransferOptions);

blobClient.downloadToFileWithResponse(options, null, null);

下载的性能注意事项

在下载期间,存储客户端库会根据 ParallelTransferOptions 定义的配置选项将给定下载请求拆分为多个子下载。 每个子下载都有自己的对 REST 操作的专用调用。 根据传输选项,客户端库会并行管理这些 REST 操作,以完成完整下载。

后续步骤