淘先锋技术网

首页 1 2 3 4 5 6 7

1、ES集群介绍

单机的ES做数据存储与搜索,必然面临两个问题:

  • 海量数据存储问题
  • 单点故障问题

因此,考虑使用ES集群:

  • 海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard),存储到多个节点。如此,ES的存储能力就是所有节点存储能力的总和
    在这里插入图片描述

  • 单点故障问题:将分片数据在不同的节点备份(replica),即主分片和副本分片不能在同一个节点
    在这里插入图片描述

2、搭建ES集群

利用3个docker容器模拟3个es的节点:

  • 首先编写 docker-compoes.yml文件,内容:
version: '2.2'
services:
  es01:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    container_name: es01
    environment:
      - node.name=es01  
      - cluster.name=es-docker-cluster  # 这里集群名称一样,集群名称相同的节点会形成集群
      - discovery.seed_hosts=es02,es03  # 集群中另外两个节点的IP,但这里我用容器模拟了,用容器名就能互连
      - cluster.initial_master_nodes=es01,es02,es03  # 集群有主从之分,这三个节点参与选举,产生主节点
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data01:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
    networks:
      - elastic  # 网络
  es02:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    container_name: es02
    environment:
      - node.name=es02
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es03
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    volumes:
      - data02:/usr/share/elasticsearch/data
	ports:
      - 9201:9200  # 宿主机9200已用,这里+1
    networks:
      - elastic
  es03:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.12.1
    container_name: es03
    environment:
      - node.name=es03
      - cluster.name=es-docker-cluster
      - discovery.seed_hosts=es01,es02
      - cluster.initial_master_nodes=es01,es02,es03
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    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
  • es运行需要修改一些linux系统权限,修改/etc/sysctl.conf文件:
vi /etc/sysctl.conf
  • 添加内容:
  • 生效配置:
  • 通过docker-compose启动集群:
docker-compose up -d

# yum install docker-compose

在这里插入图片描述

3、集群状态监控

kibana可以监控es集群,但新版需要依赖es的x-pack功能,配置复杂,这里用cerebro来监控es集群状态

# 官网
https://github.com/lmenezes/cerebro

# 网盘
链接:https://pan.baidu.com/s/1dj4HgTZsVfFSe6-hR2ydnA?pwd=9527 
提取码:9527
  • 下载完成后解压
    在这里插入图片描述

  • 进入bin,双击cerebro.bat
    在这里插入图片描述

  • 访问localhost:9000,输入任一节点的地址(地址后面有个/)
    在这里插入图片描述
    在这里插入图片描述

创建索引库

集群中,每个索引库的分片数量、副本数量都是在创建索引库时指定的,并且分片数量一旦设置以后无法修改。

语法如下:

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

在cerebro中创建索引库:

在这里插入图片描述

填索引库名和分片数、副本数:

在这里插入图片描述

查看overview,实线为主分片,虚线为副本分片:

在这里插入图片描述

4、集群职责及脑裂

集群节点职责:

ES集群中,不同的节点有不同的职责:

在这里插入图片描述

以上角色的默认值都为ture,但不同的角色职责不同,对硬件的要求也不同,有的对CPU要求高,有的对硬盘要求高,因此,应该每个节点都有自己独立的角色。举个例子如下图,每个节点专门干一件事:

在这里插入图片描述

脑裂:

默认情况下,每个节点都是master eligible节点,因此一旦master节点宕机,其它候选节点会选举一个成为主节点。但当主节点只是与其他节点有暂时的网络通信故障时:

在这里插入图片描述

备选节点联系不上主节点,以为主节点宕机,选举出一个新的master,由此产生两个主节点,当网络恢复,就会出现数据不一致的情况。

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

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

没启动kibana,直接调接口插入三条doc:(在9201,即es01节点插入数据)

在这里插入图片描述
查询文档,不管在9201、9202、9203,三个节点都能查到数据:

在这里插入图片描述
添加explain参数来看分片情况:三条数据在不同的分片

在这里插入图片描述

这是协调节点工作的结果,当新增文档时,它会将数据保存到不同分片,保证数据均衡。而coordinating node确实数据存到哪个分片是根据:

在这里插入图片描述

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

存储和查询都依赖这个算法,因此分片数量不能再变,否则按某个分分片数量存进去后,分片数量改变,等查的时候按这个算法计算找文档就找不到了。

新增文档流程:

在这里插入图片描述
当然,根据id查询,还是这么个流程。但如果不知道文档id,该怎么查,比如match_all

ES集群的分布式查询

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

在这里插入图片描述
coordinating node可能为其中任一个节点,就像上面match_all查询,不管访问哪个节点,最终都可以拿到三条数据。

6、ES故障转移

集群的master节点会监控集群中的节点状态,如果发现有节点宕机,会立即将宕机节点的分片数据迁移到其它节点,确保数据安全,即故障转移。比如有条数据,存于三个节点的主分片分别为P-0、P-1、P-2,副本为R-0、R-1、R-2,此时node1节点宕机:

在这里插入图片描述

当然R0+P1+P2还是可以凑出这条数据,但此时数据已经不安全,需要迁移:

在这里插入图片描述

实际模拟一下,此时三个节点都正常,数据存在三分节点上:

在这里插入图片描述

//停掉es1容器,模拟节点宕机
docker stop es01

查看集群情况:变黄了,不健康了,数据分片0有两个(主副都在),但1、2分片都只有一个了
在这里插入图片描述

再等等,开始了数据迁移了:

在这里插入图片描述
重新启动es01,查看效果:

docker start es01

分片回去了,数据还是均衡的,但es01已不再是主节点。这倒有点想Redis的哨兵模式。

在这里插入图片描述

总结:

在这里插入图片描述