Elasticsearch 集群

Cluster 集群

一个 Elasticsearch 集群由一个或多个节点(Node)组成,每个集群都有一个共同的集群名称作为标识。

Node 节点

一个 Elasticsearch 实例即一个 Node,一台机器可以有多个实例,正常使用下每个实例应该会部署在不同的机器上。Elasticsearch 的配置文件中可以通过 node.master、node.data 来设置节点类型。

node.master:表示节点是否具有成为主节点的资格
node.data:表示节点是否存储数据

注意:此属性的值为true,并不意味着这个节点就是主节点。
因为真正的主节点,是由多个具有主节点资格的节点进行选举产生的。
所以,这个属性只是代表这个节点是不是具有主节点选举资格。

主节点+数据节点(默认)

1
2
node.master: true
node.data: true

节点即有成为主节点的资格,又存储数据。这个时候如果某个节点被选举成为了真正的主节点,那么他还要存储数据,这样对于这个节点的压力就比较大了。Elasticsearch 默认每个节点都是这样的配置,在测试环境下这样做没问题。实际工作中建议不要这样设置,这样相当于主节点和数据节点的角色混合到一块了。

数据节点

1
2
node.master: false
node.data: true

节点没有成为主节点的资格,不参与选举,只会存储数据。在集群中需要单独设置几个这样的节点负责存储数据,后期提供存储和查询服务。主要消耗磁盘,内存。

主节点

1
2
node.master: true
node.data: false

不会存储数据,有成为主节点的资格,可以参与选举,有可能成为真正的主节点。普通服务器即可(CPU、内存消耗一般)。

客户端节点

1
2
node.master: false
node.data: false

不会成为主节点,也不会存储数据,主要是针对海量请求的时候可以进行负载均衡。普通服务器即可(如果要进行分组聚合操作的话,建议这个节点内存也分配多一点)

在生产环境下,如果不修改 Elasticsearch 节点的角色信息,在高数据量,高并发的场景下集群容易出现脑裂等问题。

Index 索引

一个集群下可以有多个索引,每个索引是一系列相同格式文档的集合(Elasticsearch 6.x 已不支持一个索引下多个Type)

Shard 分片

每个索引有一个或多个分片,每个分片存储不同的数据。分片可分为主分片( primary shard)和复制分片(replica shard),复制分片是主分片的拷贝。默认每个主分片有一个复制分片(默认一个索引创建后会有5个主分片,即:5主+5复制=10个分片),一个索引的复制分片的数量可以动态地调整,复制分片从不与它的主分片在同一个节点上(防止单点故障)。

复制分片有两个作用:

  1. 提高恢复能力:当主分片挂掉时,某个复制分片可以变成主分片;
  2. 提高性能:get 和 search 请求既可以由主分片又可以由复制分片处理;

集群健康值

  1. green:所有主要分片和复制分片都可用
  2. yellow:所有主要分片可用,但不是所有复制分片都可用
  3. red:不是所有的主要分片都可用

    当集群状态为 red,它仍然正常提供服务,它会在现有存活分片中执行请求,我们需要尽快修复故障分片,防止查询数据的丢失;

Windows 环境搭建集群(3个Node,全部是主节点+数据节点)

下载安装包

http://www.elastic.co/downloads/elasticsearch

解压后复制3份(每份启动一个实例)

3个实例

编辑每个文件下的 config/elasticsearch.yml

根据以下说明调整 elasticsearch.yml 对应参数配置,node2、node3 其他配置与node1一致。

node1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 集群名称,默认是 elasticsearch
cluster.name: es

# 节点名称
node.name: node1

# 是否作为集群的主节点 ,默认 true
node.master: true

# 是否作为集群的数据节点 ,默认 true
node.data: true

# 数据存储位置,默认是es根目录下的data文件夹
path.data: E:\elasticsearch\node1\data

# 日志存储位置,默认是es根目录下的logs文件夹
path.logs: E:\elasticsearch\node1\logs

# 配置访问本节点的地址
network.host: 0.0.0.0

# 设置对外服务的http端口,默认为9200
http.port: 9200

# 设置节点间交互的tcp端口,默认是9300
transport.tcp.port: 9300

# 配置所有用来组建集群的机器的IP地址
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300", "127.0.0.1:9301","127.0.0.1:9302"]

# 配置当前集群中最少具有 master 资格节点数,对于多于两个节点的集群环境,建议配置大于1
discovery.zen.minimum_master_nodes: 2
node2
1
2
3
4
path.data: E:\elasticsearch\node2\data
path.logs: E:\elasticsearch\node2\logs
http.port: 9201
transport.tcp.port: 9301
node3
1
2
3
4
path.data: E:\elasticsearch\node3\data
path.logs: E:\elasticsearch\node3\logs
http.port: 9202
transport.tcp.port: 9302

到目前位置,集群的配置就完成了,下面我们分别启动每个实例。

根据配置文件中的注释:

Prevent the “split brain” by configuring the majority of nodes (total number of master-eligible nodes / 2 + 1)

所以我们配置了 discovery.zen.minimum_master_nodes: 2 ,所以必须有两个主节点启动成功,集群才算生效。

测试

进入目录 elasticsearch-6.2.1-1 启动第一个节点,执行命令:bin\elasticsearch.bat。从日志中可以看出并没有成功,因为没发现足够的master节点。

node1

当第二个master节点启动成功时,整个集群状态变为正常。
node2

3个节点全部启动成功,通过 elasticsearch-head 插件查看集群状态,通过集群健康值:green,表示集群一切正常。目前集群内没有任何数据,所以看不出索引与分片的情况。

Elasticsearch 一般会配合 Kibana + X-Pack 对集群数据分析、监控等,官方标配。这里使用了 elasticsearch-head 插件,一个比较小巧的工具。插件的安装方法请看:elasticsearch-head 安装介绍

elasticsearch-head

添加测试数据:
添加测试数据
test索引分片分布

从截图可以看出,目前一共3个节点,一个索引 test,test 索引有5个主分片(边框加粗),5个复制分片(边框不加粗),分片会别均匀的分布到每个节点中。

我们尝试干掉node3,node3 从集群退出之后,集群在短时间内会对分片进行重新分布,当然依赖遵循主、复制分片不会在同一个Node。

node1+node2

如果我们继续把node2干掉,那么整个集群就挂了,集群健康值:未连接。因为当前可用的主节点数 1 < discovery.zen.minimum_master_nodes 设置的 2。
未连接

我们尝试把 discovery.zen.minimum_master_nodes 设置成 1,然后重启启动一个节点,会发现有一个 Unassigned 的节点,集群健康值:yellow (5 of 10)。这种情况下代表主分片全部可用,存在不可用的复制分片,5个复制分片没有分配到节点上,不过此时的集群是可用的,我们任何请求都能处理,只是所有的操作都落到主分片上,而且可能引发单点故障。当我们把第二个节点启动后,一切就恢复正常了,主分片的数据会同步到复制分片。

一个节点的集群


实际生产环境,每个节点可能设置不同的节点类型,我们在3个节点的基础上再增加两个节点,然后调整 node.master 和node.data 的值,最终设置为2个主节点,2个数据节点,1个客户端节点。

不同节点类型的集群

node1 和 node2 是具有主节点选举权限的节点,这里 node1 被选举为master节点。node3 和 node4 是数据节点,所以数据分片只会分配在这两个节点上。node5 是客户端节点,最终是对请求起到负载均衡的作用。

如果是Linux环境下,启动可能没有这么顺利,可以参考 Linux 环境下安装 elasticsearch 5.x、6.x 问题汇总

如果对你有帮助就好