ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

docker中部署ES集群的详细操作步骤(6个节点)

2022-01-26 09:31:15  阅读:497  来源: 互联网

标签:node master es 分片 集群 docker 操作步骤 节点 ES


ElasticSearch集群

1.集群原理
ElasticSearch是天生支持集群的,他不需要依赖其他的服务发现和注册的组件,如zookeeper这些,因为他内置了一个名字叫ZenDiscovery的模块,是ElasticSearch自己实现的一套用于节点发现和选主等功能的组件,所以ElasticSearch做起集群来非常简单,不需要太多额外的配置和安装额外的第三方组件。

1、单节点
A.一个运行中的ElasticSearch实例称为一个节点,而集群是由一个或者多个拥有相同的cluster.name配置的节点组成,他们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。
B.当一个节点被选举成为主节点时,他将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量的增加他也不会成为瓶颈。任何节点都可以成为主节点。我们的示例集群就只有一个节点,所以他同时也成为了主节点。
C.作为用户,我们可以将请求发送到集群中的任何节点,包括主节点。每个节点都知道任意文档所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。无论我们将请求发送到哪个节点,他都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回给客户端。ElasticSearch对这一切的管理都是透明的。

2、集群健康
ElasticSearch的集群监控信息中包含了许多的统计数据,其中最为重要的一项就是集群健康,他在status字段中展示为green、yellow或者red。
GET /_cluster/health
status字段指示着当前集群在总体上是否工作正常。他的三种颜色含义如下:
green:所有的主分片和副本分片都正常运行。
yellow:所有的主分片都正常运行,但不是所有的副本分片都正常运行。
red:有主分片没能正常运行。

3、分片
A.一个分片是一个底层的工作单元,他仅保存了全部数据中的一部分。我们的文档被存储和索引到分片内,但是应用程序是直接与索引而不是与分片进行交互。分片就认为是一个数据区
B.一个分片可以是主分片或者副本分片。索引内任意一个文档都归属于一个主分片,所以主分片的数目决定着索引能够保存的最大数据量。
C.在索引建立的时候就已经确定了主分片数,但是副本分片数可以随时修改。
D.我们在包含一个空节点的集群内创建名为block的索引。索引在默认情况下会被分配5个主分片,但是为了演示目的,我们将分配3个主分片和一份副本(每个主分片拥有一个副本分片):
PUT /block{
“settings”:{
“number_of_shards”:3,
“number_of_replicas”:1
}
}
拥有一个索引的单节点集群
此时集群的健康状况为yellow,则表示全部主分片都正常运行(集群可以正常服务所有请求),但是副本分片没有全部处在正常状态。实际上,所有3个副本分片都是unassigned–他们都没有被分配到任何节点。在同一个节点上既保存原始数据又保存副本是没有意义的,因为一旦失去了那个节点,我们也将丢失该节点上的所有副本数据。
当前我们的集群是正常运行的,但是在硬件故障时有丢失数据的风险。

4、新增节点
当你在同一台机器上启动了第二个节点时,只要它和第一个节点有同样的cluster.name配置,它就会自动发现集群并加入到其中。但是在不同机器上启动节点的时候,为了加入到同一集群,你需要配置一个可连接到的单播主机列表。而且最好使用单播代替组播。

拥有2个节点的集群-所有主分片和副本分片都已被分配
此时,cluster-health现在展示的状态为green,这表示所有6个分片(包括3个主分片和3个副本分片)都在正常运行。我们的集群现在不仅仅时正常运行的,并且还处于始终可用的状态。

5、水平扩容-启动第三个节点
拥有三个节点的集群-为了分散负载而对分片进行重新分配

node1和node2上各有一个分片被迁移到了新的node3节点,现在每个节点上都拥有2个分片,而不是之前的3个。这表示每个节点的硬件资源(CPU,RAM,I/O)将被更少的分片所共享,每个分片的性能将会得到提升。

在运行的集群上是可以动态调整副本分片数目的,我们可以按需伸缩集群。我们把副本数从默认的1增加到2
PUT /block/_settings{
“number_of_replicas”:2
}
block索引现在拥有9个分片:3个主分片和6个副本分片。这意味着我们可以将集群扩容到9个节点,每个节点上一个分片。相比原来3个节点时,集群搜索性能可以提升3倍。

6、应对故障
关闭一个节点后的集群
A.我们关闭的节点是一个主节点。而集群必须拥有一个主节点来保证正常工作,所以发生的第一个事情就是选举一个新的主节点:node2.
B.在我们关闭了node1的同时也失去了主分片1和2,并且在缺失主分片的时候索引也不能正常工作。如果此时来检查集群的状况,我们看到的状态将会为red:不是所有主分片都在正常工作。
C.幸运的是,在其他节点上存在着这两个主分片的完整副本,所以新的主节点立即将这些分片在node2和node3上对应的副本分片提升为主分片,此时集群的状态将会为yellow,这个提示主分片的过程是瞬间发生的,如果按下一个开关一般。
D.为什么我们集群状态时yellow而不是green呢?虽然我们拥有所有的三个主分片,但是同时设置了每个主分片需要对应2份副本分片,而此时只存在一份副本分片。所以集群不能以green的状态,不过我们不必过于担心,如果我们同样关闭了node2,我们的程序依然可以保持在不丢任何数据的情况下运行,因为node3为每一个分片都保留着一份副本。
E.如果我们重新启动node1,集群可以将缺失的副本分片再次进行分配。如果node1依然拥有着之前的分配,它将尝试去重用它们,同时仅从主分片复制发生了修改的数据文件。

7、问题与解决

1、主节点
主节点负责创建索引、删除索引、分配分片、追踪集群中的节点状态等工作。ElasticSearch中的主节点的工作量相对较轻,用户的请求可以发往集群中任何一个节点,由该节点负责分发和返回结果,而不需要经过主节点转发。而主节点是由候选主节点通过ZenDiscovery机制选举出来的,所以要想成为主节点,首先要先成为候选主节点。

2、候选主节点
在ElasticSearch集群初始化或者主节点宕机的情况下,由候选主节点中选举其中一个作为主节点。指定候选主节点的配置为:node.master:true。
当主节点负载压力过大,或者集群环境中的网络问题,导致其他节点与主节点通讯的时候,主节点没来及响应,这样的话,某些节点就认为主节点宕机,重新选择新的主节点,这样的话整个集群的工作就有问题了,比如我们集群中有10个节点,其中7个候选主节点,1个候选主节点成为了主节点,这种情况是正常的情况。但是如果现在出现了我们上面所说的主节点响应不及时,导致其他某些节点认为主节点宕机而重选主节点,那就有问题了,这剩下的6个候选主节点可能有3个候选主节点去重选主节点,最后集群中就出现了两个主节点的情况,这种情况官方成为“脑裂现象”。
集群中不同的节点对于master的选择出现了分歧,出现了多个master竞争,导致主分片和副本的识别也发生了分歧,把一些分歧中的分片标识为了坏片。

3、数据节点
数据节点负责数据的存储和相关具体操作,比如CRUD、搜索、聚合。所以,数据节点对机器配置要求比较高,首先需要有足够的磁盘空间来存储数据,其次数据操作对系统CPU、Memory和IO的性能消耗都很大。通常随着集群的扩大,需要增加更多的数据节点来提高可用性。指定数据节点的配置:node.data:true。
ElasticSearch是允许一个节点既做候选主节点也做数据节点的,但是数据节点的负载较重,所以需要考虑将二者分离开,设置专用的候选主节点和数据节点,避免因数据节点负责重导致主节点不响应。

4、客户端节点
客户端节点就是既不做候选主节点也不做数据节点的节点,只负责请求的分发、汇总等等,但是这样的工作,其实任何一个节点都可以完成,因为在ElasticSearch中一个集群内的节点都可以执行任何请求,其会负责将请求转发给对应的节点进行处理。所以单独增加这样的节点更多是为了负载均衡。指定该节点的配置为:
node.master:false
node.data:false

5、脑裂问题可能的成因

1.网络问题:集群间的网络延迟导致一些节点访问不到master,认为master挂掉了从而选举出新的master,并对master上的分片和副本标红,分配新的主分片。
2.节点负载:主节点的角色既为master又为data,访问量较大时可能会导致ES停止响应造成大面积延迟,此时其他节点得不到主节点的响应认为主节点挂掉了,会重新选取主节点。
3.内存回收:data节点上的ES进程占用的内存较大,引发JVM的大规模内存回收,造成ES进程失去响应。

脑裂问题解决方案:
角色分离:即master节点与data节点分离,限制角色;数据节点时需要承担存储和搜索的工作的,压力会很大。所以如果该节点同时作为候选主节点和数据节点,那么一旦选上它作为主节点了,这时主节点的工作压力将会非常大,出现脑裂现象的概率就增加了。

减少误判:配置主节点的响应时间,在默认情况下,主节点3秒没有响应,其他节点就认为主节点宕机了,那我们可以把该时间设置得长一点,该配置是:
discovery.zen.ping_timeout:5

选举触发:discovery.zen.minimum_master_nodes:1(默认是1),该属性定义的是为了形成一个集群,有主节点资格并互相连接的节点的最小数目。
一个有10节点的集群,且每个节点都有成为主节点的资格,
discovery.zen.minimum_master_nodes参数设置为6。
正常情况下,10个节点,互相连接,大于6,就可以形成一个集群。
若某个时刻,其中有3个节点断开连接。剩下7个节点,大于6,继续运行之前的集群。而断开的3个节点,小于6,不能形成一个集群。
该参数就是为了防止脑裂的产生
建议设置为(候选主节点数/2)+1。

8、集群结构
以3台物理机为例。在这3台物理机上,搭建了6个ES的节点,3个data节点,3个master节点(每台物理机分别起了一个data和一个master),3个master节点,目的是达到(n/2)+1等于2的要求,这样挂掉1台master后(不考虑data),n等于2,满足参数,其他两个节点都认为master挂掉之后开始重新选举,

master节点上
node.master = true
node.data = true
discovery.zen.minimum_master_nodes =2

在这里插入图片描述

2.集群搭建
所有之前先运行:sysctl -w vm.max_map_count=262144
如果只是测试,可以临时修改。永久修改使用下面的语句
#防止JVM报错
echo vm.max_map_count=262144>> /etc/sysctl.conf sysctl -p

{"type": "deprecation", "timestamp": "2022-01-26T07:58:54,866Z", "level": "WARN", "component": "o.e.d.c.s.Settings", "cluster.name": "my-es", "node.name": "es-master-3", "message": "[discovery.zen.ping.unicast.hosts] setting was deprecated in Elasticsearch and will be removed in a future release! See the breaking changes documentation for the next major version." }
{"type": "deprecation", "timestamp": "2022-01-26T07:58:54,882Z", "level": "WARN", "component": "o.e.d.c.s.Settings", "cluster.name": "my-es", "node.name": "es-master-3", "message": "[discovery.zen.minimum_master_nodes] setting was deprecated in Elasticsearch and will be removed in a future release! See the breaking changes documentation for the next major version." }
{"type": "server", "timestamp": "2022-01-26T07:59:05,217Z", "level": "INFO", "component": "o.e.x.s.a.s.FileRolesStore", "cluster.name": "my-es", "node.name": "es-master-3", "message": "parsed [0] roles from file [/usr/share/elasticsearch/config/roles.yml]" }
{"type": "server", "timestamp": "2022-01-26T07:59:08,561Z", "level": "INFO", "component": "o.e.x.m.p.l.CppLogMessageHandler", "cluster.name": "my-es", "node.name": "es-master-3", "message": "[controller/87] [Main.cc@110] controller (64 bit): Version 7.6.2 (Build e06ef9d86d5332) Copyright (c) 2020 Elasticsearch BV" }
{"type": "server", "timestamp": "2022-01-26T07:59:13,427Z", "level": "DEBUG", "component": "o.e.a.ActionModule", "cluster.name": "my-es", "node.name": "es-master-3", "message": "Using REST wrapper from plugin org.elasticsearch.xpack.security.Security" }
{"type": "server", "timestamp": "2022-01-26T07:59:15,164Z", "level": "INFO", "component": "o.e.d.DiscoveryModule", "cluster.name": "my-es", "node.name": "es-master-3", "message": "using discovery type [zen] and seed hosts providers [settings]" }
{"type": "server", "timestamp": "2022-01-26T07:59:22,616Z", "level": "INFO", "component": "o.e.n.Node", "cluster.name": "my-es", "node.name": "es-master-3", "message": "initialized" }
{"type": "server", "timestamp": "2022-01-26T07:59:22,617Z", "level": "INFO", "component": "o.e.n.Node", "cluster.name": "my-es", "node.name": "es-master-3", "message": "starting ..." }
{"type": "server", "timestamp": "2022-01-26T07:59:24,821Z", "level": "INFO", "component": "o.e.t.TransportService", "cluster.name": "my-es", "node.name": "es-master-3", "message": "publish_address {172.18.12.23:9303}, bound_addresses {[::]:9303}" }
{"type": "server", "timestamp": "2022-01-26T07:59:26,236Z", "level": "INFO", "component": "o.e.b.BootstrapChecks", "cluster.name": "my-es", "node.name": "es-master-3", "message": "bound or publishing to a non-loopback address, enforcing bootstrap checks" }
ERROR: [1] bootstrap checks failed
[1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
ERROR: Elasticsearch did not exit normally - check the logs at /usr/share/elasticsearch/logs/my-es.log
{"type": "server", "timestamp": "2022-01-26T07:59:26,277Z", "level": "INFO", "component": "o.e.n.Node", "cluster.name": "my-es", "node.name": "es-master-3", "message": "stopping ..." }
{"type": "server", "timestamp": "2022-01-26T07:59:26,327Z", "level": "INFO", "component": "o.e.n.Node", "cluster.name": "my-es", "node.name": "es-master-3", "message": "stopped" }
{"type": "server", "timestamp": "2022-01-26T07:59:26,328Z", "level": "INFO", "component": "o.e.n.Node", "cluster.name": "my-es", "node.name": "es-master-3", "message": "closing ..." }
{"type": "server", "timestamp": "2022-01-26T07:59:26,435Z", "level": "INFO", "component": "o.e.n.Node", "cluster.name": "my-es", "node.name": "es-master-3", "message": "closed" }
{"type": "server", "timestamp": "2022-01-26T07:59:26,438Z", "level": "INFO", "component": "o.e.x.m.p.NativeController", "cluster.name": "my-es", "node.name": "es-master-3", "message": "Native controller process has stopped - no new native processes can be started" }

1.准备docker网络
docker创建容器时默认采用bridge网络,自行分配ip,不允许自己指定。
在实际部署中,我们需要指定容器ip,不允许其自行分配ip,尤其时搭建集群时,固定ip是必须的。
我们可以创建自己的bridge网络:mynet,创建容器的时候指定网络为mynet并指定ip即可。
查看网络模式 docker network ls;

创建一个新的bridge网络
docker network create --driver bridge --subnet=172.18.12.0/16 --gateway=172.18.1.1 mynet
查看网络信息

docker network inspect mynet

以后使用 --network=mynet --ip 172.18.12.x 指定ip

2.创建3个master

for port in $(seq 1 3); \
do \
mkdir -p /mydata/elasticsearch/master-${port}/config
mkdir -p /mydata/elasticsearch/master-${port}/data
chmod -R 777 /mydata/elasticsearch/master-${port}
cat <<EOF> /mydata/elasticsearch/master-${port}/config/elasticsearch.yml
cluster.name: my-es
node.name: es-master-${port}
node.master: true 
node.data: false 
network.host: 0.0.0.0
http.host: 0.0.0.0 
http.port: 920${port}
transport.tcp.port: 930${port}
discovery.zen.ping_timeout: 10s
discovery.zen.ping.unicast.hosts: ["172.18.12.21:9301","172.18.12.22:9302","172.18.12.23:9303"]
discovery.zen.minimum_master_nodes: 2
cluster.initial_master_nodes: ["172.18.12.21"]
EOF
docker run --name elasticsearch-node-${port} \
 -p 920${port}:920${port} -p 930${port}:930${port} \
 --network=mynet --ip 172.18.12.2${port} \
 -e ES_JAVA_OPTS="-Xms300m -Xmx300m" \
 -v /mydata/elasticsearch/master-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
 -v /mydata/elasticsearch/master-${port}/plugins:/usr/share/elasticsearch/plugins \
 --privileged=true \
 -d elasticsearch:7.6.2
done

cluster.name: my-es #集群的名称,同一个集群该值必须设置相同
node.name: es-master-${port} #该节点的名字
node.master: true #该节点是否有机会成为master节点
node.data: false #该节点可以存储数据
http.host: 0.0.0.0 #所有http都可以访问
discovery.zen.ping_timeout: 10s #设置集群中自动发现其他节点时ping连接的超时时间
discovery.send_hosts: [“172.18.12.21:9301”,“172.18.12.22:9302”,“172.18.12.23:9303”] #设置集群中的master节点的初始列表,可以通过这些节点来自动发现其他新加入集群的节点,es7的新增配置
cluster.initial_master_nodes: [“172.18.12.21”]#新集群初始时的候选主节点,es7的新增配置

注意:
1.上面的创建shell脚本一定要注意后面是否带空格,如果带空格运行shell脚本会失败,比如EOF后面,当复制粘贴到linux上面的时候,后面不能带空格,不然会创建节点失败。
2.需要注意在elasticsearch.yml配置文件中,每个属性配置的时候前面要多一个空格,比如上面的cluster.name:后面就是加了一个空格,然后再是集群的名称。
3.对于centos7以上的版本,需要在运行docker的时候加上–privileged=true,不然运行shell脚本有可能会报错。

3.创建3个Data node节点

for port in $(seq 4 6); \
do \
mkdir -p /mydata/elasticsearch/node-${port}/config
mkdir -p /mydata/elasticsearch/node-${port}/data
chmod -R 777 /mydata/elasticsearch/node-${port}
cat <<EOF> /mydata/elasticsearch/node-${port}/config/elasticsearch.yml
cluster.name: my-es
node.name: es-node-${port}
node.master: false 
node.data: true 
network.host: 0.0.0.0
http.host: 0.0.0.0 
http.port: 920${port}
transport.tcp.port: 930${port}
discovery.zen.ping_timeout: 10s
discovery.zen.ping.unicast.hosts: ["172.18.12.21:9301","172.18.12.22:9302","172.18.12.23:9303"]
discovery.zen.minimum_master_nodes: 2
cluster.initial_master_nodes: ["172.18.12.21"]
EOF
docker run --name elasticsearch-node-${port} \
 -p 920${port}:920${port} -p 930${port}:930${port} \
 --network=mynet --ip 172.18.12.2${port} \
 -e ES_JAVA_OPTS="-Xms300m -Xmx300m" \
 -v /mydata/elasticsearch/node-${port}/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
 -v /mydata/elasticsearch/node-${port}/plugins:/usr/share/elasticsearch/plugins \
 --privileged=true \
 -d elasticsearch:7.6.2
done

运行之后,通过docker ps检查每个节点是否正常启动,节点信息如下:

[root@centos3 etc]# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                                                                NAMES
780bc49a4a44        elasticsearch:7.6.2   "/usr/local/bin/do..."   7 minutes ago       Up 7 minutes        9200/tcp, 0.0.0.0:9206->9206/tcp, 9300/tcp, 0.0.0.0:9306->9306/tcp   elasticsearch-node-6
d05b846789be        elasticsearch:7.6.2   "/usr/local/bin/do..."   7 minutes ago       Up 7 minutes        9200/tcp, 0.0.0.0:9205->9205/tcp, 9300/tcp, 0.0.0.0:9305->9305/tcp   elasticsearch-node-5
852b40cd39a8        elasticsearch:7.6.2   "/usr/local/bin/do..."   8 minutes ago       Up 7 minutes        9200/tcp, 0.0.0.0:9204->9204/tcp, 9300/tcp, 0.0.0.0:9304->9304/tcp   elasticsearch-node-4
de72572353ee        elasticsearch:7.6.2   "/usr/local/bin/do..."   14 minutes ago      Up 14 minutes       9200/tcp, 0.0.0.0:9203->9203/tcp, 9300/tcp, 0.0.0.0:9303->9303/tcp   elasticsearch-node-3
61271dd17d42        elasticsearch:7.6.2   "/usr/local/bin/do..."   14 minutes ago      Up 14 minutes       9200/tcp, 0.0.0.0:9202->9202/tcp, 9300/tcp, 0.0.0.0:9302->9302/tcp   elasticsearch-node-2
eb898f25b615        elasticsearch:7.6.2   "/usr/local/bin/do..."   14 minutes ago      Up 14 minutes       9200/tcp, 0.0.0.0:9201->9201/tcp, 9300/tcp, 0.0.0.0:9301->9301/tcp   elasticsearch-node-1
[root@centos3 etc]# 

在网页中输入http://192.168.0.106:9206/_cat/nodes,查看集群状态,截图如下:
在这里插入图片描述如果我们手动的停掉一个节点,则该节点将自动停止,会从其他的备份主节点中选举一个作为主节点信息,例如:如果将es-master-1停掉,则会从es-master-2和es-master-3中选举一个作为主节点,当es-master-1恢复的时候,es-master-1就作为备份主节点参与到集群中来。

调试es集群的命令:

批量停止es集群容器:
docker stop $(docker ps -a | grep elasticsearch-node-* | awk ‘{ print $1}’)

批量删除es集群容器:
docker rm $(docker ps -a | grep elasticsearch-node-* | awk ‘{ print $1}’)

标签:node,master,es,分片,集群,docker,操作步骤,节点,ES
来源: https://blog.csdn.net/miachen520/article/details/122695524

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有