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

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

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

针对上传进行性能优化

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

设置上传的传输选项

可以配置 BlockBlobParallelUploadOptions 中的属性以提高数据传输操作的性能。 下表列出了可以配置的属性及其说明:

属性 说明
blockSize 作为上传操作一部分的每个请求传输的最大块大小。 要了解详细信息,请参阅 blockSize
maxSingleShotSize 如果数据的大小小于或等于此值,则会在单个放置操作中上传,而不是拆分成区块。 如果一次性上传数据,则会忽略块大小。 默认值为 256 MB。 如果自定义此属性,则必须使用小于或等于 256 MB 的值。 若要了解详细信息,请参阅 maxSingleShotSize
concurrency 在任何给定时间,作为单个并行传输的一部分发出的最大并行请求数量。

注意

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

maxSingleShotSize

maxSingleShotSize 值是单个请求上传的最大 blob 大小(以字节为单位)。

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

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

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

blockSize

blockSize 值是以区块形式上传块 blob 时传输的最大长度(以字节为单位)。

如前所述,此值不限制 maxSingleShotSize,后者可以大于 blockSize

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

代码示例

以下代码示例演示如何设置 BlockBlobParallelUploadOptions 的值并将选项作为上传方法调用的一部分包含在内。 此示例中提供的值不作为建议。 若要正确优化这些值,需要考虑应用的特定需求。

// Specify data transfer options
const uploadOptions = {
  blockSize: 4 * 1024 * 1024, // 4 MiB max block size
  concurrency: 2, // maximum number of parallel transfer workers
  maxSingleShotSize: 8 * 1024 * 1024, // 8 MiB initial transfer size
} 

// Create blob client from container client
const blockBlobClient = containerClient.getBlockBlobClient(blobName);

// Upload blob with transfer options
await blockBlobClient.uploadFile(localFilePath, uploadOptions);

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

上传的性能注意事项

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

注意

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

上传期间的缓冲

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

针对下载进行性能优化

仅当使用 downloadToBuffer 方法时,才能针对下载优化数据传输选项。 此方法根据 BlobDownloadToBufferOptions 中定义的值并行下载 blob。 其他下载方法不支持优化数据传输选项。

设置下载的传输选项

使用 downloadToBuffer 方法时,可以优化以下值以供下载:

  • blockSize:要为每个请求传输的最大块大小。
  • concurrency:作为单个并行传输的一部分,在任何给定时间发出的最大并行请求数。

下载的性能注意事项

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

代码示例

下面的代码示例演示如何设置 BlobDownloadToBufferOptions 的值,并将这些选项包含在 downloadToBuffer 方法调用中。 此示例中提供的值不作为建议。 若要正确优化这些值,需要考虑应用的特定需求。

// Specify data transfer options
const downloadToBufferOptions = {
    blockSize: 4 * 1024 * 1024, // 4 MiB max block size
    concurrency: 2, // maximum number of parallel transfer workers
}

// Download data to buffer
const result = await client.downloadToBuffer(offset, count, downloadToBufferOptions);