跨集群搜索 (Search across clusters)

跨集群搜索 允许你针对一个或多个 远程集群 运行单个搜索请求。 例如,你可以使用跨集群搜索来过滤和分析存储在不同数据中心的集群上的日志数据。

跨集群搜索需要 远程集群

支持的 API

下面的几个 API 支持跨集群搜索:

跨集群搜索的示例

远程集群设置

要执行跨集群搜索,必须至少配置一个远程集群。

下面这个 集群更新设置(cluster update settings) API 请求添加了三个远程集群:cluster_onecluster_twocluster_three

PUT _cluster/settings
{
  "persistent": {
    "cluster": {
      "remote": {
        "cluster_one": {
          "seeds": [
            "127.0.0.1:9300"
          ]
        },
        "cluster_two": {
          "seeds": [
            "127.0.0.1:9301"
          ]
        },
        "cluster_three": {
          "seeds": [
            "127.0.0.1:9302"
          ]
        }
      }
    }
  }
}

搜索单个远程集群

下面这个 search API 请求在远程集群 cluster_one上搜索索引 twitter

GET /cluster_one:twitter/_search
{
  "query": {
    "match": {
      "user": "kimchy"
    }
  }
}

API 返回以下响应:

{
  "took": 150,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0,
    "skipped": 0
  },
  "_clusters": {
    "total": 1,
    "successful": 1,
    "skipped": 0
  },
  "hits": {
    "total" : {
        "value": 1,
        "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "cluster_one:twitter", 
        "_type": "_doc",
        "_id": "0",
        "_score": 1,
        "_source": {
          "user": "kimchy",
          "date": "2009-11-15T14:12:12",
          "message": "trying out Elasticsearch",
          "likes": 0
        }
      }
    ]
  }
}

搜索响应正文的 _index 参数中包含远程集群的名称。

搜索多个远程集群

下面这个 search API 请求在三个集群上搜索索引 twitter

  • 两个远程集群: cluster_onecluster_two
  • 本地集群
GET /twitter,cluster_one:twitter,cluster_two:twitter/_search
{
  "query": {
    "match": {
      "user": "kimchy"
    }
  }
}

API 返回以下响应:

{
  "took": 150,
  "timed_out": false,
  "num_reduce_phases": 4,
  "_shards": {
    "total": 3,
    "successful": 3,
    "failed": 0,
    "skipped": 0
  },
  "_clusters": {
    "total": 3,
    "successful": 3,
    "skipped": 0
  },
  "hits": {
    "total" : {
        "value": 3,
        "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "twitter", 
        "_type": "_doc",
        "_id": "0",
        "_score": 2,
        "_source": {
          "user": "kimchy",
          "date": "2009-11-15T14:12:12",
          "message": "trying out Elasticsearch",
          "likes": 0
        }
      },
      {
        "_index": "cluster_one:twitter", 
        "_type": "_doc",
        "_id": "0",
        "_score": 1,
        "_source": {
          "user": "kimchy",
          "date": "2009-11-15T14:12:12",
          "message": "trying out Elasticsearch",
          "likes": 0
        }
      },
      {
        "_index": "cluster_two:twitter", 
        "_type": "_doc",
        "_id": "0",
        "_score": 1,
        "_source": {
          "user": "kimchy",
          "date": "2009-11-15T14:12:12",
          "message": "trying out Elasticsearch",
          "likes": 0
        }
      }
    ]
  }
}

这个文档的 _index 参数不包含集群名称,表示它来自本地集群。

这个文档来自 cluster_one

这个文档来自 cluster_two

跳过不可用集群

默认情况下,如果请求中的任何集群不可用,跨集群搜索将返回错误。

要在跨集群搜索期间跳过不可用的集群,请将集群设置 skip_unavailable 设置为 true

下面这个 cluster update settings API 请求将 cluster_twoskip_unavailable 设置更改为 true

PUT _cluster/settings
{
  "persistent": {
    "cluster.remote.cluster_two.skip_unavailable": true
  }
}

果在跨集群搜索期间 cluster_two 断开连接或不可用,Elasticsearch 将不会在最终结果中包含该集群匹配的文档。

在嗅探模式(sniff mode)下选择网关和种子节点

对于使用 嗅探连接(sniff connection) 模式的远程集群,需要通过你的网络从本地集群访问网关和种子节点。

默认情况下,任何不符合主节点条件的节点都可以充当网关节点。 如果需要,可以通过将 cluster.remote.node.attr.gateway 设置为 true

对于跨集群搜索,我们建议你使用能够充当搜索请求 协调节点 的网关节点。 如果需要,集群的种子节点可以是这些网关节点的子集。

代理模式(proxy mode)下的跨集群搜索

代理模式(Proxy mode) 远程集群连接支持跨集群搜索。 所有远程连接都连接到配置的 proxy_address。 任何期望的到网关或协调节点的连接路由必须由中间代理在这个配置的地址上实现。

跨集群搜索如何处理网络延迟

因为跨集群搜索涉及到向远程集群发送请求,所以任何网络延迟都会影响搜索速度。 为了避免缓慢的搜索,跨集群搜索提供了两种处理网络延迟的选项:

最小化网络往返 (minimize network roundtrips)

默认情况下,Elasticsearch 减少了远程集群之间的网络往返次数。 这降低了网络延迟对搜索速度的影响。 然而,Elasticsearch 无法减少大型搜索请求的网络往返次数,例如那些包含 滚动(scroll)内部命中(inner hits) 的请求。

请参阅 最小化网络往返 以了解该选项的工作原理。

不要最小化网络往返 (don’t minimize network roundtrips)

对于包含 滚动(scroll) 或 内部命中(inner hits) 的搜索请求,Elasticsearch 向每个远程集群发送多个传出和传入请求。 你也可以通过将 ccs_minimize_roundtrips 参数设置为 false来选择此选项。 虽然这种方法通常较慢,但对于低延迟的网络来说可能效果很好。

请参阅 不要最小化网络往返 以了解该选项的工作原理。

最小化网络往返 (minimize network roundtrips)

以下是当最大限度地减少网络往返时跨集群搜索的工作方式。

  1. 向本地集群发送跨集群搜索请求。 该集群中的协调节点接收并解析该请求。

    ccs min roundtrip client request

  2. 协调节点向包括本地集群在内的每个集群发送单个搜索请求。 每个集群独立执行搜索请求,对请求使用自己的集群级设置。

    ccs min roundtrip cluster search

  3. 每个远程集群将其搜索结果发送回协调节点。

    ccs min roundtrip cluster results

  4. 从每个集群收集结果后,协调节点在跨集群搜索响应中返回最终结果。

    ccs min roundtrip client response

不要最小化网络往返 (don’t minimize network roundtrips)

以下是没有最小化网络往返时,跨集群搜索是如何工作的。

  1. 向本地集群发送跨集群搜索请求。 该集群中的协调节点接收并解析该请求。

    ccs min roundtrip client request

  2. 协调节点向每个远程集群发送一个 搜索分片(search shards) API 请求。

    ccs min roundtrip cluster search

  3. 每个远程集群将其响应发送回协调节点。 该响应包含关于跨集群搜索请求将在其上执行的索引和分片的信息。

    ccs min roundtrip cluster results

  4. 协调节点向每个分片发送搜索请求,包括它自己集群中的分片。 每个分片独立地执行搜索请求。

    当网络往返没有最小化时去执行搜索,就好像所有数据都在协调节点所在的群集中。 建议更新限制搜索的集群级设置,如 action.search.shard_count.limit, pre_filter_shard_sizemax_concurrent_shard_requests 以解决这一问题。 如果这些限制太低,搜索可能会被拒绝。

    ccs dont min roundtrip shard search

  5. 每个分片将其搜索结果发送回协调节点。

    ccs dont min roundtrip shard results

  6. 从每个集群收集结果后,协调节点在跨集群搜索响应中返回最终结果。

    ccs min roundtrip client response