使用 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 操作,以完成完整下载。

后续步骤