跨集群操作—Elastic Stack 实战手册-阿里云开发者社区

开发者社区> Elasticsearch 技术团队> 正文
登录阅读全文

跨集群操作—Elastic Stack 实战手册

简介: Elasticsearch 集群天然支持横向水平扩展,因此当业务规模扩大、对集群产生读写压力时,增加节点总是运维人员的“懒人选择”。但随着节点数增多,集群主节点要维护的 meta 信息也随之增多,这会导致集群更新压力增大,甚至无法提供正常服务。 另外每个企业的数据中心都需要有灾备方案,在集群间同步数据,因为单点集群会存在隐患。

970X90.png

· 更多精彩内容,请下载阅读全本《Elastic Stack实战手册》

· 加入创作人行列,一起交流碰撞,参与技术圈年度盛事吧

创作人:张刘毅
审稿人:吴斌

Elasticsearch 集群天然支持横向水平扩展,因此当业务规模扩大、对集群产生读写压力时,增加节点总是运维人员的“懒人选择”。但随着节点数增多,集群主节点要维护的 meta 信息也随之增多,这会导致集群更新压力增大,甚至无法提供正常服务。 另外每个企业的数据中心都需要有灾备方案,在集群间同步数据,因为单点集群会存在隐患。

鉴于此,Elastic官方提供了跨集群操作。主要包括:

(1)跨集群搜索(CCS):允许配置多个远程集群并且在所有已配置的集群中实现联合搜索。

(2)跨集群复制(CCR):允许跨多个集群复制索引,适合于做灾备方案和数据本地化场景。

跨集群配置

跨集群操作有两种配置模式连接远程的集群:嗅探模式(Sniff mode)或者代理模式(Proxy mode)。

  • 在嗅探模式下,我们使用集群名称和种子节点列表注册远程集群。注册后,集群状态将被种子节点获取,该模式要求本地群集可以访问网关节点的发布地址。
  • 在代理模式下,使用集群名称和单个代理地址注册远程集群。代理模式不需要远程集群节点具有可访问的发布地址。

我们可以在 Kibana 上动态配置远程集群,也可以在各个节点的 elasticsearch.yml 文件的上配置。

动态配置远程集群

我们在 Kibana 上使用 cluster update settings API 为每个节点动态配置远程集群。

例如:

PUT _cluster/settings
{
  "persistent": {
    "cluster": {
      "remote": {
        "cluster_one": {
          "seeds": [
            "127.0.0.1:9300"
          ],
          "transport.ping_schedule": "30s"
        },
        "cluster_two": {
          "mode": "sniff",
          "seeds": [
            "127.0.0.1:9301"
          ],
          "transport.compress": true,
          "skip_unavailable": true
        },
        "cluster_three": {
          "mode": "proxy",
          "proxy_address": "127.0.0.1:9302"
        }
      }
    }
  }
}

上面的配置中,当前集群是 cluster_one,一起联合远程访问的集群 cluster_two、cluster_three。其中 cluster_two 的连接方式是嗅探模式,cluster_three 的连接方式是代理模式,代理地址是 "127.0.0.1:9302"。

其中:

  • transport.compress:网络传输的压缩参数
  • transport.ping_schedule :集群内部通信(tcp)的访问频率
  • skip_unavailable:默认情况下如果请求中的任何集群都不可用则会返回错误。如果跳过不可用的集群,可以将 skip_unavailable 设置为 true。

以上这些参数是可以动态调整的,但必须要包括 seed 列表或者代理地址。

我们如果想关闭压缩、将 ping_schedule 由 30s 改成 60s可以通过如下示例方式

PUT _cluster/settings
{
  "persistent": {
    "cluster": {
      "remote": {
        "cluster_one": {
          "seeds": [
            "127.0.0.1:9300"
          ],
          "transport.ping_schedule": "60s"
        },
        "cluster_two": {
          "mode": "sniff",
          "seeds": [
            "127.0.0.1:9301"
          ],
          "transport.compress": false
        },
        "cluster_three": {
          "mode": "proxy",
          "proxy_address": "127.0.0.1:9302",
          "transport.compress": true
        }
      }
    }
  }
}

静态配置远程集群

在节点的 elasticsearch.yml 中配置远程连接,只有在 YAML 文件中设置的节点,才能连接到远程集群,并处理远程集群请求。

举例

cluster:
    remote:
        cluster_one: 
            seeds: 127.0.0.1:9300 
            transport.ping_schedule: 30s 
        cluster_two: 
            mode: sniff 
            seeds: 127.0.0.1:9301 
            transport.compress: true 
            skip_unavailable: true 
        cluster_three: 
            mode: proxy 
            proxy_address: 127.0.0.1:9302 

其中,cluster_one,cluster_two 和 cluster_three 是表示与每个集群的连接的集群名称,用于区分本地索引和远程索引。

跨集群搜索

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

在5.3.0之前的版本,Elastic 官方提供了 Tribe Node 实现多集群访问的解决方案。

Tribe Node 是以 Client Node 的角色添加到集群中。但是由于不保留集群的 meta 信息,每次重启需要重新加载初始化。因此,在5.3版本中 Elastic 官方提供了 CCS 的功能,允许集群中的任何节点可以联合查询。

快速入门

下面以两个集群的跨集群搜索为例。我们预先启动了两个集群:cluster1、cluster2,当前集群是 cluster1。现在的任务是联合远程访问的集群 cluter2 进行跨集群搜索。

我们分别在两个集群上动态配置 remote cluster。

注意:在 seeds 列表中填写的是集群节点间通信的 TCP 端口而不是 HTTP 端口。

PUT _cluster/settings
{
  "persistent": {
    "cluster": {
      "remote": {
        "cluster_one": {
          "seeds": [
            "192.168.2.2:9300"
          ]
        },
        "cluster_two": {
          "seeds": [
            "192.168.2.2:9500"
          ]
        }
      }
    }
  }
}

1.png

在 cluster1 中插入数据

PUT esfighttogether/_doc/1
{
  "teamname":"team 10"
}

在 cluster2 中插入数据

 PUT esfighttogether/_doc/1
{
  "teamname":"team 1"
}

PUT esfighttogether/_doc/2
{
  "teamname":"team 7"
}

在两个集群上分别验证数据。因为写入时 Elasticsearch 自带的默认分词器会对数据进行分词,我们通过 team 就可以查询到所有数据。

查询语句如下:

GET esfighttogether/_search
{
  "query": {
    "match": {
      "teamname": "team"
    }
  }
}

执行跨集群搜索

GET cluster_one:esfighttogether,cluster_two:esfighttogether/_search?timeout=5m
{
  "query": {
    "match": {
      "teamname": "team"
    }
  }
}

2.png

如上图所示,通过 CCS 查询到 3 条数据:cluster_one 的一条数据 team 10 以及 cluster_two 的两条数据 team 1 和 team 7,和之前写入的数据一致。

跨集群复制

跨集群复制是将特定索引,从一个 Elasticsearch 集群复制到另外的集群。

一般用于以下场景:

  • 灾备:数据中心服务中断时,可以继续响应用户的搜索请求,防止用户大的查询影响到写入吞吐
  • 数据本地化:将数据复制到更靠近用户的位置以降低搜索延迟

跨集群复制使用主动-被动模型,我们将索引写入领导者索引,数据会被复制到一个或多个只读跟随者索引。在将跟随者索引添加到集群之前,我们需要配置包含领导者索引的远程集群。

当领导者索引有写入请求时,跟随者索引从远程集群上的领导者索引中拉取增量数据。我们可以手动创建跟随者索引,或配置自动跟随模式(auto-follow patterns),创建跟随者索引。

我们可以单向或双向配置 CCR:

  • 在单向配置中,一个集群仅包含领导者索引,而另一个集群仅包含跟随者索引。

3.png

  • 在双向配置中,每个集群都包含领导者索引和跟随者索引

4.png

快速入门

我们在服务器上启动两个集群来模拟不同地区数据中心的集群:

  • “cluster1”:在端口 9200 上运行。我们会将文档从 cluster1 复制到 cluster2。
  • “cluster2”:在端口 9400 上运行。cluster2 将维护一个来自 cluster1 的复制索引。

5.png

配置远程集群

我们选择 CCR 的单向配置,因此 CCR 是基于拉取模式,所以我们只需要确保 cluster2 连接到cluster1 ,而不需要指定从 cluster2 到 cluster1 的连接。

下面让我们通过 cluster2 上的 API 调用来定义 cluster1:

PUT /_cluster/settings
{
  "persistent": {
    "cluster": {
      "remote":{
        "cluster1":{
          "seeds":["192.168.2.2:9300"]
        }
      }
    }
  }
}

6.png

Kibana 中远程集群管理的 UI,单击左侧导航面板中的 “Management”(齿轮图标),然后点击 “Stack Management” ,导航到 Elasticsearch 部分中的 “Remote Clusters”(远程集群)。

7.png

创建要复制的索引

PUT esfightalone
{
  "settings": {
    "index": {
      "number_of_shards": 1,
      "number_of_replicas": 0,
      "soft_deletes": {
        "enabled": true
      }
    }
  },
  "mappings": {
    "properties": {
      "name": {
        "type": "keyword"
      }
    }
  }
}

CCR 的 Leader 索引需要使用软删除(soft_deletes),无论何时删除或更新现有文档,都可以将操作历史记录保留在领导者分片上,等重新操作历史记录时,供追随者分片任务使用。

当追随者分片从领导者复制数据时,会在领导者分片上留下标记,这样领导者就知道追随者在历史记录中的所在位置。基于这些标记,领导者分片将会保留这些操作,直到分片历史记录保留到设定时间结束(默认为 12 个小时)。

我们已经为远程集群创建了一个别名,并创建了一个我们要复制的索引,接下来我们启动复制。在 cluster2 上,执行:

 PUT /esfightalone-copy/_ccr/follow
{
  "remote_cluster" : "cluster1",
  "leader_index" : "esfightalone"
}

注意,复制索引是只读的,不能接受写操作。至此,我们已配置了要从一个 Elasticsearch 集群复制到另一个集群的索引。

8.png

测试 CCR 复制

我们在 cluster1 上写入数据:

 POST /esfightalone/_doc
  {
    "name" :"team 1"
  }

然后在 cluster2 上查询,验证索引数据是否同步,发现此时数据已实时同步到 cluster2 中了:

   GET /esfightalone-copy/_search

9.png

CCR 属于 Elastic 官方的白金付费(Platinum License)的功能。一般企业还是会选择自研数据同步工具,来同步集群间的数据。

不过,需要体验的小伙伴可以在 Elastic 官网或阿里云 Elasticsearch 申请 30 天免费使用或者在自己的本地安装中启用试用功能。

创作人简介:
张刘毅,存储研发工程师,曾经做过 AI 大数据平台研发,负责过 80+ES 集群。目前专
注于生物医药和大数据。
博客:https://blog.csdn.net/dtzly

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享: