正在加载

跨集群使用 ES|QL

Elastic Stack Serverless 不可用

警告

ES|QL 的跨集群搜索处于技术预览阶段,可能会在未来的版本中更改或删除。 Elastic 将努力修复任何问题,但技术预览版的功能不受官方 GA 功能的支持 SLA 约束。

使用 ES|QL,您可以在多个集群上执行单个查询。

  • 跨集群搜索需要远程集群。 要设置远程集群,请参阅 远程集群

    为确保您的远程集群配置支持跨集群搜索,请参阅支持的跨集群搜索配置

  • 为了获得完整的跨集群搜索功能,本地集群和远程集群必须处于相同的 订阅级别

  • 本地协调节点必须具有 remote_cluster_client 节点角色。

  • 如果您使用 嗅探模式,则本地协调节点必须能够连接到远程集群上的种子节点和网关节点。

    我们建议使用能够充当协调节点的网关节点。 种子节点可以是这些网关节点的子集。

  • 如果您使用 代理模式,则本地协调节点必须能够连接到配置的 proxy_address。 该地址上的代理必须能够将连接路由到远程集群上的网关和协调节点。

  • 跨集群搜索需要在本地集群和远程集群上具有不同的安全权限。 请参阅 配置跨集群搜索的权限远程集群

Elasticsearch 支持两种用于跨集群搜索 (CCS) 的安全模型

提示

要检查正在使用哪种安全模型来连接您的集群,请运行 GET _remote/info。 如果您使用的是 API 密钥身份验证方法,您将在响应中看到 "cluster_credentials" 键。

在 9.0.0 中已弃用。

请改用 API 密钥身份验证

TLS 证书身份验证使用相互 TLS 保护远程集群。 当单个管理员完全控制两个集群时,这可能是首选模型。 我们通常建议角色及其权限在两个集群中都是相同的。

有关先决条件和详细的设置说明,请参阅 TLS 证书身份验证

以下信息与在使用 基于 API 密钥的安全模型 的集群中使用 ES|QL 有关。 您需要按照该页面上的步骤进行完整设置说明。 此页面仅包含特定于 ES|QL 的其他信息。

基于 API 密钥的跨集群搜索 (CCS) 可以更精细地控制集群之间允许的操作。 当您对不同的集群有不同的管理员,并且想要更好地控制谁可以访问哪些数据时,这可能是首选模型。 在此模型中,集群管理员必须明确定义授予集群和用户的访问权限。

您将需要

在使用基于 API 密钥的安全模型时,将 ES|QL 与 API 密钥安全模型一起使用需要一些额外的权限,而在使用基于传统查询 DSL 的搜索时可能不需要这些权限。 以下 API 调用示例创建一个角色,该角色在使用基于 API 密钥的安全模型时可以使用 ES|QL 查询远程索引。 最终权限 remote_cluster 是允许远程丰富操作所必需的。

 POST /_security/role/remote1 {
  "cluster": ["cross_cluster_search"],
  "indices": [
    {
      "names" : [""],
      "privileges": ["read"]
    }
  ],
  "remote_indices": [
    {
      "names": [ "logs-*" ],
      "privileges": [ "read","read_cross_cluster" ],
      "clusters" : ["my_remote_cluster"]
    }
  ],
   "remote_cluster": [
        {
            "privileges": [
                "monitor_enrich"
            ],
            "clusters": [
                "my_remote_cluster"
            ]
        }
    ]
}
  1. 本地集群需要 cross_cluster_search 集群权限。
  2. 通常,用户将具有读取本地索引和远程索引的权限。 但是,对于角色仅用于搜索远程集群的情况,仍然需要对本地集群具有 read 权限。 为了提供对本地集群的读取访问权限,但不允许读取本地集群中的任何索引,names 字段可以是一个空字符串。
  3. 允许读取访问远程集群的索引。 配置的 跨集群 API 密钥 还必须允许读取此索引。
  4. 在使用基于 API 密钥的安全模型通过 ES|QL 跨集群时,始终需要 read_cross_cluster 权限。
  5. 这些权限适用的远程集群。 必须使用 跨集群 API 密钥配置此远程集群,并且必须先连接到远程集群,然后才能查询远程索引。 使用 远程集群信息 API 验证连接。
  6. 允许远程丰富是必需的。 没有它,用户将无法从远程集群上的 .enrich 索引中读取。 remote_cluster 安全权限是在 8.15.0 版本中引入的。

然后,您需要一个具有上述权限的用户或 API 密钥。 以下 API 调用示例创建一个具有 remote1 角色的用户。

 POST /_security/user/remote_user {
  "password" : "<PASSWORD>",
  "roles" : [ "remote1" ]
}

请记住,来自本地集群的所有跨集群请求都受跨集群 API 密钥的权限的约束,这些权限由远程集群的管理员控制。

提示

需要在 8.15.0 之前的版本中创建的跨集群 API 密钥需要更换或更新,以添加 ES|QL 与 ENRICH 所需的新权限。

配置安全模型后,您可以添加远程集群。

以下 集群更新设置 API 请求添加了三个远程集群:cluster_onecluster_twocluster_three

 PUT _cluster/settings {
  "persistent": {
    "cluster": {
      "remote": {
        "cluster_one": {
          "seeds": [
            "35.238.149.1:9300"
          ],
          "skip_unavailable": true
        },
        "cluster_two": {
          "seeds": [
            "35.238.149.2:9300"
          ],
          "skip_unavailable": false
        },
        "cluster_three": {
          "seeds": [
            "35.238.149.3:9300"
          ]
        }
      }
    }
  }
}
  1. 由于未在 cluster_three 上设置 skip_unavailable,因此它使用默认值 true。 有关详细信息,请参阅 可选远程集群 部分。

FROM 命令中,使用格式 <remote_cluster_name>:<target> 指定远程集群上的数据流和索引。 例如,以下 ES|QL 请求查询名为 cluster_one 的单个远程集群上的 my-index-000001 索引

FROM cluster_one:my-index-000001
| LIMIT 10

类似地,这个 ES|QL 请求查询来自三个集群的 my-index-000001 索引

  • 本地(“查询”)集群
  • 两个远程集群,cluster_onecluster_two
FROM my-index-000001,cluster_one:my-index-000001,cluster_two:my-index-000001
| LIMIT 10

同样,这个 ES|QL 请求查询来自所有远程集群(cluster_onecluster_twocluster_three)的 my-index-000001 索引

FROM *:my-index-000001
| LIMIT 10

使用 "include_ccs_metadata": true 选项,用户可以请求 ES|QL 跨集群搜索响应包含每个集群上搜索的元数据(当响应格式为 JSON 时)。这里我们展示一个使用异步搜索端点的例子。 跨集群搜索元数据也存在于同步搜索端点响应中(如果被请求)。 如果搜索返回部分结果并且存在部分分片或远程集群故障,则无论 include_ccs_metadata 参数如何,包含故障的 _clusters 元数据都将包含在响应中。

 POST /_query/async?format=json {
  "query": """
    FROM my-index-000001,cluster_one:my-index-000001,cluster_two:my-index*
    | STATS COUNT(http.response.status_code) BY user.id
    | LIMIT 2
  """,
  "include_ccs_metadata": true
}

返回

{
  "is_running": false,
  "took": 42,
  "is_partial": false,
  "columns" : [
    {
      "name" : "COUNT(http.response.status_code)",
      "type" : "long"
    },
    {
      "name" : "user.id",
      "type" : "keyword"
    }
  ],
  "values" : [
    [4, "elkbee"],
    [1, "kimchy"]
  ],
  "_clusters": {
    "total": 3,
    "successful": 3,
    "running": 0,
    "skipped": 0,
    "partial": 0,
    "failed": 0,
    "details": {
      "(local)": {
        "status": "successful",
        "indices": "blogs",
        "took": 41,
        "_shards": {
          "total": 13,
          "successful": 13,
          "skipped": 0,
          "failed": 0
        }
      },
      "cluster_one": {
        "status": "successful",
        "indices": "cluster_one:my-index-000001",
        "took": 38,
        "_shards": {
          "total": 4,
          "successful": 4,
          "skipped": 0,
          "failed": 0
        }
      },
      "cluster_two": {
        "status": "successful",
        "indices": "cluster_two:my-index*",
        "took": 40,
        "_shards": {
          "total": 18,
          "successful": 18,
          "skipped": 1,
          "failed": 0
        }
      }
    }
  }
}
  1. 整个搜索(跨所有集群)花费的时间,以毫秒为单位。
  2. 这部分计数器显示了所有可能的集群搜索状态以及当前处于该状态的集群搜索的数量。 集群可以具有以下状态之一: running (正在运行),successful (所有分片上的搜索都成功),skipped (在标记为 skip_unavailable=true 的集群上搜索失败),failed (在标记为 skip_unavailable=false 的集群上搜索失败) 或 partial (搜索在完成之前 被中断 或者部分失败)。
  3. _clusters/details 部分显示了关于每个集群上搜索的元数据。
  4. 如果您在跨集群搜索中包含了发送请求的本地集群的索引,它将被标识为“(local)”。
  5. 搜索在每个集群上花费的时间(以毫秒为单位)。 这对于确定哪些集群的响应时间比其他集群慢很有用。
  6. 该集群上搜索的分片详细信息,包括由于 can-match 阶段结果而跳过的分片计数。 当分片没有任何匹配数据时,它们会被跳过,因此不包含在完整的 ES|QL 查询中。
  7. 如果由于任何原因搜索具有部分结果,例如由于部分分片故障、远程集群故障,或者如果异步查询被调用了 异步查询停止 API 停止,则 is_partial 字段设置为 true

跨集群元数据可用于确定是否有任何数据从集群返回。 例如,在下面的查询中,cluster-two 的通配符表达式没有解析为具体的索引(或索引)。 因此,该集群被标记为skipped,并且搜索的分片总数设置为零。

 POST /_query/async?format=json {
  "query": """
    FROM cluster_one:my-index*,cluster_two:logs*
    | STATS COUNT(http.response.status_code) BY user.id
    | LIMIT 2
  """,
  "include_ccs_metadata": true
}

返回

{
  "is_running": false,
  "took": 55,
  "is_partial": true,
  "columns": [
     ...
  ],
  "values": [
     ...
  ],
  "_clusters": {
    "total": 2,
    "successful": 1,
    "running": 0,
    "skipped": 1,
    "partial": 0,
    "failed": 0,
    "details": {
      "cluster_one": {
        "status": "successful",
        "indices": "cluster_one:my-index*",
        "took": 38,
        "_shards": {
          "total": 4,
          "successful": 4,
          "skipped": 0,
          "failed": 0
        }
      },
      "cluster_two": {
        "status": "skipped",
        "indices": "cluster_two:logs*",
        "took": 0,
        "_shards": {
          "total": 0,
          "successful": 0,
          "skipped": 0,
          "failed": 0
        }
      }
    }
  }
}
  1. 由于该集群上没有匹配的索引,因此该集群被标记为skipped
  2. 表明没有搜索任何分片(由于没有匹配的索引)。
  3. 由于其中一个集群被跳过,因此搜索结果被标记为部分结果。

跨集群的 ES|QL 中的 Enrich 操作类似于 本地 Enrich。 如果 enrich 策略及其 enrich 索引在所有集群中都一致,只需编写 enrich 命令,就像没有远程集群一样。 在此默认模式下,ES|QL 可以在本地集群或远程集群上执行 enrich 命令,旨在最大限度地减少计算或集群间数据传输。 确保策略存在于本地集群和远程集群上且数据一致,对于 ES|QL 产生一致的查询结果至关重要。

提示

8.15.0 版本中引入了使用基于 API 密钥的安全模型的跨集群 ES|QL Enrich。 在 8.15.0 之前的版本中创建的跨集群 API 密钥需要替换或更新才能使用新的必需权限。 请参阅 API 密钥身份验证 部分中的示例。

在以下示例中,可以在本地集群或远程集群 cluster_one 上执行使用 hosts 策略的 Enrich。

FROM my-index-000001,cluster_one:my-index-000001
| ENRICH hosts ON ip
| LIMIT 10

仅针对远程集群的 ES|QL 查询进行 Enrich 也可以在本地集群上进行。 这意味着以下查询要求 hosts enrich 策略也存在于本地集群上。

FROM cluster_one:my-index-000001,cluster_two:my-index-000001
| LIMIT 10
| ENRICH hosts ON ip

ES|QL 提供了 enrich _coordinator 模式,以强制 ES|QL 在本地集群上执行 enrich 命令。 当远程集群上没有 enrich 策略或者维护跨集群 enrich 索引的一致性具有挑战性时,应使用此模式。

FROM my-index-000001,cluster_one:my-index-000001
| ENRICH _coordinator:hosts ON ip
| SORT host_name
| LIMIT 10
重要提示

使用 _coordinator 模式的 Enrich 通常会增加集群间数据传输和本地集群上的工作负载。

ES|QL 还提供了 enrich _remote 模式,以强制 ES|QL 在目标索引所在的每个远程集群上独立执行 enrich 命令。 对于在每个集群上管理不同的 enrich 数据非常有用,例如每个区域的 hosts 的详细信息,其中目标(主)索引包含来自这些 hosts 的日志事件。

在以下示例中,需要在所有远程集群上存在 hosts enrich 策略:querying 集群(因为包含本地索引)、远程集群 cluster_onecluster_two

FROM my-index-000001,cluster_one:my-index-000001,cluster_two:my-index-000001
| ENRICH _remote:hosts ON ip
| SORT host_name
| LIMIT 10

stats 命令之后,无法执行 _remote enrich。 以下示例将导致错误

FROM my-index-000001,cluster_one:my-index-000001,cluster_two:my-index-000001
| STATS COUNT(*) BY ip
| ENRICH _remote:hosts ON ip
| SORT host_name
| LIMIT 10

您可以在同一查询中包含具有不同模式的多个 enrich 命令。 ES|QL 将尝试相应地执行它们。 例如,此查询执行两个 enrich,首先在任何集群上使用 hosts 策略,然后在本地集群上使用 vendors 策略。

FROM my-index-000001,cluster_one:my-index-000001,cluster_two:my-index-000001
| ENRICH hosts ON ip
| ENRICH _coordinator:vendors ON os
| LIMIT 10

_coordinator enrich 命令之后,无法执行 _remote enrich 命令。 以下示例将导致错误。

FROM my-index-000001,cluster_one:my-index-000001,cluster_two:my-index-000001
| ENRICH _coordinator:hosts ON ip
| ENRICH _remote:vendors ON os
| LIMIT 10

要排除整个集群,请在 FROM 命令中,在集群别名前面加上减号,例如:-my_cluster:*

FROM my-index-000001,cluster*:my-index-000001,-cluster_three:*
| LIMIT 10

要排除特定的远程索引,请在 FROM 命令中,在索引前面加上减号,例如 my_cluster:-my_index

FROM my-index-000001,cluster*:my-index-*,cluster_three:-my-index-000001
| LIMIT 10

如果远程集群与查询集群断开连接,{ccs-cap} for {esql} 会将其设置为 skipped 并继续使用其他集群的查询,除非远程集群的 skip_unavailable 设置为 false,在这种情况下,查询将失败。

您仍然可以在对本地集群执行滚动升级时搜索远程集群。 但是,本地协调节点的“upgrade from”和“upgrade to”版本必须与远程集群的网关节点兼容。

警告

不支持在同一集群中运行多个版本的 Elasticsearch,超出升级持续时间。

有关升级的更多信息,请参阅 升级 Elasticsearch

© . All rights reserved.