Elasticsearch 高可用集群搭建

阿里云产品限时红包,最高 ¥1888 元,立即领取

以下我们将基于 elasticsearch-6.6.0 版本,在单机上部署 3 个节点组成的集群。3个节点都用作候选主节点,且同时作为数据节点。

集群搭建

  1. 下载 elasticsearch-6.6.0 二进制包,解压,复制 3 份,分别命名为 es1, es2, es3。

  2. 分别修改 config/elasticsearch.yml 的配置,

es1 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 集群名称,相同集群的节点名称一致
cluster.name: my-application
# 节点名称
node.name: es1
# 数据存储路径
path.data: /path/to/es1/data
# 日志存储路径
path.logs: /path/to/es1/logs
# 是否用作候选主节点,默认为 true
node.master: true
# 是否用作数据节点,默认为 true
node.data: true
# HTTP 端口,提供 RESTful 服务交互
http.port: 5201
# TCP 端口,集群节点之间通信
transport.tcp.port: 5301
# 集群中相互通信的节点
discovery.zen.ping.unicast.hosts: ["localhost:5301","locahost:5302","locahost:5303"]
# 集群最小主节点个数
discovery.zen.minimum_master_nodes: 2

es2 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 集群名称,相同集群的节点名称一致
cluster.name: my-application
# 节点名称
node.name: es2
# 数据存储路径
path.data: /path/to/es2/data
# 日志存储路径
path.logs: /path/to/es2/logs
# 是否用作候选主节点,默认为 true
node.master: true
# 是否用作数据节点,默认为 true
node.data: true
# HTTP 端口,提供 RESTful 服务交互
http.port: 5202
# TCP 端口,集群节点之间通信
transport.tcp.port: 5302
# 集群中相互通信的节点
discovery.zen.ping.unicast.hosts: ["localhost:5301","locahost:5302","locahost:5303"]
# 集群最小主节点个数
discovery.zen.minimum_master_nodes: 2

es3 如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 集群名称,相同集群的节点名称一致
cluster.name: my-application
# 节点名称
node.name: es3
# 数据存储路径
path.data: /path/to/es3/data
# 日志存储路径
path.logs: /path/to/es3/logs
# 是否用作候选主节点,默认为 true
node.master: true
# 是否用作数据节点,默认为 true
node.data: true
# HTTP 端口,提供 RESTful 服务交互
http.port: 5203
# TCP 端口,集群节点之间通信
transport.tcp.port: 5303
# 集群中相互通信的节点
discovery.zen.ping.unicast.hosts: ["localhost:5301","locahost:5302","locahost:5303"]
# 集群最小主节点个数,为了防止脑裂,最小主节点个数应该为(候选主节点个数 / 2 + 1)
discovery.zen.minimum_master_nodes: 2
  1. 分别启动 3 个节点
1
2
cd /path/to/es1
bin/elasticsearch -d
  1. 在浏览器中查看集群状态

查看集群状态

可视化管理

通过 elasticsearch-head 可以可视化的管理 es 集群。

elasticsearch-head 项目地址 http://mobz.github.io/elasticsearch-head

如果本地有 nodejs 环境,通过以下步骤安装 elasticsearch-head。

1
2
3
4
git clone git://github.com/mobz/elasticsearch-head.git
cd elasticsearch-head
npm install
npm run start

安装完成,在浏览器中访问 http://localhost:9100/

可视化集群管理

elasticsearch-head 在访问 es 实例 RESTful API 时会存在跨域问题,es 实例启动时,配置文件需要添加一下参数

http.cors.enabled: true
http.cors.allow-origin: "*"

基础操作

创建索引

1
2
3
4
5
6
7
8
PUT /my_index

{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 0
}
}

number_of_shards: 主分片数量,默认为 5
number_of_replicas: 分片副本数量,默认为 1

动态更新副本数量

1
2
3
4
5
PUT /my_index/settings

{
"number_of_replicas": 1
}

高可用性验证

这里以另外一个真实在用的集群来演示集群的高可用性。

步骤一

  • 索引 app_jgus_ynapp_jgus 都是在单节点集群情况下创建的,默认主分片数量为 5,副本数量为 0。
  • 后来,集群扩展到 3 个节点,我为 app_jgus 动态更新了副本数量为 1。
  • 该集群处于 green 状态:

集群正常

步骤二

  • 集群中 es3 节点失败了,集群处于 red 状态,有主分片缺失,此时集群不可用。
  • app_jgus 索引的查询依然可以正常进行,因为 app_jgus 的每个主分片都有 1 个副本,剩余 2 个节点中保存有所有的索引数据。
  • 索引 app_jgus_yn 由于没有为主分片生成副本,随 es3 节点失败,缺少了 2 个主分片,缺失的分片数据将无法被操作。

集群中节点挂了

步骤三

  • 重启 es3 节点,刷新查看集群状态

节点 es3 恢复中

  • 最终,集群状态恢复为步骤一中的正常状态

步骤四

  • 为索引 app_jgus_yn 动态更新副本数量,将 number_of_replicas 设为 1,即每个主分片都有 1 份副本。
  • 每个分片都拥有了 1 份副本,集群处于 green 状态

动态修改副本数量

步骤五

  • 原主节点宕机,es3 被选为新的主节点。
  • 由于原来每个主分片,都有副本,虽然一个节点宕机了,但其他 2 个节点有所有的数据,依赖可以完成所有的数据操作。此时,集群状态为 yellow。

原主节点宕机,集群依然可以提供服务

  • 一段时间以后,新的集群将达到 green 状态

新的集群达到完美状态

步骤六

  • 恢复原节点,相当于在已经稳定的集群中再新增节点。
  • 集群将在新节点上分配数据,并最终达到新的 green 状态。

集群新增节点

问题排查记录

问题一

在集群搭建完成以后,创建索引过程中,遇到了数据分片 unassigned 的异常。大致情况如下:

分片 unassigned

查看分片 unassigned 原因

1
GET /_cluster/allocation/explain?pretty

查看分片 unassigned 的具体原因

这里是因为空间不够引起的。

解决方案是调整集群磁盘水印的参数。

1
2
3
4
5
6
7
8
PUT /_cluster/settings

{
"persistent": {
"cluster.routing.allocation.disk.watermark.high": "95%",
"cluster.routing.allocation.disk.watermark.low": "93%"
}
}

问题二

集群搭建过程中,配置文件显式指定 transport.tcp.port ,但未显式设置 discovery.zen.ping.unicast.hosts 时,几个节点之间无法组成集群,各自独立。

我在配置时,3 个 es 节点的 transport.tcp.port 分别为 5301、5302、5303。当没有显式设置 discovery.zen.ping.unicast.hosts 时,会自动按照 9300、9301、9302 的端口顺序设置这个广播地址,因此无法与真实的实例端口通信。以上是我通过查看进程占用的端口得出的结论。

参考

谈一谈Elasticsearch的集群部署

ES集群的高可用

ElasticSearch高可用集群环境搭建和分片原理

如何在Elasticsearch中解析未分配的分片(unassigned shards)

Elasticsearch unassigned 故障排查

Elasticsearch 学习笔记 索引创建、插入、查询、修改、删除