ES相关分布式特性

es分布式介绍

  • es是分布式的,能够轻松扩容到上百到上千台服务节点,并能够支持pb级数据
  • es对用户屏蔽了分布式的复杂性,以下相关分布式特性在幕后自动发生

    共识算法,es中使用了PacificA算法
    节点发现
    节点选主
    分区故障
    副本日志复制
    文档数据分片
    节点间文档索引、查询相关负载均衡算法策略
    shard副本,高可用
    节点请求路由转发
    节点扩缩容,无缝集成与重新分片
    故障转移

  • 虽然es屏蔽了分布式系统的复杂性,但是我们如果能了解下es的分布式特性,对于我们学习其他的分布式算法,实现自己的分布式系统,丰富es的知识都是必要的。

基本概念

在了解集群分布式特性之前,先了解下相关基本概念。分布式系统可以说是一个非常大的知识体系。其中分布式共识算法,一致性在分布式系统中作为最基础的理论基础尤为重要,本文重点先入门了解下es的分布式相关特性。先大概了解下分布式要解决的核心问题,对分布式系统有个宏观的理解,后续再针对分布式算法写一个专题系列,重点讲解下主流的一致性算法:paxos、multi paxos、gossip、ZAB、RAFT、pacificA等。

Node 节点

对于单节点来说,达成数据共识是一件简单的事情,如果多个节点组成一个集群,那么在集群之间达成共识,就是分布式要解决的问题。

  • 任意时刻启动一个es的实例,就是启动一个Node节点;互联的node的集合称为集群cluster。如果你启动了一个单一的es的节点,那么该集群中相当于只有一个节点。

  • 每个节点默认是都能处理http和网络传输协议的。传输层是专门用在node节点间间通信;http层被rest客户端使用。

  • 每个节点都知道集群中的其他任意节点,并且能够转发客户端请求到适当的节点上。

  • 默认情况下,一个节点拥有所有这些类型:master-eligible,data,ingest,machine learning(如果被勾选了),transform nodes
    Node roles

  • 客户端可以根集群中的每一个节点进行交互(包括主节点),每个节点都能知道每一份文档存储在哪里,并能路由客户端的请求,到正确存储了你需要的数据的节点上

  • 我们进行交互的任意节点,都将管理从一个或多个节点上收集数据,并返回响应到客户端的过程,这一切都由Es透明的管理。

  • 可以在配置文件中,自定义节点的角色。如果不进行配置,每个节点默认有以下角色

    master
    data
    ingest
    machine learning
    remote_cluster_client

  • 如果设置了node.roles.那么该节点只有指定的角色

Cluster 集群

每一个node都是一个运行中es实例,一组有相同名字集群名【cluster.name】的节点,组成了集群;该集群共享数据和工作负载;当集群中有新节点加入或节点删除时,集群能够自己重新组织并均匀分布数据。

节点发现

1.在同一台机器上启动一个新的Node,只要配置的cluster.name和之前的cluster.name一致,该节点会被自动发现,并加入到集群中。

2.如果是在不同的机器上启动新节点,并希望加入到集群中,则需要配置可以联系到的主机列表

分片

1.首先要存储数据,必须要建立索引。在es中索引实际仅仅是一个逻辑上的命名空间,这个命名空间指向的是一个或多个的分片shard,其中分片的出先可以实现水平扩容,副本分片的出现作用于高可用。
2.一个分片是一个仅仅保存了索引中所有数据中一部分分片数据的低级别的工作单元
3.一个分片就是一个Lucene实例,对于他本身而言就是一个完整的查询搜索引擎。
4.我们的文档是被存储索引在分片中的,但是客户端并不直接和分片交互,而是和index索引进行交互
5.众多分片是ES集群分布式存储数据的方式,可以简单把分片当作存储数据的容器。文档存储在分片中,分片被分配到集群中的节点Node中。
6.当集群扩容、缩容时,es能够自动的对集群节点中分片上的数据进行迁移,最终仍能保证数据均衡分布
7.分片分为主分片和副本分片
8.每个分片从技术实现上来讲,最大可以索引Integer.MAX_VALUE-128个文档;实际上存储的上限取决于你的硬件资源、文档结构的复杂度等

  • primary shard 主分片
  1. 每个文档都只会存储在一个主分片中,不会分散存储在多个主分片中,并且每个分片所存储的容量是有上限的,因此我们配置的每个索引的主分片数量,就决定了该索引最大的容量。
  2. 主分片的数量是在创建索引时就确定的,不能再修改
  • replica shard 副本分片
    副本分片是主分片的一个copy,有两个目的一是:解决单点问题,用于冗余数据,应对硬件故障,实现高可用;二是:大流量支撑,每个副本都可以提供查询、检索请求。

    副本数量在任何时刻都可以变更
    每个主分片的副本分片,不会被和他的主分片分配在同一个Node节点上,因为在同一个节点上的主、副本分配上没有任何意义的,一旦该Node挂掉,这个Node节点上的主、副本副片都会丢失。

选主节点

es是元数据相关的操作,是强领导者模型的,但是文档级别的变更操作,主节点并不会参与进来,因此不会成为增长的瓶颈。
  • 有多个node组成的一个集群中,需要选举出一个主节点leader节点。
  • 主节点负载整个集群范围内的各种变更操作,比如:创建、删除索引;在集群中删除、添加一个新的node节点等操作。注意是集群这个维度的变更
  • 主节点并不参与文档级级别的变更、查询操作,因此主节点的存在并不会成为流量增长的瓶颈
  • 集群中的任何节点都可以被选举为主节点

shard副本同步

  • 新的文档被索引时,先被索引到主分配,然后并行化的复制到关联的副本分片中。

水平扩容

单Node,3主分片

ES相关分布式特性_第1张图片

两Node,3主分片,每个主节点1个Replica副本节点

ES相关分布式特性_第2张图片

三Node,3主分片,每个主节点1个Replica副本节点

ES相关分布式特性_第3张图片

1.示例中一个索引3主分片1副本(每个主分片一个副本),由单节点到3个节点的过程就是水平扩容Scale Horizontally的过程.

2.扩容到三个节点后,每个节点现在有两个分片,由于前文讲过,实际上一个分片就是一个完整的Lucene实例。这就意味着单个节点的系统资源比如(CPU\内存\IO)将会在更少的分片之间共享,这样每个节点上的分片性能更佳

3.理论上对于上诉示例,我们可以扩充到6个Node,这样每个分片都会独享每个节点的系统资源

三Node,3主分片,每个主分片2个副本分片

ES相关分布式特性_第4张图片

上诉共9个分片(3主分片+6副本),这意味着我们可以扩容到9个Node,每个分片在一个节点上。也就意味着我们可以向外扩展到3倍吞吐量的性能。
查询、检索操作可以在副本分片和主分片中进行,因此理论上更多的副本分片,可以增大查询检索吞吐量,但是如果副本分片集中在同一个Node中也并不能有更多提升,因为每个分片将共享同一个Node的系统资源,处理效率相对不会太高。

故障转移

上一讲讲到的水平扩容,索引有3主分片、6个副本、3个Node节点
下面看一下Node节点下线过程

kill掉主节点node1,后效果如果

ES相关分布式特性_第5张图片

1.下掉master节点后,因为集群间元数据(索引创建、mapping映射、节点发现)等集群间管理操作,是需要主节点进行交互的,因此会在剩下的两个节点上,选出一个主节点

2.杀掉master节点后,我们丢失掉了P1、P2两个分片,因为缺少了主分片的信息,集群中索引将会收到影响。此时集群健康状态为red(红色):非所有主分片可用

3.由于P1、P2的两个副本在另外两个节点中存活,因此新主Node接下来要做的第一件事情就是,在node1、node2剩下的两个节点的副本分片中,选出主分片,此时我们的集群恢状态恢复的黄色(所有主分片可用,非所有副本可用),推动副本分片成为主分片是瞬时的。

4.由于每个主分片应该有两个副分片,但是现在down掉一个节点。每个主分片目前只有一个副本,因此集群状态非green状态,但是此时并不需要担心,即使我们在下掉一个node,最后一个node节点上仍有所有的分片数据,因此集群会正常工作,并不会有数据丢失。

5.当我们恢复节点1、2时就是上一讲的水平扩容的过程

文档路由到正确分片

给定索引的文档,是如何存储到相应分片,并后续从正确分片中检索到的?
答案是:shard = hash(routing) % number_of_primary_shards

要索引到的分片= hash(routing) % 主分片数

routing 可以是任意的字符串,默认是文档的_id,也可以自定义文档的属性

因为是对主分片数量做的求余操作,因此这也就解释了为什么主分片的数量是创建索引的时候指定的,并不会再被更改。假如在某个时刻能被更改的化,则被索引的文档就相当于失效了。

写操作:创建、索引、删除请求

create、index、delete等写请求,必须在主分片执行成功后,才能复制到相关联的副本分片中,如果所示
ES相关分布式特性_第6张图片

1.客户端发起创建文档的请求到Node1
2.根据shard = hash(routing) % number_of_primary_shards 假设得到的分片是0,则Node1节点转发请求到Node3节点,因为该节点包含了分片为0的主分片
3.Node3在主分片P0上执行相应请求的操作,当操作成功后,并行转发请求到副本R0在的Node1和Node2节点,一旦所有分片返回执行成功,Node3会向协调节点Node1报告成功,Node1此时向客户端响应成功。
4.此时客户端端接收到成功请求,文档的变更请求在主分片和所有副本分片都执行成功。

有一系列的参数配置,可以影响这个执行过程,上诉过程中是所有副本分片都响应成功后,才返回给协调节点,进而返回处理成功响应给客户端。如果副本分片很多,则因为不同节点间的网络问题,性能开销也是比较大。因此可以通过调整一些参数,来改变这个复制过程。但是es官方文档不推荐修改这些参数,因为很少用到,且目前es已经非常快了。

这些参数的控制,其实就是在性能和一致性之间做trade off,也就是大家所属性的CAP理论,在分布式的网络分区过程中选CP还是AP的问题
es副本分片之间采用的是大多数分片可用,公式为:int( (primary + number_of_replicas) / 2 ) + 1。比如在再1主2副本的情况下,大多数为2
需要强调的一点是:number_of_replicas是在配置中的数字,而非目前正存活的副本数量
如果在节点之间存在超时问题,没有足够的大多数副本分片可用,集群会处于等待状态,默认等待时间是1分钟,可以通过参数个性化调整。

检索文档

查询、检索文档可以从主分片获取,也可以从副本分片获取,下图展示了获取流程
ES相关分布式特性_第7张图片

1.用户发送获取文档的请求到Node1节点
2.Node1节点执行shard = hash(routing) % number_of_primary_shards操作,假如算出在0分片,则Node1转发请求到另外两个节点到其中一个

有同学可能有疑问,既然在检索请求即可以在主分片上执行,也可以在副本分片上执行,为什么Node1节点还要转发到Node2节点的R0分片上去,这是因为ES定的规则,为了保障负载均衡,协调节点将会转发到不同的节点执行,使用的是轮训的算法。

后续将会继续对此文档的细节进行完善,并写一下分布式系统共识算法系列文章

你可能感兴趣的:(ES分布式特性,分布式,算法,java,es,elasticsearch)