elasticsearch集群
  VxbKCNpUI3P6 2023年11月30日 35 0

一、elasticsearch集群结构介绍

单机的elasticsearch做数据存储,必然面临两个问题:海量数据存储问题、单点故障问题。

  • 海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard),存储到多个节点,每个节点存放在一个服务器上
  • 单点故障问题:将分片数据在不同节点备份(replica),例如:0号分片的数据保存到node2节点上,这样,0号分片所在分主机出现宕机,数据也不会丢失

elasticsearch集群_数据

 注意:分片都是在不同的node主机上,互相备份不同节点

二、elasticsearch集群搭建

2.1.集群搭建

创用3个docker容器模拟3个es的节点。由于docker容器之间互隔离,用来模拟是没有问题的,不过生产环境推荐大家每一台服务器节点仅部署一个es的实例

下面部署es集群使用docker-compose来完成,要求你的Linux虚拟机至少有4G的内存空间, docker-compose文件是在一个文本文件里去描述多个容器的部署方式,从而形成将来一键部署,在这个compose文件里描述了我们要部署的三个ES节点的容器部署方案es01、es02、es03,如下:docker-compose.yml文件内容如下:

version: '2.2'
services:
  es01:
    image: elasticsearch:7.17.5
    container_name: es01
    environment:
      - node.name=es01
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es02,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - data01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - elastic
  es02:
    image: elasticsearch:7.17.5
    container_name: es02
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - data02:/usr/share/elasticsearch/data
    ports:
      - 9201:9200
    networks:
      - elastic
  es03:
    image: elasticsearch:7.17.5
    container_name: es03
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - data03:/usr/share/elasticsearch/data
    networks:
      - elastic
    ports:
      - 9202:9200
volumes:
  data01:
    driver: local
  data02:
    driver: local
  data03:
    driver: local

networks:
  elastic:
    driver: bridge

将上面的文件上传到root目录如下:

elasticsearch集群_elasticsearch_02

es运行需要修改一些linux系统权限,修改/etc/sysctl.conf文件

vi/etc/sysctl.conf

添加下面的内容:

vm.max_map_count=262144

然后执行命令,让配置生效:

sysctl -p

执行后如下:

elasticsearch集群_docker_03

 执行创建容器集群命令如下:

docker-compose up -d

执行后如下:

elasticsearch集群_elasticsearch_04

2.2.集群监控

kibana可以监控es集群,不过新版本需要依赖es的x-pack功能,配置比较复杂。这里推荐使用cerebro来监控es集群状态,官方网址:https://github.com/lmenezes/cerebro

elasticsearch集群_数据_05

 下载后解压:

elasticsearch集群_数据_06

进入bin目录,点击cerebro.bat启动,然后再浏览器访问:http://localhost:9000,即可打开启动页面,

elasticsearch集群_elasticsearch_07

输入地址打开监控页面

elasticsearch集群_docker_08

绿色的线条,表示elasticsearch集群状态健康

实心的星代表它是主节点,

空心的星:候选节点,将来可以参与主节点的选举

elasticsearch集群_数据_09

2.3.创建索引库

2.3.1.利用kiba na的Dev Tools创建索引库

在DevTools中输入指令:

PUT /itcast
{
  "settings": {
    "number_of_shards": 3, // 分片数量
    "number_of_replicas": 1 // 副本数量
  },
  "mappings": {
    "properties": {
      // mapping映射定义 ...
    }
  }
}

2.3.2.利用cerebro创建索引库

进入创建索引库页面

elasticsearch集群_elasticsearch_10

进入页面后执行如下:

elasticsearch集群_docker_11

创建后主页:显示创建的索引库,并进行了分片,实线框:0 1 2主分片 虚线框:副本分片

并且每个分片在不同的机器上,这样就确保了如果有任意一台机器宕机备份依然在保存的,避免出现数据故障

elasticsearch集群_elasticsearch_12

三、elasticsearch集群职责及脑裂

3.1.ES集群的节点角色

elasticsearch中集群节点有不同的职责划分:

elasticsearch集群_elasticsearch_13

说明:

  • master eligible:备选主节点(候选主节点)可以参与竞选主节点,为了防止主节点挂了,候选主节点可以顶上去,做到高可用
  • ingest:预处理节点,可以进行节点的预处理,将文档插入到索引库里,插入之前ingest节点,可以对这个文档做预处理,例如:加一个字段啊,删除一个字段,或者对某些字段的内容做修改,都可以由它来做 ,但是在准备文档的时候,一般会用java代码把文档处理好了,直接往索引库插入,所以就不需要预处理了。
  • corrindinating:协调节点 比如说有用户请求搜索数据,到达协调节点,它会把这个请求路由到真正处理的数据节点上去,数据节点处理完之后把结果返回,它在把结果合并,返回给用户,协调节点自己不需要去处理,只要路由一下,路由的时候还可以随机路由,还起到负载均衡的作用。这个节点就可以说是路由+负载均衡 然后合并结果
  • 默认ES节点同时具备这四种角色,身兼数职,但是在实际开发过程中,不能让节点身兼数职,原因:不同的职责对硬件的配置需要是不一样的,主节点是管理集群的,不做数据处理,只需要对cpu有一定的要求即可。数据节点要求较高,需要磁盘大一点,对内存要求较高,对cpu也有要求。协调节点要求较低,对cpu要求一点,对磁盘没有要求。

实际操作的时候可以把角色分离,针对不同的角色,给它搭配不同的硬件,来减少成本,第二个因为他们之间的职责会产生影响,比如说数据节点跟主节点耦合在一起,数据处理的时候会大量的占用CPU和内存,主节点的任务有可能就无法完成了,没办法去监管整个集群了,出现主节点无法连接的情况。

因此一个典型的ES集群,它一定是把每个节点的职责,分离出去,不同的节点去干不同的事,怎样去控制节点的职责呢,在环境变量里去控制几个参数

默认情况下所有节点都是协调节点,可以控制一个节点只干协调,不用做其他的,只需要将上面表格中三个true都调成false,如下:

elasticsearch集群_elasticsearch_14

3.2.ES集群的分布式查询

elastic search中的每个节点角色都有自己不同的职责,因此建议集群部署时,每个节点都有独立的角色。

elasticsearch集群_数据_15

有三个协调节点,N个数据节点(海量数据存储),3个候选节点(保证高可用)

还可以有一个负载均衡器,最协调节点做负载均衡比如说用nginx,用户请求来了,可以由不同的协调节点去接受,这样就提升了并发能力,协调节点,再把请求路由到数据节点,n个数据节点可以做海量数据存储,可以避免单点故障

这样的ES集群就是一个比较健壮的集群了,缺点是:搭建起来比较麻烦,往往会有一个脑裂的问题

3.3.elasticsearch集群的脑裂

3.3.1.脑裂问题现象说明

默认情况下,每个节点都是master eligible(备选节点)节点,因此一旦master节点岩机,其它候选节点会选举一个成为主节点。当主节点与其他节点网络故障时,可能发生脑裂问题。

elasticsearch集群_docker_16

 

脑裂:当出现网路阻塞node1节点是好的,但是网络问题导致node1和node2 node3连接不上了,当node2 node3连不上node1的时候,会认为node1挂了,node2和node3会选举出来新的主节点,这个时候相当于集群中出现了两个主节点,一部分节点跟node1结合,有数据做增删改查的时候由node1来控制,还有一部分由node3来结合,数据做增删改查的时候由node3来控制,这两部分各自处理各自的集群,一旦网络恢复,用户在来访问的时候会出现数据不一致的情况,这就是脑裂问题,一个集群出现了两个主节点。

3.3.2.脑裂问题如何解决?

默认情况下,每个节点都是master eligible节点,因此一旦master节点岩机,其它候选节点会选举一个成为主节点。当主节点与其他节点网络故障时,可能发生脑裂问题。

为了避免脑裂,需要要求选票超过(eligible节点数量+1)/2  才能当选为主,因此eligible节点数量最好是奇数。对应配置项是discovery.zen.minimum_master_nodes,在es7.以后,已经成为默认配置,因此一般不会发生脑裂问题

elasticsearch集群_数据_17

四、分布式新增和查询流程

4.1.ES集群的分布式存储

4.1.1.分布式存储算法说明

当新增文档时,应该保存到不同分片,但是需要保证数据均衡(每一个分片的数据量应该是需要差不多的),那么coordinating node如何确定数据该存储到哪个分片呢?

elasticsearch会通过hash算法来计算文档应该存储到哪个分片:

elasticsearch集群_数据_18

说明:

  • _routing默认是文档的id
  • number_of_shards 主分片数量
  • 算法与分片数量有关,因此索引库一旦创建,分片数量不能修改!

4.1.2.测试

测试,插入数据:在9200端口,相当于集群的es01节点,利用postman发起三条请求,添加三条数据,注意文档id需要改变,内容为了测试方便,也是需要改变

elasticsearch集群_elasticsearch_19

查询:在9200端口的elasticsearch容器查询所有的数据,如下:

elasticsearch集群_docker_20

在9201和9202端口的elasticsearch中查询:也查到这三条,如下:

elasticsearch集群_数据_21

elasticsearch集群_docker_22

那么这些数据到底存储到那个分片上呢?

可以通过添加一个命令:explain值为true 可以查看存储到那个分片上,如下:

elasticsearch集群_数据_23

4.2.elasticsearch集群的分布式存储

上面测试的时候数据明明是在9200上插入的,为什么在3个片上都有呢,说明协调节点确实工作了,那么它是怎么工作的呢? 

就是利用前面的算法计算,存入数据的时候使用分片的数量运算存储,查询的时候使用分片的数量去运算那个分片查询 ,所以分片的数量一旦创建之后一定不能更改

elasticsearch集群_docker_24

4.3.elasticsearch集群的分布式查询

elasticsearch的查询分成两个阶段:

  • scatter phase:分散阶段,coordinating node(协调节点)会把请求分发到每一个分片
  • gather phase:聚集阶段,coordinating node(协调节点)汇总data node(数据节点)的搜索结果,并处理为最终结果集返回给用户

elasticsearch集群_elasticsearch_25

五、elasticsearch集群故障转移

5.1.什么是elasticsearch集群故障转移

集群的master节点会监控集群中的各个节点状态,如果发现有节点岩机,会立即将宕机节点的分片数据迁移到其它节点,确保数据安全,这个叫做故障转移。

elasticsearch集群_docker_26

当主节点挂掉之后,会重新选举,选出主节点,(此时的节点数据状态是不安全的,p-1没有副本分片,r-0没有主分片)0号片和0号片的数据是不安全的,因为只有一份一旦挂了就完了,此时寄集群的状态处于危险的边缘转态,主节点发现挂的节点 ,看一下上面有什么分片,然后把它迁移到健康的节点上面,确保任何一份分片都由两份,确保数据的安全

故障转移如下:

elasticsearch集群_elasticsearch_27

5.2.测试elasticsearch集群故障转移

测试把es01节点停掉,停止容易运行即可,执行如下命令:

docker-compose stop es01

但是需要注意:结束es01节点后,监控界面也需要替换连接其他两个节点的es

观察监控界面颜色变了: 变黄了,表示发现了某个节点状态不正常,需要经过一会等待颜色会恢复正常:会进行数据迁移,把故障节点的数据迁移到正常的节点上了es02和es03上都由了3个片了,集群中每一个片都由2分满足了最低要求,集群又变成绿色了,这就是故障转移,效果如下:

elasticsearch集群_数据_28

那么数据有没有丢失呢?查询一下发现并没有丢失

elasticsearch集群_数据_29

如果重启es01:

docker-compose start es01

等待es01节点恢复,此时它已经不是主节点了,这时候主分片es02把分片又迁回去了,确保每个分片上都有数据,重新做了一个备份,确保数据是均衡的

elasticsearch集群_数据_30

此时从es01节点查询,也能正常工作查询出来数据,如下:

elasticsearch集群_docker_31



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月30日 0

暂无评论

推荐阅读
VxbKCNpUI3P6