一、跨集群搜索概述

什么是跨集群搜索

跨集群搜索(Cross-Cluster Search,简称 CCS),说白了就是让你能用一台 Kibana 或一个客户端,同时查询多个 Elasticsearch 集群里的数据。

我打个比方你就明白了。假设你有三个集群:一个在北京,一个在上海,一个在深圳。以前你要查数据,得分别连三个集群,查三次,再自己拼结果。有了 CCS,你只需要连其中一个集群,它自动帮你把查询请求分发到另外两个集群,最后汇总返回给你。

嗯,这里要注意:CCS 不是数据复制,也不是数据迁移。它只是查询层面的联邦能力。数据还是存在各自的集群里,只是查询的时候能“穿透”过去。

核心要点:跨集群搜索 = 一个查询入口 + 多个数据源 + 结果聚合。

为什么需要跨集群搜索

我在实际项目中遇到过不少场景,非用 CCS 不可。我给你列几个最典型的:

  • 多机房部署:公司业务遍布全球,每个区域一个集群。总部的分析师想一眼看到全球数据,总不能让他挨个连集群吧?
  • 环境隔离:有些公司把日志集群和业务集群分开。日志集群存 Nginx 日志,业务集群存订单数据。但做故障排查时,需要同时查两边数据。CCS 就派上用场了。
  • 部门数据隔离:每个部门有自己的集群,但高层需要跨部门看报表。你想想看,如果每个部门都开放直连权限,安全风险多大?CCS 可以做到“查询可见,数据不动”。
  • 冷热数据分离:热数据在 SSD 集群,冷数据在 HDD 集群。查询时自动跨集群搜索,用户无感知。

我记得有一次,客户的生产环境出了故障,需要同时查应用日志、数据库慢查询、网络流量三个集群的数据。如果没有 CCS,我得开三个 Kibana 页面来回切换,那画面太美我不敢看。

我的建议:如果你的公司有超过 2 个 ES 集群,并且存在跨集群查询的需求,尽早引入 CCS。别等到业务方天天催你“能不能一个页面查完所有数据”的时候再搞。

适用场景

不是所有场景都适合 CCS。我总结了几类“天生匹配”的场景:

场景 说明 我见过的坑
跨地域查询 多个数据中心,数据不迁移,但需要统一查询 网络延迟大,查询超时。建议加超时配置
多租户隔离 每个租户一个集群,但运营需要全局视图 权限控制要小心,别让租户A查到租户B的数据
数据归档 旧数据移到冷集群,但偶尔需要回溯查询 冷集群性能差,查询要加限流
测试与生产隔离 测试集群和生产集群分开,但对比数据时要用 千万别在生产环境误配测试集群的地址

反过来,有些场景就不太适合 CCS。比如:

  • 高频实时写入+查询:CCS 有网络开销,不适合毫秒级响应的场景。
  • 数据需要强一致性:CCS 是最终一致性,跨集群查询可能拿到不同时间点的数据。
  • 超大结果集:比如一次查几百万条,CCS 的聚合开销会让你怀疑人生。

架构概览

CCS 的架构其实不复杂。我画个文字版的给你看:

+-------------------+       +-------------------+
|    Kibana / 客户端  |       |    Kibana / 客户端  |
+--------+----------+       +--------+----------+
         |                            |
         v                            v
+-------------------+       +-------------------+
|  集群A(协调节点)  |       |  集群B(协调节点)  |
|  192.168.1.10     |       |  192.168.2.20     |
+--------+----------+       +--------+----------+
         |                            |
         |  跨集群查询                  |  跨集群查询
         v                            v
+-------------------+       +-------------------+
|  集群C(数据节点)  |       |  集群D(数据节点)  |
|  192.168.3.30     |       |  192.168.4.40     |
+-------------------+       +-------------------+

工作原理是这样的:

  1. 客户端连上集群A(我们叫它“查询集群”)。
  2. 集群A 收到查询请求后,发现索引名带有集群前缀(比如 cluster_c:logs)。
  3. 集群A 把查询请求转发给集群C 和集群D。
  4. 集群C 和集群D 各自执行查询,返回结果给集群A。
  5. 集群A 汇总结果,返回给客户端。

这里有个关键点:集群A 必须能通过网络访问到集群C 和集群D。说白了,网络连通性是 CCS 的生命线。

我曾经踩过的坑:有一次配置 CCS,集群A 和集群C 之间网络是通的,但集群A 的防火墙只开放了 9200 端口,没开放 9300 端口。结果 CCS 一直连不上,查了半天才发现是端口问题。记住,CCS 用的是 transport 协议(9300 端口),不是 HTTP 协议(9200 端口)。

配置方式也很简单。在集群A 上执行一条命令就行:

PUT _cluster/settings
{
  "persistent": {
    "cluster.remote": {
      "cluster_c": {
        "seeds": ["192.168.3.30:9300", "192.168.3.31:9300"]
      },
      "cluster_d": {
        "seeds": ["192.168.4.40:9300", "192.168.4.41:9300"]
      }
    }
  }
}

配置好之后,查询的时候这样写:

GET cluster_c:logs/_search
{
  "query": {
    "match": {
      "message": "error"
    }
  }
}

看到没?索引名前加了个 cluster_c: 前缀,ES 就知道要去远程集群查了。

一个小技巧:如果你不想每次查询都写集群前缀,可以在 Kibana 里配置索引模式时,把远程集群的索引也加进来。这样用户完全感知不到数据来自不同集群。

好了,这一章就讲到这里。下一章我会带你手把手配置跨集群搜索,包括网络配置、安全认证、性能调优这些实战内容。到时候我会分享一些我踩过的坑,保证让你少走弯路。