1.写在前面
前面的博客,我已经简单的介绍了elasticsearch的安装,以及一些的工具的安装,只是简简单单入了一个门,但是elasticsearch一般都离不来集群,我们知道它是一个分布式,高性能、高可用、可伸缩的搜索和分析系统,所以今天的博客打算介绍一下它的集群的方式,但是由于我的电脑的配置有限,所以这儿就简简单单在一台机器上启动三个elasticsearch,然后搭建集群,当然多台机器搭建集群的方式比较简单,我在这儿就不介绍了。
2.搭建集群的方式
我们这儿主要是介绍两种方式,一种是通过多配置的文件的方式启动多台elasticsearch,一种是通过单配置的文件的方式来启动多台elasticsearch。
2.1.单配置文件的方式启动多台elasticsearch
在介绍这种的情况,我们先来了解下对应的配置文件中的配置的项的意思,具体的如下:
#集群的名称
cluster.name: king
#节点的名称
node.name: node‐1
#是否是主节点
node.master: true
node.data: true
#地址
network.host: 0.0.0.0
#端口
http.port: 9200
#参数设置一系列符合主节点条件的节点的主机名或 IP 地址来引导启动集群。
cluster.initial_master_nodes: ["node‐1"]
# 设置新节点被启动时能够发现的主节点列表(主要用于不同网段机器连接)
discovery.zen.ping.unicast.hosts: ["192.168.181.6","192.168.181.7","192.168.181.8"]
# 该参数就是为了防止”脑裂”的产生。定义的是为了形成一个集群,有主节点资格并互相连接的节点的最小数目。类似过半机制
discovery.zen.minimum_master_nodes: 2
# 解决跨域问题配置
http.cors.enabled: true
http.cors.allow‐origin: "*"
既然我们已经了解上面的配置的项,那么我们就让我们来搭起集群的环境吧!先来修改对应的配置文件,具体的如下:
设置好对应的项,然后保存,由于elasticsearch的启动的时候的会有log文件还有data数据,所以这个时候,我们需要创建这个文件夹,用来存储这些的文件,创建/ES/node1/data``/ES/node1/logs``/ES/node2/data``/ES/node2/logs``/ES/node3/data``/ES/node3/logs 这几个文件夹,具体的如下:
这个时候就让我们来启动对应的三台elasticsearch吧,启动的命令如下:
./elasticsearch -d -E node.name=node-1 -E http.port=9200 -E transport.port=9300 -E path.data=/ES/node1/data -E path.logs=/ES/node1/logs
./elasticsearch -d -E node.name=node-2 -E http.port=9201 -E transport.port=9301 -E path.data=/ES/node2/data -E path.logs=/ES/node2/logs
./elasticsearch -d -E node.name=node-3 -E http.port=9202 -E transport.port=9302 -E path.data=/ES/node3/data -E path.logs=/ES/node3/logs
运行上面的命令,然后我们通过对应的ps命令,查询的结果如下:
我这儿说说我的碰到的错误吧!之前的启动的时候一直说我的http.cors.allow‐origin: "*" 这个参数项解析不来,应该是编码的问题,于是我重新打了一次,然后用utf-8格式保存解决了,然后在启动的时候,直接报错,就是上一次运行的没有报的错:**max number of threads [2048] for user [tongtech] is too low, increase to at least [4096]用户的最大线程数[2048]过低,增加到至少[4096]**大家可以参考这篇的文章解决linux修改limits.conf不生效,最后在谷歌浏览器中看看我们启动的情况。具体的如下:
这个第一种方式讲完了,然后我们看第二种的方式
2.2多配置文件的方式启动多台elasticsearch
这种方式比较简单,我们只需要将原来的elasticsearch的目录复制三份,然后分别修改对应的配置文件,具体的如下:
elasticsearch-7.3.2_node1
cluster.name: king
node.name: node‐1
node.master: true
node.data: true
network.host: 0.0.0.0
http.port: 9200
transport.port: 9300
cluster.initial_master_nodes: ["node‐1"]
discovery.seed_hosts: ["92.168.181.6:9300", "92.168.181.6:9301","92.168.181.6:9302"]
discovery.zen.minimum_master_nodes: 2
http.cors.enabled: true
http.cors.allow‐origin: "*"
elasticsearch-7.3.2_node2
cluster.name: king
node.name: node‐2
node.master: true
node.data: true
network.host: 0.0.0.0
http.port: 9201
transport.port: 9301
cluster.initial_master_nodes: ["node‐1"]
discovery.seed_hosts: ["192.168.181.6:9300", "92.168.181.6:9301","92.168.181.6:9302"]
discovery.zen.minimum_master_nodes: 2
http.cors.enabled: true
http.cors.allow‐origin: "*"
elasticsearch-7.3.2_node3
cluster.name: king
node.name: node‐3
node.master: true
node.data: true
network.host: 0.0.0.0
http.port: 9202
transport.port: 9302
cluster.initial_master_nodes: ["node‐1"]
discovery.seed_hosts: ["192.168.181.6:9300", "92.168.181.6:9301","92.168.181.6:9302"]
discovery.zen.minimum_master_nodes: 2
http.cors.enabled: true
http.cors.allow‐origin: "*"
分别启动:
./elasticsearch ‐p /tmp/elasticsearch_9200_pid ‐d
./elasticsearch ‐p /tmp/elasticsearch_9201_pid ‐d
./elasticsearch ‐p /tmp/elasticsearch_9202_pid ‐d
这种方式我这儿就不演示,因为这种方式比较简单,只要对应的配置的文件配置好就行了。
3.写的机制
步骤:
- 客户端向 NODE I 发送写请求。
- 检查Active的Shard数。
- NODEI 使用文档 ID 来确定文档属于分片 0,通过集群状态中的内容路由表信息获知分片 0 的主分片位于NODE3 ,因此请求被转发到 NODE3 上。
- NODE3 上的主分片执行写操作 。 如果写入成功,则它将请求并行转发到 NODE I 和 NODE2 的副分片上,等待返回结果 。当所有的副分片都报告成功, NODE3 将向协调节点报告 成功,协调节点再向客户端报告成功 。 在客户端收到成功响应时 ,意味着写操作已经在主分片和所有副分片都执行完成。
注意:
-
为什么要检查Active的Shard数? ES中有一个参数,叫做waitforactiveshards,这个参数是Index的一个setting,也可以在请求中带上这个参数。这个参数的含义是,在每次写入前,该shard至少具有的active副本数。假设我们有一个Index,其每个Shard有3个Replica,加上Primary则总共有4个副本。如果配置waitforactiveshards为3,那么允许最多有一个Replica挂掉,如果有两个Replica挂掉,则Active的副本数不足3,此时不允许写入。 这个参数默认是1,即只要Primary在就可以写入,起不到什么作用。如果配置大于1,可以起到一种保护的作用,保证写入的数据具有更高的可靠性。但是这个参数只在写入前检查,并不保证数据一定在至少这些个副本上写入成功,所以并不是严格保证了最少写入了多少个副本。 -
在以前的版本中,是写一致性机制,现被替换为waitforactiveshards one:要求我们这个写操作,只要有一个primary shard是active活跃可用的,就可以执行 all:要求我们这个写操作,必须所有的primary shard和replica shard都是活跃的,才可以执行这个写操作 quorum:要求所有的shard中,必须是大部分的shard都是活跃的,可用的,才可以执行这个写操作 写一致性的默认策略是 quorum,即多数的分片(其中分片副本可以是主分片或副分片)在 写入操作时处于可用状态。 put /index/type/id?consistency=quorum
quroum = int( (primary + number_of_replicas) / 2 ) + 1
参数 | 简介 |
---|
version | 设置文档版本号。主要用于实现乐观锁 | version_type | 详见版本类型 | op_type | 可设置为 create 。 代表仅在文档不存在时才写入 。 如果文档己存在,则写请求 将失败 | routing | ES 默认使用文档 ID 进行路由,指定 routing 可使用 routing 值进行路由 | wait_for_active_shards | 用于控制写一致性,当指定数量的分片副本可用时才执行写入,否则重试直至超 时 。默认为 l , 主分片可用 即执行写入 | refresh | 写入完毕后执行 refresh ,使其对搜索可见 | timeout | 请求超时时间 , 默认为 l 分钟 | pipeline | 指定事先创建好的 pipeline 名称 |
-
写入Primary完成后,为何要等待所有Replica响应(或连接失败)后返回 在更早的ES版本,Primary和Replica之间是允许异步复制的,即写入Primary成功即可返回。但是这种模式下,如果Primary挂掉,就有丢数据的风险,而且从Replica读数据也很难保证能读到最新的数据。所以后来ES就取消异步模式了,改成Primary等Replica返回后再返回给客户端。 因为Primary要等所有Replica返回才能返回给客户端,那么延迟就会受到最慢的Replica的影响,这确实是目前ES架构的一个弊端。之前曾误认为这里是等waitforactive_shards个副本写入成功即可返回,但是后来读源码发现是等所有Replica返回的。 如果Replica写入失败,ES会执行一些重试逻辑等,但最终并不强求一定要在多少个节点写入成功。在返回的结果中,会包含数据在多少个shard中写入成功了,多少个失败了 如果Replica写入失败,ES会执行一些重试逻辑等,如果重试失败了,会通过广播的方式来通知其他的分片和副本,可以将这个副本剔除了。
4.新的节点加入或者有节点宕机的情况
在演示这种情况的时候,我们先创建3个分片,两个副本,先启动我们的kibana,然后用我们的kibana来操作创建,至于kibana如何启动,可以参考我的上一篇博客。
打开我们的kibana的界面如下:
我们在控制台输入以下的命令:
PUT /king
{
"settings": {
"number_of_shards": "4",
"number_of_replicas": "2"
}
}
运行结果如下:
加深的的就是分片,浅色的就是副本,这个时候我们再添加一个节点,还是原来的方式,我们先创建/ES/node4/data``/ES/node4/logs 两个文件,然后执行如下的命令:
./elasticsearch -d -E node.name=node-4 -E http.port=9203 -E transport.port=9303 -E path.data=/ES/node4/data -E path.logs=/ES/node4/logs
可以发现我们的node4已经启动起来了,这个时候我们来看下节点的信息,具体的如下:
从上面的信息可以发现:一个节点可以有多个主分片,一个节点只能有一个同样副本 不可能出现两个一样的副本都在一个节点,当加入新节点时 副本会被重新分配主分片也变
这个时候我们来演示宕机的情况,我们将node-4给kill掉,具体的如下:
然后我们再来看节点的情况,节点的情况如下:
从上面的信息可以发现:只有副本的分片宕机后集群自动重新分配副本 集群依然为绿色当有主分片的机器宕机后 副本会成为主分片
总结: 一个节点可以有多个主分片,一个节点只能有一个同样副本 不可能出现两个一样的副本都在一个节点,当加入新节点时 副本会被重新分配,主分片也变,只有副本的分片,宕机后集群自动重新分配副本,集群依然为绿色,当有主分片的机器宕机后 副本会成为主分片
5.写在最后
这篇的博客主要讲了下elasticsearch的集群的搭建,elasticsearch的写的机制,以及新的节点的加入和节点宕机对分片和副本的影响。
|