赞
踩
1、集群原理
https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html
https://www.elastic.co/guide/cn/elasticsearch/guide/current/distributed-cluster.html
elasticsearch是天然支持集群的,他不需要依赖其他的服务发现和注册的主键,如zookeeper这些,因此他内置了一个名字叫ZenDiscovery的模块,是elasticsearch自己实现的一套用于节点发现和选主等功能的组件,所以elasticsearch做起来非常简单,不需要太多额外的配置和安装额外的第三方组件。
1)、单节点
2)、集群健康
Elasticsearch 的集群监控信息中包含了许多的统计数据,其中最为重要的一项就是 集群健康 , 它在 status 字段中展示为 green 、 yellow 或者 red 。
GET /_cluster/health
status 字段指示着当前集群在总体上是否工作正常。它的三种颜色含义如下:
green 所有的主分片和副本分片都正常运行。
yellow 所有的主分片都正常运行,但不是所有的副本分片都正常运行。
red 有主分片没能正常运行。
3)、分片
- PUT /blogs
- {
- "settings" : {
- "number_of_shards" : 3,
- "number_of_replicas" : 1
- }
- }
如果我们现在查看集群健康,我们将看到如下内容:
- {
- "cluster_name": "elasticsearch",
- "status": "yellow",
- "timed_out": false,
- "number_of_nodes": 1,
- "number_of_data_nodes": 1,
- "active_primary_shards": 3,
- "active_shards": 3,
- "relocating_shards": 0,
- "initializing_shards": 0,
- "unassigned_shards": 3,
- "delayed_unassigned_shards": 0,
- "number_of_pending_tasks": 0,
- "number_of_in_flight_fetch": 0,
- "task_max_waiting_in_queue_millis": 0,
- "active_shards_percent_as_number": 50
- }
集群 status 值为 yellow 。
unassigned_shards 没有被分配到任何节点的副本数。
此时集群的健康状况为 yellow 则表示全部 主 分片都正常运行(集群可以正常服务所有请求),但是 副本 分片没有全部处在正常状态。 实际上,所有3个副本分片都是 unassigned —— 它们都没有被分配到任何节点。 在同一个节点上既保存原始数据又保存副本是没有意义的,因为一旦失去了那个节点,我们也将丢失该节点上的所有副本数据。
当前我们的集群是正常运行的,但是在硬件故障时有丢失数据的风险。
4)、新增节点
当你在同一台机器上启动了第二个节点时,只要它和第一个节点有同样的 cluster.name 配置,它就会自动发现集群并加入到其中。 但是在不同机器上启动节点的时候,为了加入到同一集群,你需要配置一个可连接到的单播主机列表。 详细信息请查看最好使用单播代替组播
当第二个节点加入到集群后,3个 副本分片 将会分配到这个节点上——每个主分片对应一个副本分片。 这意味着当集群内任何一个节点出现问题时,我们的数据都完好无损。
所有新近被索引的文档都将会保存在主分片上,然后被并行的复制到对应的副本分片上。这就保证了我们既可以从主分片又可以从副本分片上获得文档。
cluster-health 现在展示的状态为 green ,这表示所有6个分片(包括3个主分片和3个副本分片)都在正常运行。
- {
- "cluster_name": "elasticsearch",
- "status": "green",
- "timed_out": false,
- "number_of_nodes": 2,
- "number_of_data_nodes": 2,
- "active_primary_shards": 3,
- "active_shards": 6,
- "relocating_shards": 0,
- "initializing_shards": 0,
- "unassigned_shards": 0,
- "delayed_unassigned_shards": 0,
- "number_of_pending_tasks": 0,
- "number_of_in_flight_fetch": 0,
- "task_max_waiting_in_queue_millis": 0,
- "active_shards_percent_as_number": 100
- }
集群 status 值为 green 。
我们的集群现在不仅仅是正常运行的,并且还处于 始终可用 的状态。
5)、水平扩容-启动第三个节点
Node 1 和 Node 2 上各有一个分片被迁移到了新的 Node 3 节点,现在每个节点上都拥有2个分片,而不是之前的3个。 这表示每个节点的硬件资源(CPU, RAM, I/O)将被更少的分片所共享,每个分片的性能将会得到提升。
分片是一个功能完整的搜索引擎,它拥有使用一个节点上的所有资源的能力。 我们这个拥有6个分片(3个主分片和3个副本分片)的索引可以最大扩容到6个节点,每个节点上存在一个分片,并且每个分片拥有所在节点的全部资源。
但是如果我们想要扩容超过6个节点怎么办呢?
主分片的数目在索引创建时就已经确定了下来。实际上,这个数目定义了这个索引能够 存储 的最大数据量。(实际大小取决于你的数据、硬件和使用场景。) 但是,读操作——搜索和返回数据——可以同时被主分片 或 副本分片所处理,所以当你拥有越多的副本分片时,也将拥有越高的吞吐量。
在运行中的集群上是可以动态调整副本分片数目的,我们可以按需伸缩集群。让我们把副本数从默认的 1 增加到 2 :
- PUT /blogs/_settings
- {
- "number_of_replicas" : 2
- }
如Figure 5, “将参数 number_of_replicas 调大到 2”所示, blogs 索引现在拥有9个分片:3个主分片和6个副本分片。 这意味着我们可以将集群扩容到9个节点,每个节点上一个分片。相比原来3个节点时,集群搜索性能可以提升 3 倍。
当然,如果只是在相同节点数目的集群上增加更多的副本分片并不能提高性能,因为每个分片从节点上获得的资源会变少。 你需要增加更多的硬件资源来提升吞吐量。
但是更多的副本分片数提高了数据冗余量:按照上面的节点配置,我们可以在失去2个节点的情况下不丢失任何数据。
6)、应对故障
如果我们关闭第一个节点,这时集群的状态为Figure 6, “关闭了一个节点后的集群”
我们关闭的节点是一个主节点。而集群必须拥有一个主节点来保证正常工作,所以发生的第一件事情就是选举一个新的主节点: Node 2 。
在我们关闭 Node 1 的同时也失去了主分片 1 和 2 ,并且在缺失主分片的时候索引也不能正常工作。 如果此时来检查集群的状况,我们看到的状态将会为 red :不是所有主分片都在正常工作。
幸运的是,在其它节点上存在着这两个主分片的完整副本, 所以新的主节点立即将这些分片在 Node 2 和 Node 3 上对应的副本分片提升为主分片, 此时集群的状态将会为 yellow 。 这个提升主分片的过程是瞬间发生的,如同按下一个开关一般。
为什么我们集群状态是 yellow 而不是 green 呢? 虽然我们拥有所有的三个主分片,但是同时设置了每个主分片需要对应2份副本分片,而此时只存在一份副本分片。 所以集群不能为 green 的状态,不过我们不必过于担心:如果我们同样关闭了 Node 2 ,我们的程序 依然 可以保持在不丢任何数据的情况下运行,因为 Node 3 为每一个分片都保留着一份副本。
如果我们重新启动 Node 1 ,集群可以将缺失的副本分片再次进行分配,那么集群的状态也将如Figure 5, “将参数 number_of_replicas 调大到 2”所示。 如果 Node 1 依然拥有着之前的分片,它将尝试去重用它们,同时仅从主分片复制发生了修改的数据文件。
7)、问题与解决
① 主节点
主节点负责创建索引、删除索引、分配分片、追踪集群中的节点状态等工作。 Elasticsearch
中的主节点的工作量相对较轻,用户的请求可以发往集群中任何一个节点,由该节点负责分
发和返回结果,而不需要经过主节点转发。而主节点是由候选主节点通过 Zen Discovery机
制选举出来的,所以要想成为主节点,首先要先成为候选主节点。
② 候选主节点
在 elasticsearch集群初始化或者主节点宕机的情况下由候选主节点中选举其中一个作为主
节点。指定候选主节点的配置为: node.master:true
当主节点负载压力过大,或者集中环境中的网络问题,导致其他节点与主节点通讯的时候,
主节点没来的及响应,这样的话,某些节点就认为主节点宕机,重新选择新的主节点,这样
的话整个集群的工作就有问题了,比如我们集群中有10个节点,其中7个候选主节点、1
个候选主节点成为了主节点,这种情况是正常的情况。但是如果现在出现了我们上面所说的
主节点响应不及时,导致其他某些节点认为主节点宕机而重选主节点,那就有问题了,这剩
下的6个候选主节点可能有3个候选主节点去重选主节点最后集群中就出现了两个主节点
的情况,这种情况官方成为"脑裂现象";
集群中不同的节点对于 master的选择出现了分歧,出现了多个 master竞争,导致主分片
和副本的识别也发生了分歧,对一些分歧中的分片标识为了坏片。
③ 数据节点
数据节点负责数据的存储和相关具体操作,比如CRUD、搜索、聚合。所以,数据节点对机
器配置要求比较高,首先需要有足够的磁盘空间来存储数据,其次数据操作对系统CPU、
Memory和的IO的性能消耗都很大。通常随着集群的扩大,需要增加更多的数据节点来提高
可用性。指定数据节点的配置: node.data:true
elasticsearch是允许一个节点既做候选主节点也做数据节点的,但是数据节点的负载较重,
所以需要考虑将二者分离开,设置专用的候选主节点和数据节点,避免因数据节点负载重导
致主节点不响应。
④ 客户端节点
客户端节点就是既不做候选主节点也不做数据节点的节点,只负责请求的分发、汇总等等,
但是这样的工作,其实任何一个节点都可以完成,因为在 elasticsearch中一个集群内的节点
都可以执行任何请求,其会负责将请求转发给对应的节点进行处理。所以单独增加这样的节
点更多是为了负载均衡。指定该节点的配置为:
node.master:false
node.data:false
⑤ 脑裂“问题”解决方案
和搜索的工作的,压力会很大。所以如果该节点同时作为候选主节点和数据节点,
那么一旦选上它作为主节点了,这时主节点的工作压力将会非常大,出现脑裂现象
的概率就增加了。
点就认为主节点宕机了,那我们可以把该时间设置的长一点,该配置是:
discovery.zen.ping_timeout:5
为了形成一个集群,有主节点资格并互相连接的节点的最小数目
一个有10节点的集群,且每个节点都有成为主节点的资格,discovery.zen. minimum_master参数设置为6
正常情况下,10个节点,互相连接,大于6,就可以形成一个集群。
若某个时刻,其中有3个节点断开连接。剩下7个节点,大于6,继续运行之前的集群。而断开的3个节点,小于6,不能形成一个集群。
该参数就是为了防止"脑裂"的产生。
建议设置为(候选主节点数/2)+1
8)、集群结构
以三台物理机为例。在这三台物理机上,搭建了6个ES的节点,三个data节点,三个 master节点(每台物理机分别起了一个data和一个 master),3个 master节点,目的是达到(n/2)+1等于2的要求,这样挂掉一台 master后(不考虑data),n等于2,满足参数,其他两个 master节点都认为 master挂掉之后开始重新选举,
master节点上
node.master = true
node.data = false
discovery.zen.minimum_master_nodes = 2
data节点上
node.master = false
node.data = true
2、集群搭建
所有操作之前先运行: sysctl -w vm.max_map_count=262144
我们只是测试,所以临时修改。永久修改使用下面
- #防止JVM报错
- echo vm.max_map_count=262144 >>/etc/sysctl.conf
- sysctl -p
0)、准备docker网络
Docker创建容器时默认采用 bridge网络,自行分配ip,不允许自己指定。
在实际部署中,我们需要指定容器p,不允许其自行分配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 网络桥接
- [root@elasticsearch elasticsearch]# docker network ls
- NETWORK ID NAME DRIVER SCOPE
- f40bd7a7d990 bridge bridge local
- e9f72aac1c14 host host local
- 0d7bb07fbe1e mynet bridge local
- 6accb88d4b4b none null local
查看网络信息
docker network inspect mynet
以后使用 --network=mynet --ip 172.18.12.x 指定ip
1)、 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 #该节点有机会成为master节点
- node.data: false #该节点可以存储数据
- network.host: 0.0.0.0
- http.host: 0.0.0.0 #所有http均可访问
- http.port: 920${port}
- transport.tcp.port: 930${port}
- #discovery.zen.minimum_master_nodes:2 #设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点 。官方推荐(N/2)+1 解决脑裂问题,高版本es无需设置,已经有方法解决
- discovery.zen.ping_timeout: 10s #设置集群自动发现其他节点时ping连接的超时时间
- discovery.seed_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的新增配置
- 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}/data:/usr/share/elasticsearch/data \
- -v /mydata/elasticsearch/master-${port}/plugins:/usr/share/elasticsearch/plugins \
- -d elasticsearch:7.4.2
- done
- #停止所有elsaticsearch容器
- docker stop $(docker ps -a|grep elasticsearch-node-* | awk '{print $1}')
- #删除所有elsaticsearch容器
- docker rm $(docker ps -a|grep elasticsearch-node-* | awk '{print $1}')
2)、 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 #该节点有机会成为master节点
- node.data: true #该节点可以存储数据
- network.host: 0.0.0.0
- #network.publish_host: 192.168.56.10 #互相通信ip,要设置为本机可被外界访问的ip,否则无法通信
- http.host: 0.0.0.0 #所有http均可访问
- http.port: 920${port}
- transport.tcp.port: 930${port}
- #discovery.zen.minimum_master_nodes: 2 #设置这个参数来保证集群中的节点可以知道其它N个有master资格的节点 。官方推荐(N/2)+1 解决脑裂问题,高版本es无需设置,已经有方法解决
- discovery.zen.ping_timeout: 10s #设置集群自动发现其他节点时ping连接的超时时间
- discovery.seed_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的新增配置
- 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}/data:/usr/share/elasticsearch/data \
- -v /mydata/elasticsearch/node-${port}/plugins:/usr/share/elasticsearch/plugins \
- -d elasticsearch:7.4.2
- done
http://192.168.54.130:9201/
http://192.168.54.130:9202/
http://192.168.54.130:9203/
http://192.168.54.130:9206/ 均能够访问
集群常用 查询命令 https://note.youdao.com/s/4bJvKGk4
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。