仓库分析 API

编辑

分析仓库,报告其性能特征以及发现的任何不正确的行为。

resp = client.perform_request(
    "POST",
    "/_snapshot/my_repository/_analyze",
    params={
        "blob_count": "10",
        "max_blob_size": "1mb",
        "timeout": "120s"
    },
)
print(resp)
response = client.snapshot.repository_analyze(
  repository: 'my_repository',
  blob_count: 10,
  max_blob_size: '1mb',
  timeout: '120s'
)
puts response
const response = await client.transport.request({
  method: "POST",
  path: "/_snapshot/my_repository/_analyze",
  querystring: {
    blob_count: "10",
    max_blob_size: "1mb",
    timeout: "120s",
  },
});
console.log(response);
POST /_snapshot/my_repository/_analyze?blob_count=10&max_blob_size=1mb&timeout=120s

请求

编辑

POST /_snapshot/<repository>/_analyze

先决条件

编辑
  • 如果启用了 Elasticsearch 安全功能,您必须拥有 manage 集群权限才能使用此 API。有关详细信息,请参阅 安全权限

描述

编辑

有大量第三方存储系统可用,但并非所有系统都适合用作 Elasticsearch 的快照仓库。某些存储系统的行为不正确,或者性能不佳,尤其是在 Elasticsearch 集群的多个节点同时访问时。

仓库分析 API 对您的仓库执行一系列读取和写入操作,这些操作旨在检测不正确的行为并测量您的存储系统的性能特征。

此 API 参数的默认值故意设置较低,以减少意外运行分析的影响,并为您的调查提供合理的起点。使用默认参数值运行您的第一次分析,以检查简单的问题。如果成功,请运行一系列越来越大的分析,直到您遇到失败或达到至少 2000blob_count、至少 2gbmax_blob_size、至少 1tbmax_total_data_size 和至少 100register_operation_count。始终指定充裕的超时时间,可能为 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。

可线性化寄存器是特殊的 blob,Elasticsearch 使用原子比较和交换操作来操作它们。即使多个节点同时访问 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
(字符串)在写入此 blob 时,等待 max_snapshot_bytes_per_sec(或者如果设置了托管服务的恢复设置,则为 indices.recovery.max_bytes_per_sec)限制所花费的时间长度。
write_throttled_nanos
(长整型)在写入此 blob 时,等待 max_snapshot_bytes_per_sec(或者如果设置了托管服务的恢复设置,则为 indices.recovery.max_bytes_per_sec)限制所花费的时间长度(以纳秒为单位)。
reads

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

reads 中各项的属性
node

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

node 的属性
id
(字符串)读取节点的 ID。
name
(字符串)读取节点的名称
before_write_complete
(布尔值)表示读取操作是否可能在写入操作完成之前开始。如果为 false,则省略。
找到
(布尔值)表示此读取操作是否找到了该 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 所花费的时间,以纳秒为单位。