详解SpringCloud微服务技术栈:深入ElasticSearch(4)——ES集群

👨‍🎓作者简介:一位大四、研0学生,正在努力准备大四暑假的实习

🌌上期文章:详解SpringCloud微服务技术栈:深入ElasticSearch(3)------数据同步(酒店管理项目)

📚订阅专栏:微服务技术全家桶

希望文章对你们有所帮助

ElasticSearch本身就是分布式的,在这里将要讨论如何用3个docker容器来模拟实现ElasticSearch的集群搭建,并且提出集群会出现的脑裂问题并讨论解决方案。

但是这里集群的部署需要我们的Linux虚拟机至少拥有4G的内存空间,内存有限就不要做了。

深入ElasticSearch(4)------ES集群

集群结构介绍

单机的ElasticSearch做数据存储,会面临两个问题:海量数据存储问题,单点故障问题。

针对这两个问题,不得不用集群来解决了:

海量数据存储问题:将索引库从逻辑上拆分为N个分片(shard),存储到多个节点

单点故障问题:将分片数据在不同节点备份(replica),也就是说其主分片和副本分片不能在同一个节点

搭建集群

没有多台电脑,所以这里会利用3个docker容器来模拟3个ES结点。

编写docker-compose文件,里面包含了三个容器结点的部署方案,大致看懂语句的意思是什么:

powershell 复制代码
version: '2.2'
services:
  es01:
    image: elasticsearch:7.12.1 # 镜像
    container_name: es01 # 容器名,与服务es01名称保持一致
    environment:
      - node.name=es01 # 结点名称,与服务es01名称保持一致
      - cluster.name=es-docker-cluster # 集群名称,三个节点的名称都要一样,ES就会自动组装成集群
      - discovery.seed_hosts=es02,es03 # 集群中另外两个结点,docker中可以直接在容器内互联,不一定要ip地址
      - 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.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
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - data02:/usr/share/elasticsearch/data
    ports:
      - 9201:9200
    networks:
      - elastic
  es03:
    image: 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
      - "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

这个docker-compose文件直接可以从百度网盘中下载并上传到虚拟机:

链接:https://pan.baidu.com/s/10By3MR6RYqqMmjBgwDOr7w?pwd=mycu

提取码:mycu

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

powershell 复制代码
vi /etc/sysctl.conf

添加下面内容:

powershell 复制代码
vm.max_map_count = 262144

再执行语句让配置生效:

powershell 复制代码
sysctl -p

最后执行docker-compose up -d执行即可。

集群的状态监控这里不再推荐kibana了,配置比较复杂,推荐使用cerebro来监控ES集群的状态,压缩包从网盘下载:

链接:https://pan.baidu.com/s/1kywnAFGyVbbpRN4weRF8Ag?pwd=laz2

提取码:laz2

下载完就在本地解压,然后进入其中的bin目录,双击其中的cerebro.bat即可启动服务。访问9000端口就可以访问了。

在这里就可以创建索引库,并且可以直接指定需要分片的数量为3,每个分片锁被备份的数量为1。

集群职责及脑裂

ElasticSearch中节点的角色有4中:

节点类型 配置参数 默认值 节点职责
master eligible node.master true 作为备选主节点,一旦当选,则:管理和记录集群状态;处理分片在哪个节点;处理创建和删除索引库的请求
data node.data true 数据节点:存储数据、搜索、聚合、CRUD
ingest node.ingest true 数据存储之前的预处理
coordinating 上面3个参数都为false则为coordinating节点 路由请求到其它节点;合并其它节点处理的结果,返回给用户

这种方式把职责分开显然是很好的,但是还是可能会出现问题,即脑裂问题

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

node1位主节点,原先就是没有故障的,但是和备选主节点node2、node3由于网络阻塞问题没办法互联了,这时候node2或node3可能就会误认为node1宕机了,自动选举出主节点。从而造成了集群中有2个主节点,它们共同执行了系统的业务,当网络恢复正常的时候,访问节点的数据的时候就会发生数据不一致的问题。

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

分布式新增和查询流程

当新增文档时,应该保存到不同的分片,保证数据均衡,coordinating node可以确定数据该存储到哪个分片中。

例如,配置好的三台ES,从9200端口中保存3条文档,可以发现9201和9202端口都可以查询到这三条文档,同时三条消息分别分片到了三台不同的机器上。这就是协调结点起到的作用。

实际上,这个数据分片是利用一个算法来实现的:
s h a r d = h a s h ( _ r o u t i n g ) % n u m b e r _ o f _ s h a r d s shard = hash(\_routing) \% number\_of\_shards shard=hash(_routing)%number_of_shards

_routing默认是文档的id

算法与分片数量有关,因此索引库一旦创建,分片数量不能修改

这样的话,3台机器运算后的结果只会是0、1、2中的一个,从而实现数据的分布式新增。

查询分成2个阶段:

scatter phase:分散阶段,coordinating node会把请求分发到每一个分片

gather phase:聚集阶段,coordinating node汇总data node的搜索结果,并处理为最终结果集返回给用户

总结:

1、分布式新增如何确定分片:coordinating node根据id做hash运算,得到结果对shard数量取余,余数就是对应的分片

2、分布式查询:分散阶段、聚集阶段

故障转移

故障转移是ES节点一个非常重要的功能,集群的master节点会监控集群中的节点状态,如果发现有节点宕机,会立即将宕机节点的分片数据迁移到其它节点,确保数据的安全,即为故障转移。

也就是说,当数据节点发生故障时,主节点会监控到这种状态,就会将节点中的所有分片和副本都转移到其它的节点,确保数据的安全。
而主节点本身宕机的话,EligibleMaster就会选举出新的主节点出来

相关推荐
NE_STOP11 小时前
Vide Coding--AI编程工具的选择
java
码云数智-园园12 小时前
C++20 Modules 模块详解
java·开发语言·spring
程序员黑豆12 小时前
JDK 下载安装与配置详细教程
java·前端·ai编程
大志哥12312 小时前
ES和Logstash日志链路系统上线后遭遇切片爆炸(解决)
大数据·elasticsearch
霸道流氓气质12 小时前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
小宇宙Zz12 小时前
Maven依赖冲突
java·服务器·maven
swordbob12 小时前
NIO的channel中什么是 fd(File Descriptor,文件描述符)
java·开发语言·nio
咖啡八杯13 小时前
GoF设计模式——享元模式
java·spring·设计模式·享元模式
十五喵源码网13 小时前
基于springboot2+vue2的租房管理系统
java·毕业设计·springboot·论文笔记
摇滚侠13 小时前
IDEA 创建 Java 项目 手动整合 SSM 框架
java·ide·intellij-idea