存储库分析 API编辑

分析存储库,报告其性能特征和发现的任何错误行为。

response = client.snapshot.repository_analyze(
  repository: 'my_repository',
  blob_count: 10,
  max_blob_size: '1mb',
  timeout: '120s'
)
puts response
POST /_snapshot/my_repository/_analyze?blob_count=10&max_blob_size=1mb&timeout=120s

请求编辑

POST /_snapshot/<repository>/_analyze

先决条件编辑

  • 如果启用了 Elasticsearch 安全功能,您必须具有 manage 集群权限 才能使用此 API。有关更多信息,请参阅 安全权限
  • 如果启用了 操作员权限功能,则只有操作员用户才能使用此 API。

描述编辑

有大量的第三方存储系统可用,并非所有这些系统都适合用作 Elasticsearch 的快照存储库。一些存储系统行为不当,或者性能很差,尤其是在 Elasticsearch 集群节点作为多个客户端同时访问时。

存储库分析 API 对您的存储库执行一系列读写操作,这些操作旨在检测错误行为并衡量存储系统的性能特征。

此 API 参数的默认值故意设置得很低,以减少无意中运行分析的影响,并为您的调查提供一个合理的起点。使用默认参数值运行您的第一个分析以检查简单问题。如果成功,则运行一系列越来越大的分析,直到遇到故障或达到 blob_count 至少为 2000max_blob_size 至少为 2gbmax_total_data_size 至少为 1tb 以及 register_operation_count 至少为 100。始终指定一个宽裕的超时时间,可能为 1h 或更长,以允许每个分析有足够的时间运行到完成。使用与生产集群大小类似的多节点集群执行分析,以便它可以检测到仅在存储库被多个节点同时访问时才会出现的任何问题。

如果分析失败,则 Elasticsearch 检测到您的存储库行为异常。这通常意味着您正在使用第三方存储系统,该系统对它声称支持的 API 具有不正确或不兼容的实现。如果是这样,则此存储系统不适合用作快照存储库。您需要与存储系统供应商合作以解决 Elasticsearch 检测到的不兼容性。有关更多信息,请参阅 自管理存储库类型

如果分析成功,则此 API 返回测试过程的详细信息,可以选择包括每个操作花费的时间。您可以使用此信息来确定存储系统的性能。如果任何操作失败或返回错误结果,则此 API 返回错误。如果 API 返回错误,则它可能没有删除写入存储库的所有数据。错误将指示任何剩余数据的存储位置,并且此路径也记录在 Elasticsearch 日志中。您应该自己验证此位置是否已正确清理。如果指定位置仍然存在剩余数据,则应手动将其删除。

如果客户端在等待分析结果时与 Elasticsearch 的连接关闭,则测试将被取消。某些客户端配置为在没有收到响应的情况下在特定超时时间内关闭其连接。分析需要很长时间才能完成,因此您可能需要放宽任何此类客户端端超时时间。取消时,分析尝试清理正在写入的数据,但它可能无法删除所有数据。剩余数据的路径记录在 Elasticsearch 日志中。您应该自己验证此位置是否已正确清理。如果指定位置仍然存在剩余数据,则应手动将其删除。

如果分析成功,则它检测到没有错误行为,但这并不意味着可以保证正确行为。分析试图检测常见错误,但它当然不提供 100% 的覆盖率。此外,它不会测试以下内容

  • 您的存储库必须执行持久写入。写入 blob 后,它必须保留在原位,直到被删除,即使在断电或类似灾难之后也是如此。
  • 您的存储库不得出现静默数据损坏。写入 blob 后,其内容必须保持不变,直到被故意修改或删除。
  • 即使集群的连接中断,您的存储库也必须正常运行。在这种情况下,读写可能会失败,但它们不得返回错误结果。

分析会向您的存储库写入大量数据,然后再次读取。这会消耗集群和存储库之间网络上的带宽,以及存储库本身的存储空间和 IO 带宽。您必须确保此负载不会影响这些系统的其他用户。分析会尊重存储库设置 max_snapshot_bytes_per_secmax_restore_bytes_per_sec(如果可用),以及集群设置 indices.recovery.max_bytes_per_sec,您可以使用它来限制它们消耗的带宽。

此 API 旨在供人类探索使用。您应该预期请求参数和响应格式在将来的版本中会发生变化。

不同版本的 Elasticsearch 可能会执行不同的存储库兼容性检查,较新版本通常比旧版本更严格。通过一个版本的 Elasticsearch 通过存储库分析的存储系统可能会在另一个版本中失败。这表明它以以前版本未检测到的方式表现不当。您必须与存储系统供应商合作以解决 Elasticsearch 的任何版本中的存储库分析 API 检测到的不兼容性。

此 API 可能无法在混合版本集群中正常工作。

实现细节编辑

本节文档描述了存储库分析 API 在此版本的 Elasticsearch 中的工作原理,但您应该预期实现会在不同版本之间有所不同。请求参数和响应格式取决于实现的细节,因此在较新版本中也可能有所不同。

分析包括许多 blob 级任务,由 blob_count 参数设置,以及许多在可线性化寄存器上的比较和交换操作,由 register_operation_count 参数设置。这些任务分布在集群中的数据和主节点候选节点上以供执行。

对于大多数 blob 级任务,执行节点首先将 blob 写入存储库,然后指示集群中的其他一些节点尝试读取它刚刚写入的数据。blob 的大小是随机选择的,根据 max_blob_sizemax_total_data_size 参数。如果这些读取中的任何一个失败,则存储库没有实现 Elasticsearch 所需的必要读后写语义。

对于某些 blob 级任务,执行节点将指示其一些对等节点在写入过程完成之前尝试读取数据。这些读取允许失败,但不得返回部分数据。如果任何读取返回部分数据,则存储库没有实现 Elasticsearch 所需的必要原子性语义。

对于某些 blob 级任务,执行节点将在其对等节点读取 blob 时覆盖 blob。在这种情况下,读取的数据可能来自原始 blob 或覆盖的 blob,但读取操作不得返回部分数据或来自两个 blob 的数据混合。如果这些读取中的任何一个返回部分数据或两个 blob 的数据混合,则存储库没有实现 Elasticsearch 对覆盖所需必要的原子性语义。

执行节点将使用各种不同的方法来写入 blob。例如,在适用情况下,它将同时使用单部分和多部分上传。类似地,读取节点将使用各种不同的方法来再次读取数据。例如,它们可以从头到尾读取整个 blob,或者可以只读取数据的子集。

对于某些 blob 级任务,执行节点将在写入完成之前中止写入。在这种情况下,它仍然指示集群中的其他一些节点尝试读取 blob,但所有这些读取都必须无法找到 blob。

线性化寄存器是 Elasticsearch 使用原子比较并交换操作来操作的特殊 Blob。即使多个节点同时访问 Blob,此操作也能确保正确且强一致的行为。线性化寄存器上比较并交换操作的详细实现因存储库类型而异。存储库分析验证了对线性化寄存器 Blob 的无竞争比较并交换操作始终成功。存储库分析还验证了竞争操作要么成功,要么报告竞争,但不会返回错误的结果。如果操作因竞争而失败,Elasticsearch 会重试操作,直到成功。存储库分析执行的大多数比较并交换操作都会原子地递增一个计数器,该计数器表示为一个 8 字节的 Blob。一些操作还会验证对大小不为 8 字节的小 Blob 的行为。

路径参数编辑

<repository>
(必需,字符串) 要测试的快照存储库的名称。

查询参数编辑

blob_count
(可选,整数) 测试期间写入存储库的 Blob 总数。默认为 100。对于现实的实验,您应该将其设置为至少 2000
max_blob_size
(可选,大小单位) 测试期间写入的 Blob 的最大大小。默认为 10mb。对于现实的实验,您应该将其设置为至少 2gb
max_total_data_size
(可选,大小单位) 测试期间写入的所有 Blob 的总大小的上限。默认为 1gb。对于现实的实验,您应该将其设置为至少 1tb
register_operation_count
(可选,整数) 要执行的线性化寄存器操作的最小总数。默认为 10。对于现实的实验,您应该将其设置为至少 100
timeout
(可选,时间单位) 指定等待测试完成的时间段。如果在超时时间到期之前没有收到响应,则测试将被取消并返回错误。默认为 30s

高级查询参数编辑

以下参数允许对分析进行额外的控制,但您通常不需要调整它们。

concurrency
(可选,整数) 要并发执行的写入操作数。默认为 10
read_node_count
(可选,整数) 在写入每个 Blob 后执行读取操作的节点数。默认为 10
early_read_node_count
(可选,整数) 在写入每个 Blob 时执行早期读取操作的节点数。默认为 2。早期读取操作很少执行。
rare_action_probability
(可选,双精度) 对每个 Blob 执行罕见操作(早期读取、覆盖或中止写入)的概率。默认为 0.02
seed
(可选,整数) 用于生成测试期间执行的操作列表的伪随机数生成器的种子。要在多个实验中重复相同的操作集,请在每个实验中使用相同的种子。请注意,操作是并发执行的,因此在每次运行时可能并不总是按相同的顺序发生。
detailed
(可选,布尔值) 是否返回详细结果,包括分析期间执行的每个操作的计时信息。默认为 false,表示仅返回分析摘要。
rarely_abort_writes
(可选,布尔值) 是否很少中止一些写入请求。默认为 true

响应主体编辑

响应公开了分析的实现细节,这些细节可能会在不同版本之间发生变化。因此,响应主体格式不被认为是稳定的,并且在较新的版本中可能会有所不同。

coordinating_node

(对象) 标识协调分析并执行最终清理的节点。

coordinating_node 的属性
id
(字符串) 协调节点的 ID。
name
(字符串) 协调节点的名称
repository
(字符串) 作为分析主题的存储库的名称。
blob_count
(整数) 测试期间写入存储库的 Blob 数,等于 ?blob_count 请求参数。
concurrency
(整数) 测试期间并发执行的写入操作数,等于 ?concurrency 请求参数。
read_node_count
(整数) 在写入每个 Blob 后执行读取操作的节点数的限制,等于 ?read_node_count 请求参数。
early_read_node_count
(整数) 在写入每个 Blob 后执行早期读取操作的节点数的限制,等于 ?early_read_node_count 请求参数。
max_blob_size
(字符串) 测试期间写入的 Blob 大小的限制,等于 ?max_blob_size 参数。
max_blob_size_bytes
(长整数) 测试期间写入的 Blob 大小的限制(以字节为单位),等于 ?max_blob_size 参数。
max_total_data_size
(字符串) 测试期间写入的所有 Blob 的总大小的限制,等于 ?max_total_data_size 参数。
max_total_data_size_bytes
(长整数) 测试期间写入的所有 Blob 的总大小的限制(以字节为单位),等于 ?max_total_data_size 参数。
seed
(长整数) 用于生成测试期间使用的操作的伪随机数生成器的种子。如果设置,则等于 ?seed 请求参数。
rare_action_probability
(双精度) 测试期间执行罕见操作的概率。等于 ?rare_action_probability 请求参数。
blob_path
(字符串) 测试期间写入所有 Blob 的存储库中的路径。
issues_detected
(列表) 检测到的正确性问题列表,如果 API 成功,则该列表将为空。包含以强调成功响应并不保证将来行为正确。
summary

(对象) 一组统计信息,总结了测试结果。

summary 的属性
write

(对象) 一组统计信息,总结了测试中写入操作的结果。

write 的属性
count
(整数) 测试中执行的写入操作数。
total_size
(字符串) 测试中写入的所有 Blob 的总大小。
total_size_bytes
(长整数) 测试中写入的所有 Blob 的总大小(以字节为单位)。
total_throttled
(字符串) 由于 max_snapshot_bytes_per_sec 节流而花费的总等待时间。
total_throttled_nanos
(长整数) 由于 max_snapshot_bytes_per_sec 节流而花费的总等待时间(以纳秒为单位)。
total_elapsed
(字符串) 测试中写入 Blob 所花费的总时间。
total_elapsed_nanos
(长整数) 测试中写入 Blob 所花费的总时间(以纳秒为单位)。
read

(对象) 一组统计信息,总结了测试中读取操作的结果。

read 的属性
count
(整数) 测试中执行的读取操作数。
total_size
(字符串) 测试中读取的所有 Blob 或部分 Blob 的总大小。
total_size_bytes
(长整数) 测试中读取的所有 Blob 或部分 Blob 的总大小(以字节为单位)。
total_wait
(字符串) 等待每个读取请求的第一个字节接收所花费的总时间。
total_wait_nanos
(长整数) 等待每个读取请求的第一个字节接收所花费的总时间(以纳秒为单位)。
max_wait
(字符串) 等待任何读取请求的第一个字节接收所花费的最大时间。
max_wait_nanos
(长整数) 等待任何读取请求的第一个字节接收所花费的最大时间(以纳秒为单位)。
total_throttled
(字符串) 由于 max_restore_bytes_per_secindices.recovery.max_bytes_per_sec 节流而花费的总等待时间。
total_throttled_nanos
(长整数) 由于 max_restore_bytes_per_secindices.recovery.max_bytes_per_sec 节流而花费的总等待时间(以纳秒为单位)。
total_elapsed
(字符串) 测试中读取 Blob 所花费的总时间。
total_elapsed_nanos
(长整数) 测试中读取 Blob 所花费的总时间(以纳秒为单位)。
details

(数组) 测试期间执行的每个读取和写入操作的描述。这仅在 ?detailed 请求参数设置为 true 时返回。

details 中项目的属性
blob

(对象) 写入和读取的 Blob 的描述。

blob 的属性
name
(字符串) Blob 的名称。
size
(字符串) Blob 的大小。
size_bytes
(长整数) Blob 的大小(以字节为单位)。
read_start
(长整数) 读取操作开始的字节位置。
read_end
(长整数) 读取操作完成的字节位置。
read_early
(布尔值) 是否在写入操作完成之前开始任何读取操作。
overwritten
(布尔值) 是否在读取操作进行时覆盖了 Blob。
writer_node

(对象) 标识写入此 Blob 并协调读取操作的节点。

writer_node 的属性
id
(字符串) 写入节点的 ID。
name
(字符串) 写入节点的名称
write_elapsed
(字符串) 写入此 Blob 所花费的时间。
write_elapsed_nanos
(长整数) 写入此 Blob 所花费的时间(以纳秒为单位)。
overwrite_elapsed
(字符串) 覆盖此 Blob 所花费的时间。如果 Blob 未被覆盖,则省略。
overwrite_elapsed_nanos
(长整数) 覆盖此 Blob 所花费的时间(以纳秒为单位)。如果 Blob 未被覆盖,则省略。
write_throttled
(字符串) 等待 max_snapshot_bytes_per_sec(如果设置了 托管服务的恢复设置,则为 indices.recovery.max_bytes_per_sec)节流器的时间长度,同时写入此 Blob。
write_throttled_nanos
(长整数) 等待 max_snapshot_bytes_per_sec(如果设置了 托管服务的恢复设置,则为 indices.recovery.max_bytes_per_sec)节流器的时间长度(以纳秒为单位),同时写入此 Blob。
reads

(数组) 对此 Blob 执行的每个读取操作的描述。

reads 中项目的属性
node

(对象) 标识执行读取操作的节点。

node 的属性
id
(字符串) 读取节点的 ID。
name
(字符串) 读取节点的名称
before_write_complete
(布尔值) 是否可能在写入操作完成之前开始读取操作。如果为 false,则省略。
found
(布尔值) 此读取操作是否找到了 Blob。如果读取操作在写入完成之前开始,或者写入在完成之前被中止,则可能为 false
first_byte_time
(字符串) 等待接收读取操作的第一个字节的时间长度。如果未找到 Blob,则省略。
first_byte_time_nanos
(长整型) 等待接收读取操作的第一个字节的时间长度,以纳秒为单位。如果未找到 Blob,则省略。
elapsed
(字符串) 读取此 Blob 所花费的时间长度。如果未找到 Blob,则省略。
elapsed_nanos
(长整型) 读取此 Blob 所花费的时间长度,以纳秒为单位。如果未找到 Blob,则省略。
throttled
(字符串) 在读取此 Blob 期间,由于 max_restore_bytes_per_secindices.recovery.max_bytes_per_sec 节流而等待的时间长度。如果未找到 Blob,则省略。
throttled_nanos
(长整型) 在读取此 Blob 期间,由于 max_restore_bytes_per_secindices.recovery.max_bytes_per_sec 节流而等待的时间长度,以纳秒为单位。如果未找到 Blob,则省略。
listing_elapsed
(字符串) 检索容器中所有 Blob 列表所花费的时间。
listing_elapsed_nanos
(长整型) 检索容器中所有 Blob 列表所花费的时间,以纳秒为单位。
delete_elapsed
(字符串) 删除容器中所有 Blob 所花费的时间。
delete_elapsed_nanos
(长整型) 删除容器中所有 Blob 所花费的时间,以纳秒为单位。