抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

ElasticSearch 集群管理

img

集群模式

Elasticsearch节点设计支持多种角色,这个是实现集群最重要的前提,节点角色各司其职,也可以任意组合,职责重合。

img

节点角色说明

  • Master,集群管理
  • Voting,投票选举节点
  • Data,数据节点Ingest,数据编辑节点
  • Coordinate,协调节点
  • Machine Learning,集群学习节点

单节点

单节点模式默认开启所有节点特性,具备一个集群所有节点角色,可以认为是一个进程内部的集群

img

​ Elasticsearch在默认情况下,不用任何牌配置也可以运行,这也是它设计的精妙之处,相比其它很多数据产品集群配置,如Mongodb,简化了很多,起步入门容易。

基本高可用

elasticsearch集群要达到基本高可用,一般要至少启动3个节点,3个节点互相连接,单个节点包括所有角色,其中任意节点停机集群依然可用,为什么要至少3个节点?因为集群选举算法奇数法则。

img

数据与管理分离

Elasticserach管理节点职责是管理集群元数据、索引信息、节点信息等,自身不设计数据存储与查询,资源消耗低;相反数据节点是集群存储与查询的执行节点

img

​ 管理节点与数据节点分离,各司其职,任意数据节点故障或者全部数据节点故障,集群仍可用;管理节点一般至少启动3个,任意节点停机,集群仍正常运行。

数据与协调分离

Elasticsearch内部执行查询或者更新操作时,需要路由,默认所有节点都具备此职能,特别是大的查询时,协调节点需要分发查询命令到各个数据节点,查询后的数据需要在协调节点合并排序,这样原有数据节点代价很大,所以分离职责

img

协调读写分离

Elasticsearch设置读写分离指的是在协调节点上,不是数据节点上,集群大量的查询需要消耗协调节点很大的内存与CPU合并结果,同时集群大量的数据写入会阻塞协调节点,所以在协调节点上做读写分离很少必要,也很简单,由集群设计搭建时规划好即可。

img

数据节点标签

​ Elasticsearch给数据节点标签,目的是分离索引数据的分布,在一个集群规模中等以上,索引数据用途多种多样,对于数据节点的资源需求不一样,数据节点的配置可以差异化,有的数据节点配置高做实时数据查询,有的数据节点配置低做历史数据查询,有的数据节点做专门做索引重建。

​ Elasticsearch集群部署时需要考虑基础硬件条件,集群规模越来越大,需要多个数据中心,多个网络服务、多个服务器机架,多个交换机等组成,索引数据的分布与这些基础硬件条件都密切相关

img

主副分片分离

Elasticsearch集群规模大了之后得考虑集群容灾,若某个机房出现故障,则可以迅速切换到另外的容灾机房

img

跨集群操作

​ Elasticsearch单个集群规模不能无限增长,理论上可以,实际很危险,通过创建多个分集群分解,集群直接建立直接连接,客户端可以通过一个代理集群访问任意集群,包括代理集群本身数据。

​ Elasticsearch集群支持异地容灾,采用的是跨集群复制的机制,与同一集群主分片副本分片分离是不同的概念,2个集群完全是独立部署运行,仅数据同步复制。

img

跨集群版本操作

​ elasticsearch版本更新很快,已知问题修复很快,新特性新功能推出很快,一日不学,如隔三秋。有的集群数据重要性很高,稳定第一,不能随意升级,有的业务场景刚好需要最新版本新功能新特性支持。

img

集群管理

集群健康检查

Elasticsearch 的集群监控信息中包含了许多的统计数据,其中最为重要的一项就是集群健康 , 它在 status 字段中展示为 greenyellow 或者 red

查看集群状态

可以通过如下的命令查看集群的状态

1
GET /_cluster/health

image-20220815102706307

集群状态

status 字段是我们最关心的,status 字段指示着当前集群在总体上是否工作正常,它的三种颜色含义如下

  • **green**:所有的主分片和副本分片都正常运行

  • **yellow**:所有数据可用,但有些副本尚未分配(集群功能完全)

  • **red**:有主分片没能正常运行。

注意: 当集群处于红色状态时,正常的分片将继续提供搜索服务,但你可能要尽快修复它。

分片和副本

什么是分片

因为ES是个分布式的搜索引擎, 所以索引通常都会分解成不同部分, 而这些分布在不同节点的数据就是分片

​ 当有大量的文档时,由于内存的限制、磁盘处理能力不足、无法足够快的响应客户端的请求等,一个节点可能不够。这种情况下,数据可以分为较小的分片,每个分片放到不同的服务器上。
​ 当你查询的索引分布在多个分片上时,ES会把查询发送给每个相关的分片,并将结果组合在一起,而应用程序并不知道分片的存在,即:这个过程对用户来说是透明的
​ ES自动管理和组织分片, 并在必要的时候对分片数据进行再平衡分配, 所以用户基本上不用担心分片的处理细节,一个分片默认最大文档数量是20亿。

分片的意义

分片存在的重要原因有以下两个:

  • 允许水平分扩展容量。
  • 允许在分片之上进行分布式的,并行的操作,从而提高其吞吐量。
分片的本质

分片质上是一个lucene的索引,一个分片就是一个lucene索引

​ 一个elasticsearch索引就是一个lucene索引的集合,当进行查询时,会将查询请求发送到每一个属于当前elasticsearch索引的分片上,然后将每个分片得到的结果进行合并返回。

什么是副本

为提高查询吞吐量或实现高可用性,可以使用分片副本。

​ 副本是一个分片的精确复制,每个分片可以有零个或多个副本。ES中可以有许多相同的分片,其中之一被选择更改索引操作,这种特殊的分片称为主分片,当主分片丢失时,如:该分片所在的数据不可用时,集群将副本提升为新的主分片。

​ ES默认为一个索引创建5个主分片,并分别为其创建一个副本分片, 也就是说每个索引都由5个主分片成本,而每个主分片都相应的有一个copy

​ 在一个网络 / 云的环境里,失败随时都可能发生,在某个分片/节点不知怎么的就处于离线状态,或者由于任何原因消失了,这种情况下,有一个故障转移机制是非常有用并且是强烈推荐的。为此目的,Elasticsearch 允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片(副本)。

副本的意义

副本存在的两个重要原因:

  • 提高可用性:注意的是副本不能与主/原分片位于同一节点。
  • 提高吞吐量:搜索操作可以在所有的副本上并行运行。
分片和副本的区别

分片与副本的区别在于:

分片

​ 当你分片设置为5,数据量为30G时,es会自动帮我们把数据均衡地分配到5个分片上,即每个分片大概有6G数据,当你查询数据时,ES会把查询发送给每个相关的分片,并将结果组合在一起。

副本

而副本,就是对分布在5个分片的数据进行复制,因为分片是把数据进行分割而已,数据依然只有一份,这样的目的是保障查询的高效性副本则是多复制几份分片的数据,这样的目的是保障数据的高可靠性,防止数据丢失

分片验证

下面我们验证以下分片的使用

验证一个分片

首先我们通过建立索引的方式来看下什么是分片,会产生哪些变化。

创建索引

我们首先创建一个名为test的索引,让它有一个分片,我们看看结果,在kibana执行以下命令

1
2
3
4
5
6
7
8
9
PUT test
{
"settings":{
"index":{
"number_of_shards" : "1",
"number_of_replicas" : "0"
}
}
}

这样我们就创建了一个分片

image-20220815110858508

查看分片

我们在cerebro中查看结果,我们看到test只在node-2节点上:

image-20220815111124833

验证两个分片

我们再来创建两个分片看看会发生上面

创建索引

我们再次创建两个分片的test1

1
2
3
4
5
6
7
8
9
PUT test1
{
"settings":{
"index":{
"number_of_shards" : "2",
"number_of_replicas" : "0"
}
}
}

这样我们就创建了一个索引

image-20220815111452214

查看分片

我们在cerebro中查看结果,我们看到test1node-1node-3上面

image-20220815111613706

如上图看到分片分别分布在两个节点上,不用想,如果是3个那么肯定均匀分布在三个节点上

验证四个分片

如果我们创建四个分片,多于节点数会发生什么呢

创建索引

我们创建四个分片的索引

1
2
3
4
5
6
7
8
9
PUT test2
{
"settings":{
"index":{
"number_of_shards" : "4",
"number_of_replicas" : "0"
}
}
}

这样我们就创建了一个索引

image-20220815111828553

查看分片

我们发现有两个分片在node-2的节点上

image-20220815112009953

验证副本

下面我们对副本进行验证

验证两副本分片
创建索引

创建一个含有一个分片,两个副本的test3:

1
2
3
4
5
6
7
8
9
PUT test3
{
"settings":{
"index":{
"number_of_shards" : "1",
"number_of_replicas" : "2"
}
}
}

这样我们就创建出来了一个分片带两个分片的索引

image-20220815113453334

查看索引

如下图所示,我们看到了3个绿色的0,其中在node-1节点的边框是粗体的,这个表示分片,而另外两个节点的0的边框是虚线的,这两个就是分片的副本。

image-20220815113556248

通常我们三个节点建立两个副本就可以了,三份数据均匀得到分布在三个节点

验证三副本分片

如果建立三个副本会怎么样呢?

创建索引

创建一个分片三个副本的索引

1
2
3
4
5
6
7
8
9
PUT test4
{
"settings":{
"index":{
"number_of_shards" : "1",
"number_of_replicas" : "3"
}
}
}

image-20220815113859360

查看索引

如下所示我们看到多出一个Unassigned的副本,这个副本其实是多余的了,因为每个节点已经包含了分片的本身和其副本,多于这个没有意义!

image-20220815114015125

并且因为多出来了一个副本无法分配,整个集群都变成了yellow的状态

分片与副本的组合

默认组合

如果不指定分片和副本会怎么样呢

创建索引

创建一个索引不指定副本和索引数量

1
2
3
4
5
6
7
PUT test5
{
"settings":{
"index":{
}
}
}

image-20220815114309027

查看索引

如下图所示看到默认是有一个分片和一个副本的。

image-20220815114404974

两副本两分片

下面我们试验一下两副本两分片,看看会发生什么

创建索引

下面我们创建两个分片和两个副本

1
2
3
4
5
6
7
8
9
PUT test6
{
"settings":{
"index":{
"number_of_shards" : "2",
"number_of_replicas" : "2"
}
}
}

image-20220815114601421

查看索引

我们看到下面就是两副本两分片的情况,每一个分片都有两个副本,如果再多一个副本就会无法再分配了

image-20220815114641375

三分片两副本

下面我们验证以下三分片两副本的情况

创建索引

我们创建一个三个分片两个副本的索引

1
2
3
4
5
6
7
8
9
PUT test7
{
"settings":{
"index":{
"number_of_shards" : "3",
"number_of_replicas" : "2"
}
}
}

image-20220815115034950

查看索引

如下所示看到分片和副本都均匀的分布在每个节点上。

image-20220815115249762

故障与恢复

故障转移

集群的master节点会监控集群中的节点状态,如果发现有节点宕机,会立即将宕机节点的分片数据迁移到其它节点,确保数据安全,这个叫做故障转移。

正常集群状态

下图是正常集群的状态,node1是主节点,其它两个节点是从节点

image-20210723225945963

节点故障

突然,node1发生了故障

image-20210723230020574

宕机后的第一件事,需要重新选主,例如选中了node2

image-20210723230055974

数据迁移

node2成为主节点后,会检测集群监控状态,发现:shard-1、shard-0没有副本节点,因此需要将node1上的数据迁移到node2、node3

image-20210723230216642

节点故障

我们观察下如果三个节点有一个节点宕机了,上文的test7的分片和副本会有哪些变化

关闭node2节点

我们关闭node-2节点

执行关闭命令

我们暂停node-2节点

1
docker pause node-2
查看索引

如下所示,原本的node-2节点变成了Unassigned

​ 注意我标注的三个红框内的分片,这三个分片已经随着节点的宕机消息了,这就造成了数据的丢失,反观后面几个,虽然node2宕机了,但是由于我们做了分片与备份,索引仍然可以正常的工作,

image-20220815134724326

原本在node-2的2号分片移动到了node-1节点,在使用es集群的过程中,一定要注意分片和副本的使用,保证我们整个集群的高可用性

关闭node3节点

我们关闭以下node-3节点看下情况

执行关闭命令

执行如下命令暂停node-3

1
docker pause node-3
查看集群状态

通过Cerebro我们发现整个集群已经无法进行访问了

image-20220815135556926

当集群中的节点数少于半数,将导致整个集群不可用

节点恢复

经过上面的宕机试验后,我们现在要对宕机的服务进行启动

启动node2节点

我们先启动node2节点

执行启动命令

执行下面的命令恢复node-2节点

1
docker unpause node-2
查看集群状态

如上发现集群已经能够恢复访问了

image-20220815140033413

创建索引

此时我们在两个几点可用的情况下创建一个有三分片,两个副本的索引

1
2
3
4
5
6
7
8
9
PUT test8
{
"settings":{
"index":{
"number_of_shards" : "3",
"number_of_replicas" : "2"
}
}
}

image-20220815140156620

查看索引状态

如下所示,分片与副本的分布没有问题,有三个副本未分配

image-20220815140347882

启动node3节点

下面我们就启动node3节点

执行启动命令

执行下面的命令恢复node-2节点

1
docker unpause node-3
查看索引

所有的未分配副本移动到了node-3节点,并没有将分片移动到node-2上

image-20220815140547535

扩缩容

服务布局

我们整体采用Docker方式进行布局,以下是我们需要部署的服务,标红色的我们需要新增的节点

服务名称 服务名称 开放端口 内存限制
ES-node1 node-1 9200 1G
ES-node2 node-2 9201 1G
ES-node3 node-3 9202 1G
ES-node4 node-4 9203 1G
ES-cerebro cerebro 9000 不限
kibana

扩容节点

创建节点目录

创建ES的节点目录

1
2
3
mkdir -p /tmp/data/elasticsearch/node-4/{config,plugins,data,log}
#进行授权
chmod 777 /tmp/data/elasticsearch/node-4/{config,plugins,data,log}
添加IK分词器

只要将其他节点的IK分词器复制过来就可

1
cp -R ik/ /tmp/data/elasticsearch/node-4/plugins/
编写配置文件

我们边界node4节点的配置文件

1
vi /tmp/data/elasticsearch/node-4/config/elasticsearch.yml
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
33
34
35
36
37
38
39
#集群名称
cluster.name: elastic
#当前该节点的名称
node.name: node-4
#是不是有资格竞选主节点
node.master: true
#是否存储数据
node.data: true
#最大集群节点数
node.max_local_storage_nodes: 3
#给当前节点自定义属性(可以省略)
#node.attr.rack: r1
#数据存档位置
path.data: /usr/share/elasticsearch/data
#日志存放位置
path.logs: /usr/share/elasticsearch/log
#是否开启时锁定内存(默认为是)
#bootstrap.memory_lock: true
#设置网关地址,我是被这个坑死了,这个地址我原先填写了自己的实际物理IP地址,
#然后启动一直报无效的IP地址,无法注入9300端口,这里只需要填写0.0.0.0
network.host: 0.0.0.0
#设置映射端口
http.port: 9200
#内部节点之间沟通端口
transport.tcp.port: 9300
#集群发现默认值为127.0.0.1:9300,如果要在其他主机上形成包含节点的群集,如果搭建集群则需要填写
#es7.x 之后新增的配置,写入候选主节点的设备地址,在开启服务后可以被选为主节点,也就是说把所有的节点都写上
discovery.seed_hosts: ["node-1","node-2","node-3"]
#当你在搭建集群的时候,选出合格的节点集群,有些人说的太官方了,
#其实就是,让你选择比较好的几个节点,在你节点启动时,在这些节点中选一个做领导者,
#如果你不设置呢,elasticsearch就会自己选举,这里我们把三个节点都写上
cluster.initial_master_nodes: ["node-1","node-2","node-3"]
#在群集完全重新启动后阻止初始恢复,直到启动N个节点
#简单点说在集群启动后,至少复活多少个节点以上,那么这个服务才可以被使用,否则不可以被使用,
gateway.recover_after_nodes: 2
#删除索引是是否需要显示其名称,默认为显示
#action.destructive_requires_name: true
# 禁用安全配置,否则查询的时候会提示警告
xpack.security.enabled: false
编写部署文档

我们在部署脚本增加node-4节点

1
vi docker-compose.yml
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
version: "3"
services:
node-1:
image: elasticsearch:7.17.5
container_name: node-1
environment:
- "ES_JAVA_OPTS=-Xms1024m -Xmx1024m"
- "TZ=Asia/Shanghai"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
ports:
- "9200:9200"
logging:
driver: "json-file"
options:
max-size: "50m"
volumes:
- /tmp/data/elasticsearch/node-1/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- /tmp/data/elasticsearch/node-1/plugins:/usr/share/elasticsearch/plugins
- /tmp/data/elasticsearch/node-1/data:/usr/share/elasticsearch/data
- /tmp/data/elasticsearch/node-1/log:/usr/share/elasticsearch/log
networks:
- elastic
node-2:
image: elasticsearch:7.17.5
container_name: node-2
environment:
- "ES_JAVA_OPTS=-Xms1024m -Xmx1024m"
- "TZ=Asia/Shanghai"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
ports:
- "9201:9200"
logging:
driver: "json-file"
options:
max-size: "50m"
volumes:
- /tmp/data/elasticsearch/node-2/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- /tmp/data/elasticsearch/node-2/plugins:/usr/share/elasticsearch/plugins
- /tmp/data/elasticsearch/node-2/data:/usr/share/elasticsearch/data
- /tmp/data/elasticsearch/node-2/log:/usr/share/elasticsearch/log
networks:
- elastic
node-3:
image: elasticsearch:7.17.5
container_name: node-3
environment:
- "ES_JAVA_OPTS=-Xms1024m -Xmx1024m"
- "TZ=Asia/Shanghai"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
ports:
- "9202:9200"
logging:
driver: "json-file"
options:
max-size: "50m"
volumes:
- /tmp/data/elasticsearch/node-3/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- /tmp/data/elasticsearch/node-3/plugins:/usr/share/elasticsearch/plugins
- /tmp/data/elasticsearch/node-3/data:/usr/share/elasticsearch/data
- /tmp/data/elasticsearch/node-3/log:/usr/share/elasticsearch/log
networks:
- elastic
node-4:
image: elasticsearch:7.17.5
container_name: node-4
environment:
- "ES_JAVA_OPTS=-Xms1024m -Xmx1024m"
- "TZ=Asia/Shanghai"
ulimits:
memlock:
soft: -1
hard: -1
nofile:
soft: 65536
hard: 65536
ports:
- "9203:9200"
logging:
driver: "json-file"
options:
max-size: "50m"
volumes:
- /tmp/data/elasticsearch/node-4/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
- /tmp/data/elasticsearch/node-4/plugins:/usr/share/elasticsearch/plugins
- /tmp/data/elasticsearch/node-4/data:/usr/share/elasticsearch/data
- /tmp/data/elasticsearch/node-4/log:/usr/share/elasticsearch/log
networks:
- elastic
kibana:
container_name: kibana
image: kibana:7.17.5
volumes:
- /tmp/data/kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml
ports:
- 5601:5601
networks:
- elastic
cerebro:
image: lmenezes/cerebro:0.9.4
container_name: cerebro
environment:
TZ: 'Asia/Shanghai'
ports:
- '9000:9000'
networks:
- elastic
networks:
elastic:
driver: bridge
启动服务

我们完成配置后就可以启动服务了

1
docker-compose up -d
查看节点信息

我们可以在监控界面看到节点的信息,我们发现节点4已经加入进来了

image-20220920112324300

节点缩容

接下来我们要将node4节点去掉完成缩容操作

禁止数据分配

我们先排除node-4节点,禁止数据在该节点分配数据,然后才能停止节点,如果想正常缩容,这里填上所有要缩容的节点名称就可以了

1
2
3
4
5
6
PUT /_cluster/settings
{
"persistent": {
"cluster.routing.allocation.exclude._name": "node-4"
}
}

image-20220920113249782

检查数据分配

接下来检查一下缩容节点的数据迁移情况,我们发现数据已经全部迁移完成了

image-20220920113342936

关闭节点

等到数据全部迁移完成后就可以进行缩容节点了

1
docker-compose stop node-4

image-20220920113536524

查看集群情况

接下来看一下集群的情况,我们发现已经缩容成功了,并且没有出现主分片丢失的情况

image-20220920113615163

评论