集群
单机的elasticsearch做数据存储,必然面临两个问题:海量数据存储问题、单点故障问题。
●海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard),存储到多个节点
●单点故障问题:将分片数据在不同节点备份(replica )
ES集群相关概念:
● 集群(cluster):一组拥有共同的 cluster name 的 节点。
● 节点(node) :集群中的一个 Elasticearch 实例
● 分片(shard):索引可以被拆分为不同的部分进行存储,称为分片。在集群环境下,一个索引的不同分片可以拆分到不同的节点中
解决问题:数据量太大,单点存储量有限的问题。
图片加载失败
全部索引数据
分片2
分片0
分片1
SHARD1
SHARD2
SHARDO
此处,我们把数据分成3片:shard0、shard1、shard2
● 主分片(Primary shard):相对于副本分片的定义。
● 副本分片(Replica shard)每个主分片可以有一个或者多个副本,数据和主分片一样。
数据备份可以保证高可用,但是每个分片备份一份,所需要的节点数量就会翻一倍,成本实在是太高了!
为了在高可用和成本间寻求平衡,我们可以这样做:
●首先对数据分片,存储到不同节点
●然后对每个分片进行备份,放到对方节点,完成互相备份
这样可以大大减少所需要的服务节点数量,如图,我们以3分片,每个分片备份一份为例:
全部索引数据
分片1
分片0
分片2
SHARDO
SHARD1
SHARD2
分片0备份
分片2
分片0
SHARD2
SHARDO-REPLICA
SHARDO
分片1备份
分片1
分片2备份
SHARD1
SHARD1-REPLICA
SHARD2-REPLICA
NODE-1
NODE-O
NODE-2
现在,每个分片都有1个备份,存储在3个节点:
●node0:保存了分片0和1
●node1:保存了分片0和2
●node2:保存了分片1和2
1.搭建ES集群
我们会在单机上利用docker容器运行多个es实例来模拟es集群。不过生产环境推荐大家每一台服务节点仅部署一个es的实例。部署es集群可以直接使用docker-compose来完成,但这要求你的Linux虚拟机至少有4G的内存空间。
1.创建es集群
首先编写一个docker-compose文件(我们已经帮大家准备好了,直接上传即可),内容如下:
创建一个存放路径。我们再tmp目录下创建一个文件件:es-cluster,将文件上传进去
X
1 LRONMAN
查看
仆排序
新建
[ROOT@LOCALHOST ES-CLUSTER]#PWD
/TMP/ES-CLUSTER
[ROOT@LOCALHOST ES-CLUSTER]#
DAY6-分布..>3-资料
在3-资料中搜索
修改
名称
图片
1
202
回收站
202
音乐
ASSETS
202
HOTEL-ADMIN
视频
202
此电脑
PY
CEREBRO-0.9.4.ZIP
202
4-备课视频
202
DOCKER-COMPOSE.YML
3-资料
ELASTICSEARCH-ANALYSIS-PINYIN-7.12.1.ZIP
202
基础篇预习资料
机
202
HOTEL-ADMIN.ZIP
3-资料
命令输入(按ALT键提示历!
历史
选项
202
安装ELASTICSEARCH.MD
自定义分词器JSONC
2023
命令
文件
ONEDRIVE
历史
/TMP/ES-CLUSTER
WPS云盘
类型
文件名
大小
7002
.英),
此电脑
YAML 源...
DOCKER-COMPOSE.Y...
1.4 KB
7003
7004
WINDOWS(C:)
8001
DATA(D:)
8002
es运行需要修改一些linux系统权限,修改/etc/sysctl.conf文件
添加下面的内容:
# SYSCTL
TL SETTINGS ARE DEFINED THROUGH FILES IN
#/USR/LIB/SYSCTL.D/,/RUN/SYSCTL.D/,AND /ETE/SYSCTL.D/.
#
# VENDORS SETTINGS LIVE IN /USR/LIB/SYSCTL.D/.
# T
FILE OVERRIDE A WHOLE FILE, CREATE A NEW FILE W
LE WITH THE SAME
IN
TO OVERRIDE
# /ETC/SYSCTL.D/ AND PUT NEW SETTINGS THERE.
# ONLY SPECIFIC SETTINGS, ADD A
LEXICALLY LATER
FILEWITHA
ND PUT NEW SETTINGS THERE,
NAMEIN/ETC/SYSCTLDAND
# FOR MORE INFORMATION, SEE SYSCTL.CONF(5) AND SYSCTL.D(5).
VM.MAX MAP_COUNT262144
然后执行命令,让配置生效:
[ROOT@LOCALHOST
]# SYSCTL
-P
出现这个,说明正常
VM,MAX MAP COUNT 三 262144
如果上面创建了文件夹,则在/tmp/es-cluster路径下执行下述命令,通过docker-compose启动集群:
192.168.206.130
复制
[ROOT@LOCALHOST ES-CLUSTER]# DOCKER-COMPOSE UP
系统信息
RECREATING ES01... DONE
CREATING ES02
. DONE
行4:59
CREATING ES03
DONE
载1.76,0.89,0.47
[ROOT@LOCALHOST ES-CLUSTER]#
78%
PU
存54%
4.1G/7.6G
换0%
0/4G
存
CPU
260.9...140.4 JAVA
可以通过:docker logs -f es02查看启动日志,会发现左侧CPU基本打满
通过docker ps查看应用是否启动完成(状态都是up)
CLUSTERL# DOCKER PS
[ROOT@LOCALHOST ES-CL
COMMAND
STATUS
CONTAINER ID
IMAGE
PORTS
CREATED
NAMES
"/BIN/TINI
201-9200/TCP,:::9201->920
ELASTICSEARCH:7.12.1
UP ABOUT A MINUTE
0.0:9201
0.0.0
B02A62EB8F2A
/USR/
9300/TCP,
ABOUT A MINUTE
AGO
ES01
0/TCP
"/BIN/TINI--/USR/L.."
0:9203->9200/TCP, ::9203->920
ELASTICSEARCH:7.12.1
0.0:92
9300/TCP
0.0.0.
UP ABOUT A MINUTE
ABOUT
EDCC139B6395
MINUTE
AGO
0/TCP
ES03
9300/TCP,
ELASTICSEARCH:7.12.1
95F3087E2510
/USR/L..."
UP ABOUT A MINUTE
0.0.0.0:9202
02>920
"/BIN/TINI
ABOUT A MINUTE AGO
9200/TCP,:9202
0/TCP
ES02
5 DAYS AGO
"/BIN/TINI
73EB559BE4C4
0.0.0.0:5601->5601/TCP,
::5601-5601/TCP
KIBANA:7.12.1
UP 5 HOURS
/USR/L,.
KIBANA
2.集群状态监控
kibana可以监控es集群,不过新版本需要依赖es的x-pack 功能,配置比较复杂。这里推荐使用cerebro来监控es集群状态,官方网址:https://github.com/lmenezes/cerebro,或使用提供的安装包
cerebro-0.9.4.zip(54.6 MB),双击bin目录下的cerebro.bat文件即可启动服务。
命令提示符-CEREBRO.BAT
MICROSOFT WINDOWS [版本 10.0.19042.985]
(C)MICROSOFT CORPORATION.保留所有权利.
D:\LESSON\CEREBRO-0.9.4\BIN>CEREBRO.BAT
I REFLECTIVE ACCESS OPERATION HAS OCCURRED
WARNING: AN ILLEGAL REFL
WARNING; ILLEGAL REFLECTIVE ACCESS BY CON-BOOBLE.INJECT,INTERNAL-CQLIB~COREFLECTUTILSS1 (FILE:///////
/CEREBRO-0.9.4/LIB/COM.GOOGLE.INJECT.GUICE-4.2.3.JAR) T
OD JAVA.LANG.CLASSLOADER.DEFINECLASS(JAVA.LANG.
TO METHOD JI
STRING,BYTE[],INT,INT,JAVA.SECURITY.PROTECTIONDOMAIN)
MARNING: PLGASE CONSIDER REPORTING THIS TO THE MAINTAINERS OF COM.BOOBLE-INJECT.INTERNAL-CORE.SREFLAC
UTILS$1
WARNING: USE --ILLEGAL-ACCESS-WARN TO ENABLE WARNINGS OF FURTHER ILLEGAL REFLECTIVE ACCESS OPERATIONS
WARNING: ALL ILLEGAL ACCESS OPERATIONS WILL BE DENIED IN A FUTURE RELEASE
[INFO] PLAY.API.PLAY - APPLICATION STARTED (PROD) (NO GLOBAL STATE)
[INFO] P.C.S.AKKAHTTPSERVER
NING FOR HTTP ON /[0:0:0:0:0:0:0]:9000
LISTENING F
访问http://localhost:9000 即可进入管理界面:
注意:输入地址需要完整:http://192.168.206.130:9201
CEREBRO V0.9.3
NODE ADDRESS
CONNECT
黑马程序员
输入你的elasticsearch的任意节点的地址和端口,点击connect即可:
MORE
15SEC
REST
OVERVIEW
NODES
1 GREEN
绿色,说明集群正常
O CHARDS
0B
ES-DOCKER-CLUSTER
DOCS
NODES
0-0 OF 0
FILTER INDICES BY NAME OR ALI.
FILTER NODES BY NAME
CLOSED
SPECIAL
(O)
(0)
AZ
ES01
8172.23.0.4
536870912
LOAD
DISK
HEAP
CPU
ES02
172.23.0.3
斗
536870912
LOAD
HEAP
CPU
DISK
实心标识的是当前集群的主节点
SES03
172.23.0.2
536870912
LOAD
DISK
HEAP
CPU
13:30
绿色的条,代表集群处于绿色(健康状态)。
3.创建索引库
方式一:利用kibana的DevTools创建索引库
在DevTools中输入指令:
方式二:利用cerebro创建索引库
利用cerebro还可以创建索引库:
OVERVIEW
NODES
MORE
REST
CREATE INDEX
CLUSTER SETTINGS
ES-DOCKER-CLUSTER
ALIASES
ANALYSIS
FILTOR INDICOE HY NAMO ALIACAE
填写索引库信息:
C'REST
HFIP/192 168 206 130:9201 [GREEN]
RODES
MORE
索引库名称
NUMBER OF REPLICAS
NUMBEROF SHARDS
每个分片的副本数,如果是1就表示每个分片只有1个副本
分片数量
3
在此配置中就最终会变成:3个分片+3个副本
LOAD SETTINGS FROM EXISTING INDEX
点击就可创建
CREALE
01:1
点击右下角的create按钮:
HTTP://192.168.206.130:9201[YELLOW]
15SEC
INDICES CREATED
INDEX SUCCESSFULLY CREATED
创建之后,会提示成功
4.查看分片效果
回到首页,即可查看索引库分片效果:
S15SEC
LA OVERVIEW
HTTP://192.168.206.130:9201[GREEN]
2 REST
1.22KB
0 DOCS
1 INDICES
ES-DOCKER-CLUSTER
SHARDS
3 NODES
1-10F 1
FILTER NODES BY NAME
CLOSED(0)
SPECIAL(0)
FILTER INDICES BY NAME OR ALIASES
合C501
8 1723.04
女
实线是主分片
536870912
虚线是副本分片
同时会发现:主副分片都在不同节点,任意两个分片会拼接出一个完整的集群信息
536870912
LOAD
HEAP
GPU
DISK
01
6503
B 172.23.0.2
536870912
10AD
16AP
CPU
2.集群脑裂问题
2.1.集群职责划分
elasticsearch中集群节点有不同的职责划分:
节点职责
配置参数
默认值
节点类型
备选主节点:主节点可以管理和记录集群状态,决定
MASTER ELIGIBLE
TRUE
NODE.MASTER
分片在哪个节点,处理创建和删除索引库的请求
数据节点:存储数据,搜索,聚合,CRUD
DATA
TRUE
NODE.DATA
数据存储之前的预处理
INGEST
NODE.INGEST
TRUE
路由请求到其它节点
上面3个参数都为FALSE
COORDINATING
无
则为COORDINATING节点
合并其它节点处理的结果,返回给用户
默认情况下,集群中的任何一个节点都同时具备上述四种角色。但是真实的集群一定要将集群职责分离:
●master节点:对CPU要求高,但是内存要求低
●data节点:对CPU和内存要求都高
●coordinating节点:对网络带宽、CPU要求高
职责分离可以让我们根据不同节点的需求分配不同的硬件去部署。而且避免业务之间的互相干扰。
一个典型的es集群职责划分如图:
DATA
MASTER-
DATA
COORDINATING
ELIGIBLE
MASTER-
COORDINATING
DATA
LB
ELIGIBLE
MASTER-
DATA
COORDINATING
ELIGIBLE
DATA
2.2.脑裂问题
脑裂是因为集群中的节点失联导致的。例如一个集群中,主节点与其它节点失联:
众
NODE3
NODE2
NODE1
网络阻塞
此时,node2和node3认为node1宕机,就会重新选主:
NODE3
NODE1
NODE2
网络阻塞
当node3当选后,集群继续对外提供服务,node2和node3自成集群,node1自成集群,两个集群数据不同步,出现数据差异。
当网络恢复后,因为集群中有两个master节点,集群状态的不一致,出现脑裂的情况:
NODE1
NODE2
NODE3
图片加载失败
解决脑裂的方案是,要求选票超过 ( eligible节点数量 + 1 )/ 2 才能当选为主,因此eligible节点数量最好是奇数。对应配置项是discovery.zen.minimum_master_nodes,在es7.0以后,已经成为默认配置,因此一般不会发生脑裂问题
例如:3个节点形成的集群,选票必须超过 (3 + 1) / 2 ,也就是2票。node3得到node2和node3的选票,当选为主。node1只有自己1票,没有当选。集群中依然只有1个主节点,没有出现脑裂。
2.3.小结
master eligible节点的作用是什么?
●参与集群选主
●主节点可以管理集群状态、管理分片信息、处理创建和删除索引库的请求
data节点的作用是什么?
●数据的CRUD
coordinator节点的作用是什么?
● 路由请求到其它节点
● 合并查询到的结果,返回给用户
3.集群分布式存储
当新增文档时,应该保存到不同分片,保证数据均衡,那么coordinating node如何确定数据该存储到哪个分片呢?
3.1.分片存储测试
插入三条数据:
HTTP://192.168.150.101:9200/ITCAST/_DOC/1
POST
HEADERS (9)
SETTINGS
AUTHORIZATION
TESTS
PARAMS
PRE-REQUEST SCRIPT
BODY
BINARYGRAPHQL
X-WWW-FORM-URLENCODED
JSON
FORM-DATA
RAW
NONE
1
23
..."TITLE":."我试着插入一条,ID.三.1"
7
HTTP://192.168.150.101:9200/ITCAST/_DOC/3
POST
SETTINGS
HEADERS (9)
PRE-REQUEST SCRIPT
AUTHORIZATION
TESTS
BODY
PARAMS
X-WWW-FORM-URLENCODED
FORM-DATA
GRAPHQL
JSON
BINARY
NONE
RAW
."TITLE":"我试着插入一条,ID.三.3"
2
3
HTTP://192.168.150.101:9200/ITCAST/_DOC/5
POST
BODY
SETTINGS
TESTS
PARAMS
PRE-REQUEST SCRIPT
AUTHORIZATION
HEADERS (9)
FORM-DATA
BINARY
GRAPHQL
JSON
X-WWW-FORM-URLENCODED
RAW
NONE
1
"TITLE":"我试着插入一条,ID.-5"
2
3
测试可以看到,三条数据分别在不同分片:
HTTP://192.168.150.101:9200/ITCAST/_SEARCH
GET
PRE-REQUEST SCRIPT
SETTINGS
HEADERS (9)
TESTS
BODY
PARAMS
AUTHORIZATION
GRAPHQL
BINARY
FORM-DATA
JSON
X-WWW-FORM-URLENCODED
RAW
NONE
1 S
2
"EXPLAIN":
TRUE,
345
"QUERY":
好
"MATCH_ALL":
6
结果:
[ITCAST][1]",
SHARD":
"HHY3NGSLRII5CCLMYPSXJQ",
NODE"
_INDEX":"ITCAST",
_TYPE": " DOC",
ID":"3",
SCORE":1.0,
SOURCE":
"TITLE":"试着插入一条 ID
ID - 3"
EXPLANATION":
"VALUE":1.0,
"DESCRIPTION":"**",
"DETAILS":
_SHARD": "[ITCAST][2]",
"APLHLP8QSOKS5GH9PMNC A",
NODE":"
INDEX":"ITCAST",
_TYPE":"_DOC",
ID": "1",
SCORE":1.0,
SOURCE
"TITLE":"试着插入一条ID 1"
3.2.分片存储原理
elasticsearch会通过hash算法来计算文档应该存储到哪个分片:
SHARD 三 HASH(_ROUTING) %
SHARDS
NUMBER
OF
说明:
●_routing默认是文档的id
●算法与分片数量有关,因此索引库一旦创建,分片数量不能修改!
新增文档的流程如下:
新增文档流程:
1.新增文档ID1
3.路由到对应分片
PRIMARYSHARD2
2.HASH运算,得到2
4.保存文档
5.同步
7.返回结果
给副本
分片
P-1
P-2
R-1
R-2
P-0
R-O
NODE1
NODE2
NODE3
6.返回结果到COORDINATING NODE
解读:
●1)新增一个id=1的文档
●2)对id做hash运算,假如得到的是2,则应该存储到shard-2
●3)shard-2的主分片在node3节点,将数据路由到node3
●4)保存文档
●5)同步给shard-2的副本replica-2,在node2节点
●6)返回结果给coordinating-node节点
4.集群分布式查询
elasticsearch的查询分成两个阶段:
● scatter phase:分散阶段,coordinating node会把请求分发到每一个分片
● gather phase:聚集阶段,coordinating node汇总data node的搜索结果,并处理为最终结果集返回给用户
COORDINATING
-
NODE
P-1
R-O
R-2
P-2
P-0
R-1
-
NODE2
NODE1
NODE3
5.集群故障转移
集群的master节点会监控集群中的节点状态,如果发现有节点宕机,会立即将宕机节点的分片数据迁移到其它节点,确保数据安全,这个叫做故障转移。
1)例如一个集群结构如图:
P-1
P-0
R-0
R-1
R-2
P-2
-
NODE1
NODE2
NODE3
现在,node1是主节点,其它两个节点是从节点。
2)突然,node1发生了故障:
图片加载失败
P-2
P-1
R-1
R-2
P-0
R-0
NODE2
NODEL
NODE3
宕机后的第一件事,需要重新选主,例如选中了node2:
P-1
R-1
P-2
R-2
P-0
R-O
NODE2
NODE3
NODEL
node2成为主节点后,会检测集群监控状态,发现:shard-1、shard-0没有副本节点。因此需要将node1上的数据迁移到node2、node3:
R-1
P-0
P-1
R-2
P-2
P-0
R-O
R-1
NODE2
NODE3
NODEL
图片加载失败
验证一下:docker ps,会发现3个集群节点都正常
[ROOT@LOCALHOST ES-CLUSTER]# DOCKER PS
STATUS
IMAGE
CREATED
PORTS
COMMAND
CONTAINER ID
NAMES
/USR/L
"/BIN/TINI
9300/TCP,0.0.0.0:9201->9200/TCP,:::::9201->9200/TCP
ELASTICSEARCH;7.12.1
26 MINUTES
B02A62EB8F2A
UP 26 MINUTES
AGD
ES01
"/BIN/TINI
9300/TCP,
UP 26 MINUTES
ELASTICSEARCH:7.12.1
0.0.0.
26
/USR/L...
0.0.0.0:9203->9200/TCP,:::9203->9200/TCP
EDCC139B6395
MINUTES
AGG
ES03
9300/TCP,0.0.0.0.9202->9200/TCP,:::::9202->9200/TCP
UP 26 MINUTES
"/BIN/TINI
95F3087E2510
26
/USR/...
ELASTICSEARCH:7.12.1
MINUTES
AGO
ES02
去cerebro查看也都正常
Z REST
OVERVIEW
NODES
MORE
ES-DOCKER-CLUSTER
6 SHARDS
NODES
INDICES
FILTER NODES BY NAME
CLOSED(0)
FILTER INDICES BY NAME OR ALIASES
-SPECIAL(0)
ITCAST
会
SIZE:8.26KB
食ES01
8172.23.0.4
女
536870912
LOAD
CPU
HEAP
DISK
目前集群正常,22成对
食ES02
日172.23.0.3
女
536870912
LOAD
DISK
HEAP
CPU
ES03
日172.23.0.2
耳
536870912
HEAP
LOAD
DISK
CPU
此时,我们挂机主节点,目前是es03,所以我们应该(停掉当前的主节点才可以):docker rm -f es03
[ROOT@LOCALHOST ES-CLUSTER]# DE
DOCKER RM -F ES03
ES03
[ROOT@LOCALHOST ES-CLUSTER]# DOCKER
PS
STATUS
PORTS
CONTAINER ID
IMAGE
COMMAND
CREATED
此时发现,只有两个节点正常
NAMES
9300/TCP,0.0.0.0:9201->9200/TCP,:::::9201->9200/TCP
"/BIN/TINI
E
ELASTICSEARCH:7.12.1
B02A62EB8F2A
28
UP 28 MINUTES
/USR/L
MINUTES
AGO
ES01
0.0.0.0:9202-9200/TCP,::9202-9200/TCP
95F3087E2510
ELASTICSEARCH:7.12.1
"/BIN/TINI--/USR/.."
28
UP 28 MINUTES
9300
MINUTES
TCP,
AGO
ES02
0.0.0.0:5601->5601/TCP,
5 DAYS AGO
73EB559BE4C4
"/BIN/TINI
KIBANA:7.12.1
::5601--5601/TCP
UP 5 HOURS
/USR/L...
KIBANA
绿条变黄了,说明集群不健康
S15SEC
ISAL2
HTTP://192.168.206.130.9201[YELLOW]
NODES
MORE
12.22KB
1 INDIOES
ES-DOCKER-CLUSTER
6 SHARDS
2 NODES
DOCS
1-10L1
CLOSED(0)
FITER INDICES BY NAME OR ALIASES
FITER NODES BY NAME
SPECIAL(0)
ITCAST
SHARDS321 CBCS 81 SIZE 8 26KB
主节点已经挂机,变灰色了
12UNASSIGNED SHARDS
SHOW ONLY ALIECLED INDICES
2!
ES01
2172.23.04
下面的节点,还在做数据迁移备份中,因此目前仍只有两个节点(1主1副)
536870912
LOAD
HEAP DISK
日172.23.0.3
536870912
DISK
HEAP
S 155EC
HTTP(/192 168.206.130:9201 [GREEN]
又绿了,真好
CREST
L NODES
TH OVERVIEW
MORE
16.53KB
ES-DOCKER-CLUSTER
3 DOCS
SHARDS
2 NODES
1-1 OF1
SPECIAL(0)
FILLER INDICES BY NAME OR ALIASES
FILLER NODES BY NAME
CLOSED(0)
ILCAST
112
81723.04
女
536870912
LOAD
CPU
稍等一点点时间后,会发现,服务恢复
日
耳
536870912
DISK
HCAN