集群初步认识
前言
在elasticsearch中,一个节点(node)就是一个elasticsearch实例,而一个集群(cluster)由一个或多个节点组成,它们具有相同的cluster.name
,并且协同工作,分享数据和负载。当加入新节点或者删除一个节点时,集群就会感知平衡数据
发现节点
es 使用两种不同的方式来发现对方
- 广播
- 单播
两者可以同时使用,但默认的广播,单播需要已知的节点列表来完成
广播
当es实例启动的时候,它发送了广播的ping请求到地址224.2.2.4:54328
。而其他的es实例使用相同的集群名称响应了这个请求。
一般默认的集群名称就是上面的cluster_name
对应的elasticsearch
。
单播
当节点的ip不经常变化的时候,或者es只连接特定的节点。单播发现是个很理想的模式。使用单播时,我们告诉es集群其他节点的ip及(可选的)端口及端口范围。我们在elasticsearch.yml
配置文件中设置:
discovery.zen.ping.unicast.hosts: ["10.0.0.1", "10.0.0.3:9300", "10.0.0.6[9300-9400]"]
一般的,我们没有必要关闭单播发现,如果你需要广播发现的话,配置文件中的列表保持空白即可。
选取主节点
无论是广播发现还是单播发现,一旦集群中的节点发生变化,它们就会协商谁将会成为主节点,elasticsearch认为所有节点都有资格成为主节点。如果集群中只有一个节点,那么该节点首先会等一段时间,如果还是没有发现其他节点,机会任命自己为主节点。
对于节点数较少的集群,我们可以设置主节点的最小数量,虽然这么设置看上去集群可以拥有多个主节点。实际上这么设置是告诉集群有多少个节点有资格成为主节点。怎么设置?修改配置文件中的:
discovery.zen.minimum_master_nodes: 3
什么是脑裂
脑裂这个词描述的是这样一个场景:(通常是在重负荷或网络存在问题时)elasticsearch集群中一个或者多个失去和主节点的通信,然后各节点就开始选举新的主节点,继续处理请求。这个时候,可能有两个不同的集群在相互运行着,这就是脑裂一次的由来,因为单一集群被分成了两部分。为了防止这种情况的发生,我们就需要设置集群节点的总数,规则就是节点总数除以2在加上一。这样,当一个或者多个节点失去通信,子节点就无法选举出新的主节点来形成新的集群。因为这些子节点们无法满足设置的规则数量。
通过下图来说明如何防止脑裂。比如现在,有这样一个5个点节点的集群,并且都有资格成为主节点
为了防止脑裂,我们对该集群设置参数:
discovery.zen.minimum_master_nodes: 3 # 3=5/2+1
之前原集群的主节点是node1
,由于网络和负荷等原因,原集群被分为了两个switch
:node1和node2
、node3、node4、node5
。因为minimum_master_nodes
参数是3,所以node3、4、5
可以组成集群,并且选举出了主节点node3
。而node1、2
节点因为不满足minimum_master_nodes
条件而无法选举,只能一直寻求加入集群(还记得单播列表吗?),要么网络和负荷恢复正常后加入node3、4、5
组成的集群中,要么就是一直处于寻找集群状态,这样就防止了集群的脑裂问题。
除了设置minimum_master_nodes
参数,有时候还需要设置node_master
参数,比如有两个节点的集群,如果出现脑裂问题,那么它们自己都无法选举,因为都不符合半数以上。这时我们可以指定node_master
,让其中一个节点有资格成为主节点,另外一个节点只能做存储用。当然这是特殊情况。
那么,主节点是如何知道某个小老弟(节点)还活着呢?这就要说到错误识别了。
错误识别
其实错误识别,就是当主节点被确定后,建立起内部的ping机制来确保每个节点在集群中保持活跃和健康,这就是错误识别。
主节点ping集群中的其他节点,而且每个节点也会ping主节点来确认主节点还活着,如果没有响应,则宣布该节点失联。想象一下,老大要时不常的看看(循环)小弟们是否还活着,而小老弟们也要时不常的看看老大还在不在,不在了就赶紧再选举一个出来!
但是,怎么看?多久没联系算是失联?这些细节都是可以设置的,不是一拍脑门子,就说某个小老弟挂了!在配置文件中,可以设置:
discovery.zen.fd.ping_timeout: 30s
discovery.zen.fd.ping_retries: 6
discovery.zen.fd.ping_interval: 30s
每个节点每隔ddiscovery.zen.fd.ping_interval
的时间(默认1秒)发送一个ping请求,等待discovery.zen.fd.ping_timeout
的时间(默认30秒),并尝试最多discovery.zen.fd.ping_retries
次(默认3次),无果的话,宣布节点失联,并且在需要的时候进行新的分片和主节点选举。
根据开发环境,适当修改这些值。
成为主节点的资格
之前当主节点node1被干掉后,为什么node4被选举出来,这其中是否存在着py
交易暂且不提。但能说的是,集群下的各节点都有资格被选举为主节点。所以node4上位后,就在思考,要把这资格收回来,怎么做呢?其实在配置文件中可以体现
node.master: false # 该节点是否可以被选举为主节点,默认为true
node.data: true # 该节点是否有存储权限,默认为true
我们通过node.master来设置哪个节点有资格称为主节点。
停用节点
很多时候,我们需要维护的时候,就需要关闭某个节点,那怎么做呢?
PUT /_cluster/settings
{
"transient": {
"cluster.routing.allocation.exclude._ip": "192.168.1.1"
}
}
一旦执行上述命令,elasticsearch将该节点上的全部分片转移到其他的节点上。并且这个设置是暂时的,集群重启后就不再有效。
集群搭建
window单机集群搭建(快速入门)
架构如下:
目录结构
--es-cluster
-- elasticsearch1
-- elasticsearch2
-- elasticsearch3
-- kibana
集群配置
现在,我们为这个集群增加一些单播配置,打开各节点内的\config\elasticsearch.yml
文件。每个节点的配置如下(原配置文件都被注释了,可以理解为空,各节点的配置,直接粘贴进去,没有动注释的,出现问题了好恢复)
-
elasticsearch1节点,,集群名称是my_es1,集群端口是9300;节点名称是node1,监听本地9200端口,可以有权限成为主节点和读写磁盘(不写就是默认的)。
cluster.name: my_es1 node.name: node1 network.host: 127.0.0.1 http.port: 9200 transport.tcp.port: 9300 discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300", "127.0.0.1:9302", "127.0.0.1:9303", "127.0.0.1:9304"]
-
elasticsearch2节点,集群名称是my_es1,集群端口是9302;节点名称是node2,监听本地9202端口,可以有权限成为主节点和读写磁盘。
cluster.name: my_es1 node.name: node2 network.host: 127.0.0.1 http.port: 9202 transport.tcp.port: 9302 node.master: true node.data: true discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300", "127.0.0.1:9302", "127.0.0.1:9303", "127.0.0.1:9304"]
-
elasticsearch3节点,集群名称是my_es1,集群端口是9303;节点名称是node3,监听本地9203端口,可以有权限成为主节点和读写磁盘。
cluster.name: my_es1 node.name: node3 network.host: 127.0.0.1 http.port: 9203 transport.tcp.port: 9303 discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300", "127.0.0.1:9302", "127.0.0.1:9303", "127.0.0.1:9304"]
-
elasticsearch4节点,集群名称是my_es1,集群端口是9304;节点名称是node4,监听本地9204端口,仅能读写磁盘而不能被选举为主节点。
cluster.name: my_es1 node.name: node4 network.host: 127.0.0.1 http.port: 9204 transport.tcp.port: 9304 node.master: false node.data: true discovery.zen.ping.unicast.hosts: ["127.0.0.1:9300", "127.0.0.1:9302", "127.0.0.1:9303", "127.0.0.1:9304"]
由上例的配置可以看到,各节点有一个共同的名字my_es1,但由于是本地环境,所以各节点的名字不能一致,我们分别启动它们,它们通过单播列表相互介绍,发现彼此,然后组成一个my_es1集群。谁是老大则是要看谁先启动了。
kibana测试
打开kibana,通过左侧菜单栏的Monitoring
来监控各集群的健康状况。
centos集群部署
node-1
安装Java环境
[root@cs tmp]# pwd
/tmp
[root@cs tmp]# yum install java-1.8.0-openjdk.x86_64 -y
[root@cs tmp]# java -version
openjdk version "1.8.0_292"
OpenJDK Runtime Environment (build 1.8.0_292-b10)
OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)
安装elasticsearch
[root@cs tmp]# wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.8.15.rpm
[root@cs tmp]# rpm -ivh elasticsearch-6.8.15.rpm
[root@cs tmp]# systemctl daemon-reload
[root@cs tmp]# rm -rf elasticsearch-6.8.15.rpm
[root@cs tmp]# rpm -qc elasticsearch
/etc/elasticsearch/elasticsearch.yml
/etc/elasticsearch/jvm.options
/etc/elasticsearch/log4j2.properties
/etc/elasticsearch/role_mapping.yml
/etc/elasticsearch/roles.yml
/etc/elasticsearch/users
/etc/elasticsearch/users_roles
/etc/init.d/elasticsearch
/etc/sysconfig/elasticsearch
/usr/lib/sysctl.d/elasticsearch.conf
/usr/lib/systemd/system/elasticsearch.service
注意,elasticsearch服务的运行需要以非root权限运行,但rpm安装时,默认帮我们创建了一个elasticsearch用户,所以,接下来,这里,我手动创建一个数据文件目录,然后给相关目录进行授权:
mkdir -p /data/elasticsearch
chown -R elasticsearch:elasticsearch /data/elasticsearch/
chmod -R g+s /data/elasticsearch/
chown -R elasticsearch:elasticsearch /etc/elasticsearch/
chown -R elasticsearch:elasticsearch /etc/init.d/elasticsearch
chown -R elasticsearch:elasticsearch /etc/sysconfig/elasticsearch
chown -R elasticsearch:elasticsearch /var/log/elasticsearch/
chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/
chown -R elasticsearch:elasticsearch /usr/lib/sysctl.d/elasticsearch.conf
chown -R elasticsearch:elasticsearch /usr/lib/systemd/system/elasticsearch.service
必要的配置
为了后续能正常启动集群,需要提前对系统参数和内核参数做些配置。
修改系统参数:
[root@cs tmp]# vim /etc/security/limits.conf
# 可打开的文件句柄最大数
* soft nofile 65535
* hard nofile 65535
# 单个用户可用的最大进程数
* soft nproc 4096
* hard nproc 4096
# 可打开的文件描述符的最大数,unlimited:无限制
* soft memlock unlimited
* hard memlock unlimited
修改内核参数:
[root@cs tmp]# vim /etc/sysctl.conf
# JAM能开启的最大线程数
vm.max_map_count = 262144
[root@cs tmp]# sysctl -p # 使修改的内核参数生效
vm.max_map_count = 262144
为了避免内存锁定失败,还需要:
[root@cs tmp]# sudo systemctl edit elasticsearch
[Service]
LimitMEMLOCK=infinity
[root@cs tmp]# sudo systemctl daemon-reload
启动前的最后准备
编辑elasticsearch的配置文件:
[root@cs tmp]# cp /etc/elasticsearch/elasticsearch.yml /etc/elasticsearch/elasticsearch.yml.bak
[root@cs tmp]# > /etc/elasticsearch/elasticsearch.yml
[root@cs tmp]# vim /etc/elasticsearch/elasticsearch.yml
cluster.name: my_cluster
node.name: node-1
node.master: true
node.data: true
path.data: /data/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
network.host: 10.0.0.201,127.0.0.1
http.port: 9200
discovery.zen.ping.unicast.hosts: ["10.0.0.201", "10.0.0.202", "10.0.0.203"]
http.cors.enabled: true
http.cors.allow-origin: "*"
# discovery.zen.minimum_master_nodes: 2
启动你的es服务,然后稍等下查看集群状态:
[root@cs tmp]# systemctl restart elasticsearch
[root@cs tmp]# systemctl status elasticsearch
[root@cs tmp]# curl http://10.0.0.201:9200
{
"name" : "node-1",
"cluster_name" : "my_cluster",
"cluster_uuid" : "sPQePmgpSi6c9AQkpWm6oA",
"version" : {
"number" : "6.8.15",
"build_flavor" : "default",
"build_type" : "rpm",
"build_hash" : "c9a8c60",
"build_date" : "2021-03-18T06:33:32.588487Z",
"build_snapshot" : false,
"lucene_version" : "7.7.3",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
[root@cs tmp]# curl http://10.0.0.201:9200/_cat/nodes
10.0.0.201 14 96 28 0.41 0.11 0.06 mdi * node-1\
OK,节点1配置好了,此时,可以浏览器通过elasticsearch-head插件访问看看了
node-2
安装Java环境
[root@cs tmp]# pwd
/tmp
[root@cs tmp]# yum install java-1.8.0-openjdk.x86_64 -y
[root@cs tmp]# java -version
openjdk version "1.8.0_292"
OpenJDK Runtime Environment (build 1.8.0_292-b10)
OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)
安装elasticsearch
[root@cs tmp]# wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.8.15.rpm
[root@cs tmp]# rpm -ivh elasticsearch-6.8.15.rpm
[root@cs tmp]# systemctl daemon-reload
[root@cs tmp]# rm -rf elasticsearch-6.8.15.rpm
注意,elasticsearch服务的运行需要以非root权限运行,但rpm安装时,默认帮我们创建了一个elasticsearch用户,所以,接下来,这里,我手动创建一个数据文件目录,然后给相关目录进行授权:
mkdir -p /data/elasticsearch
chown -R elasticsearch:elasticsearch /data/elasticsearch/
chmod -R g+s /data/elasticsearch/
chown -R elasticsearch:elasticsearch /etc/elasticsearch/
chown -R elasticsearch:elasticsearch /etc/init.d/elasticsearch
chown -R elasticsearch:elasticsearch /etc/sysconfig/elasticsearch
chown -R elasticsearch:elasticsearch /var/log/elasticsearch/
chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/
chown -R elasticsearch:elasticsearch /usr/lib/sysctl.d/elasticsearch.conf
chown -R elasticsearch:elasticsearch /usr/lib/systemd/system/elasticsearch.service
必要的配置
为了后续能正常启动集群,需要提前对系统参数和内核参数做些配置。
修改系统参数:
[root@cs tmp]# vim /etc/security/limits.conf
# 可打开的文件句柄最大数
* soft nofile 65535
* hard nofile 65535
# 单个用户可用的最大进程数
* soft nproc 4096
* hard nproc 4096
# 可打开的文件描述符的最大数,unlimited:无限制
* soft memlock unlimited
* hard memlock unlimited
修改内核参数:
[root@cs tmp]# vim /etc/sysctl.conf
# JAM能开启的最大线程数
vm.max_map_count = 262144
[root@cs tmp]# sysctl -p # 使修改的内核参数生效
vm.max_map_count = 262144
为了避免内存锁定失败,还需要:
[root@cs tmp]# sudo systemctl edit elasticsearch
[Service]
LimitMEMLOCK=infinity
[root@cs tmp]# sudo systemctl daemon-reload
启动前的最后准备
编辑elasticsearch的配置文件:
[root@cs tmp]# cp /etc/elasticsearch/elasticsearch.yml /etc/elasticsearch/elasticsearch.yml.bak
[root@cs tmp]# > /etc/elasticsearch/elasticsearch.yml
[root@cs tmp]# vim /etc/elasticsearch/elasticsearch.yml
cluster.name: my_cluster
node.name: node-2
node.master: true
node.data: true
path.data: /data/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
network.host: 10.0.0.202,127.0.0.1
http.port: 9200
discovery.zen.ping.unicast.hosts: ["10.0.0.201", "10.0.0.202", "10.0.0.203"]
http.cors.enabled: true
http.cors.allow-origin: "*"
# discovery.zen.minimum_master_nodes: 2
启动你的es服务,然后稍等下查看集群状态:
[root@cs tmp]# systemctl restart elasticsearch
[root@cs tmp]# systemctl status elasticsearch
[root@cs tmp]# curl http://10.0.0.202:9200
{
"name" : "node-2",
"cluster_name" : "my_cluster",
"cluster_uuid" : "sPQePmgpSi6c9AQkpWm6oA",
"version" : {
"number" : "6.8.15",
"build_flavor" : "default",
"build_type" : "rpm",
"build_hash" : "c9a8c60",
"build_date" : "2021-03-18T06:33:32.588487Z",
"build_snapshot" : false,
"lucene_version" : "7.7.3",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
[root@cs tmp]# curl http://10.0.0.202:9200/_cat/nodes
10.0.0.201 20 96 0 0.00 0.03 0.05 mdi * node-1
10.0.0.202 18 96 0 0.44 0.21 0.11 mdi - node-2
节点2配置好了,此时,可以浏览器通过elasticsearch-head插件访问看看了,由于节点1和节点2都属于一个集群,所以,访问任意一个具有选举权的节点,都能返回集群信息:
node-3
安装Java环境
[root@cs tmp]# pwd
/tmp
[root@cs tmp]# yum install java-1.8.0-openjdk.x86_64 -y
[root@cs tmp]# java -version
openjdk version "1.8.0_292"
OpenJDK Runtime Environment (build 1.8.0_292-b10)
OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)
安装elasticsearch
[root@cs tmp]# wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.8.15.rpm
[root@cs tmp]# rpm -ivh elasticsearch-6.8.15.rpm
[root@cs tmp]# systemctl daemon-reload
[root@cs tmp]# rm -rf elasticsearch-6.8.15.rpm
注意,elasticsearch服务的运行需要以非root权限运行,但rpm安装时,默认帮我们创建了一个elasticsearch用户,所以,接下来,这里,我手动创建一个数据文件目录,然后给相关目录进行授权:
mkdir -p /data/elasticsearch
chown -R elasticsearch:elasticsearch /data/elasticsearch/
chmod -R g+s /data/elasticsearch/
chown -R elasticsearch:elasticsearch /etc/elasticsearch/
chown -R elasticsearch:elasticsearch /etc/init.d/elasticsearch
chown -R elasticsearch:elasticsearch /etc/sysconfig/elasticsearch
chown -R elasticsearch:elasticsearch /var/log/elasticsearch/
chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/
chown -R elasticsearch:elasticsearch /usr/lib/sysctl.d/elasticsearch.conf
chown -R elasticsearch:elasticsearch /usr/lib/systemd/system/elasticsearch.service
必要的配置
为了后续能正常启动集群,需要提前对系统参数和内核参数做些配置。
修改系统参数:
[root@cs tmp]# vim /etc/security/limits.conf
# 可打开的文件句柄最大数
* soft nofile 65535
* hard nofile 65535
# 单个用户可用的最大进程数
* soft nproc 4096
* hard nproc 4096
# 可打开的文件描述符的最大数,unlimited:无限制
* soft memlock unlimited
* hard memlock unlimited
修改内核参数:
[root@cs tmp]# vim /etc/sysctl.conf
# JAM能开启的最大线程数
vm.max_map_count = 262144
[root@cs tmp]# sysctl -p # 使修改的内核参数生效
vm.max_map_count = 262144
为了避免内存锁定失败,还需要:
[root@cs tmp]# sudo systemctl edit elasticsearch
[Service]
LimitMEMLOCK=infinity
[root@cs tmp]# sudo systemctl daemon-reload
启动前的最后准备
编辑elasticsearch的配置文件:
[root@cs tmp]# cp /etc/elasticsearch/elasticsearch.yml /etc/elasticsearch/elasticsearch.yml.bak
[root@cs tmp]# > /etc/elasticsearch/elasticsearch.yml
[root@cs tmp]# vim /etc/elasticsearch/elasticsearch.yml
cluster.name: my_cluster
node.name: node-3
node.master: true
node.data: true
path.data: /data/elasticsearch
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: true
network.host: 10.0.0.203,127.0.0.1
http.port: 9200
discovery.zen.ping.unicast.hosts: ["10.0.0.201", "10.0.0.202", "10.0.0.203"]
http.cors.enabled: true
http.cors.allow-origin: "*"
# discovery.zen.minimum_master_nodes: 2
启动你的es服务,然后稍等下查看集群状态:
[root@cs tmp]# systemctl restart elasticsearch
[root@cs tmp]# systemctl status elasticsearch
[root@cs tmp]# curl http://10.0.0.203:9200
{
"name" : "node-3",
"cluster_name" : "my_cluster",
"cluster_uuid" : "sPQePmgpSi6c9AQkpWm6oA",
"version" : {
"number" : "6.8.15",
"build_flavor" : "default",
"build_type" : "rpm",
"build_hash" : "c9a8c60",
"build_date" : "2021-03-18T06:33:32.588487Z",
"build_snapshot" : false,
"lucene_version" : "7.7.3",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
[root@cs tmp]# curl http://10.0.0.203:9200/_cat/nodes
10.0.0.201 17 96 0 0.02 0.02 0.05 mdi * node-1
10.0.0.203 18 96 20 0.44 0.19 0.09 mdi - node-3
10.0.0.202 21 96 0 0.00 0.04 0.06 mdi - node-2
节点3配置好了,此时,可以浏览器通过elasticsearch-head插件访问看看了
注意事项
r" : “default”,
“build_type” : “rpm”,
“build_hash” : “c9a8c60”,
“build_date” : “2021-03-18T06:33:32.588487Z”,
“build_snapshot” : false,
“lucene_version” : “7.7.3”,
“minimum_wire_compatibility_version” : “5.6.0”,
“minimum_index_compatibility_version” : “5.0.0”
},
“tagline” : “You Know, for Search”
}
[root@cs tmp]# curl http://10.0.0.203:9200/_cat/nodes
10.0.0.201 17 96 0 0.02 0.02 0.05 mdi * node-1
10.0.0.203 18 96 20 0.44 0.19 0.09 mdi - node-3
10.0.0.202 21 96 0 0.00 0.04 0.06 mdi - node-2
节点3配置好了,此时,可以浏览器通过elasticsearch-head插件访问看看了
## 注意事项
当开始配置每个节点时,`discovery.zen.minimum_master_nodes: 2`这个参数请注释掉,因为加了这个参数后,在启动当前节点时,它会一直ping其他具有选举权的节点,然后进行选举出主节点。但如果其他节点还没启动。它就一直ping......所以,还是先注释掉它吧。等你集群跑着都没问题,再开启它。