ES 八月 13, 2024

分布式原理

文章字数 23k 阅读约需 21 mins. 阅读次数 0

分布式原理

单节点坏处

  • 服务性能受节点主机性能限制
  • 可用性差,主机或服务挂了就无法使用
  • 节点服务变更困难,若碰到需要重启服务才能生效的配置

分布式的优缺点

  • 高可用性:集群可容忍部分节点宕机而保持服务的可用性和数据的完整性
  • 易扩展:当集群的性能不满足业务要求时,可以方便快速的扩容集群,而无需停止服务。
  • 高性能:集群通过负载均衡器分摊并发请求压力,可以大大提高集群的吞吐能力和并发能力。

但相应的,由于节点的增加,维护难度相应提升.

es服务环境

配置

elasticsearch.yml中可配置项

关键配置

  • cluster.name: 集群名称,唯一确定一个集群。
  • node.name:节点名称,一个集群中的节点名称是唯一固定的,不同节点不能同名。
  • node.master: 主节点属性值
  • node.data: 数据节点属性值
  • network.host: 本节点的绑定ip,及提供服务的ip地址
  • http.port: 本节点的http端口
  • transport.port:9300——集群之间通信的端口,若不指定默认:9300
  • discovery.seed_hosts: 节点发现需要配置一些种子节点,与7.X之前老版本:disvoery.zen.ping.unicast.hosts类似,一般配置集群中的全部节点
  • cluster.initial_master_nodes:指定集群初次选举中用到的具有主节点资格的节点,称为集群引导,只在第一次形成集群时需要。

自定义配置

node.attr.{attribute}: value 自定义节点属性.可用于后续的索引分片分配配置. 可使用GET _cat/nodeattrs?v来查看节点属性.

配置方式
  • 通过编辑elasticsearch.yml 配置.

    node.attr.rack_id: rack_one
    
  • 通过在启动节点时使用命令’-E’设置参数.

    ./bin/elasticsearch -Enode.attr.rack_id=rack_one
    
索引级配置使用
  • index.routing.allocation.include.{attribute}:表示索引可以分配在包含多个值中其中一个的节点上。

  • index.routing.allocation.require.{attribute}:表示索引要分配在包含索引指定值的节点上(通常一般设置一个值)。

  • index.routing.allocation.exclude.{attribute}:表示索引只能分配在不包含所有指定值的节点上。

    eg: 将kong_v2索引只分配到node4与node5上.

    PUT kong_v2
    {
      "settings": {
        "number_of_shards": 3,
        "number_of_replicas": 1,
        "index.routing.allocation.include._name": "node4,node5"
      }
    }
    
集群级配置使用

elasticsearch修改集群范围设置提供两种方式,

  • persistent:永久性修改,persistent相关的修改保存在了/path.data/cluster.name/nodes/0/_state/global-n.st,如果想删除设置,删除此文件即可。
  • transient:集群重启后失效。

使用参数

  • cluster.routing.allocation.include.{attribute}: 将分片分配给至少具有 逗号分隔的值。

  • cluster.routing.allocation.require.{attribute}: 仅将分片分配给具有所有 逗号分隔的值。

  • cluster.routing.allocation.exclude.{attribute}: 不要将分片分配给具有任何 逗号分隔的值。

  • cluster.routing.allocation.awareness.attributes: 强制指定感知属性

PUT _cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.awareness.attributes": "rack_id" // 设置感知属性为`rack_id`
  }
}

两种模式:开发模式与生产模式

  • 开发模式(单节点模式): 开发模式是默认配置(未配置集群发现设置),如果用户只是出于学习目的,而引导检查会把很多用户挡在门外,所以ES提供了一个设置项discovery.type=single-node。此项配置为指定节点为单节点发现以绕过引导检查。

    单节点部署方式

  • 生产模式(集群模式): 当用户修改了有关集群的相关配置会触发生产模式,在生产模式下,服务启动会触发ES的引导检查或者叫启动检查(bootstrap checks),所谓引导检查就是在服务启动之前对一些重要的配置项进行检查,检查其配置值是否是合理的。引导检查包括对JVM大小、内存锁、虚拟内存、最大线程数、集群发现相关配置等相关的检查,如果某一项或者几项的配置不合理,ES会拒绝启动服务,并且在开发模式下的某些警告信息会升级成错误信息输出。引导检查十分严格,之所以宁可拒绝服务也要阻止用户启动服务是为了防止用户在对ES的基本使用不了解的前提下启动服务而导致的后期性能问题无法解决或者解决起来很麻烦。因为一旦服务以某种不合理的配置启动,时间久了之后可能会产生较大的性能问题,但此时集群已经变得难以维护,ES为了避免这种情况而做出了引导检查的设置。这种设定虽然增加了用户的使用门槛,但是避免了日后产生更大的问题.

    多节点分布式部署方式

主从架构

Elasticsearch为什么使用主从模式(Leader/Follower)?Elasticsearch使用的主从架构模式,其实除此之外,还可以使用分布式哈希表(DHT),其区别在于:

  • 主从模式适合节点数量不多,并且节点的状态改变(加入集群或者离开集群)不频繁的情况。
  • 分布式哈希表支持每小时数千个节点的加入或离开,响应约为4-10跳。

ES的应用场景一般来说单个集群中一般不会有太多节点(一般来说不超过一千个),节点的数量远远小于单个节点(只的是主节点)所能维护的连接数。并且通常主节点不必经常处理节点的加入和离开,处于相对稳定的对等网络中,因此使用主从模式。

ES节点分类

候选节点(role=master)

master节点是那些在集群状态发布期间参与选举并执行某些任务的节点,配置了master角色的节点都是有效的投票节点,可以参与选举也可以投票.

硬件要求: 高CPU,高内存,高网络,低存储

仅投票节点(role=master,voting_only)

​ 配置了master和voting_only角色的节点将成为仅投票节点,仅投票节点虽然也是候选节点,但是在选举过程中仅可以投票而不参与竞选。不过仅投票节点可以同时也是数据节点,这样的话,其不具备被选举为Master的资格,但是参与投票,可以在选举过程中发挥关键票的作用。常常作用在需要平衡票数或防止脑裂.

职责:

  • 当现有票数不足以选出Master的时候,充当决胜票。
  • 在小型集群中仅投票节点可同时作为数据节点避免资源浪费

硬件要求: 高CPU,低内存,高网络,低存储

主节点[active master]

​ 主节点是从候选节点中选举得出,任何不是voting-onlymaster节点都可以被选举为active master.

职责:

  • 创建或删除索引
  • 规划和执行分片策略
  • 发布、修改集群状态

要求:

  • 避免重负载:主节点负责轻量级集群范围的操作,例如创建或删除索引、跟踪哪些节点是集群的一部分以及决定将哪些分片分配给哪些节点。拥有一个稳定的主节点对于集群健康很重要。当选的主节点拥有履行其职责所需的资源,这对于集群的健康非常重要。如果所选的主节点承载了其他任务,那么集群将不能很好地运行。避免 master 被其他任务超载的最可靠方法是将所有符合 master 的节点配置为仅具有 master 角色的专用 master 节点,使它们能够专注于管理集群。专用master节点仍将充当协调节点,将请求从客户端路由到集群中的其他节点,但是不要以负载均衡器的目的而设置候选节点.
  • 持久化集群元数据: 主节点必须有一个path.data目录,其内容在重启后仍然存在,就像数据节点一样,因为这是存储集群元数据的地方。集群元数据描述了如何读取存储在数据节点上的数据,因此如果丢失,则无法读取存储在数据节点上的数据。
  • 高可用性 (HA): 集群需要至少三个候选节点,其中至少两个不是仅投票节点。这样即使其中一个节点发生故障,也可以保证剩下的节点能够选举出一个主节点。

硬件要求: 高CPU,高内存,高网络,低存储.

数据节点(role=data)

数据节点保存包含已编入索引的文档的分片。数据节点处理数据相关操作,如 CRUD、搜索和聚合。这些操作是 I/O 密集型、内存密集型和 CPU 密集型的。

硬件要求: 高CPU,高内存,高网络,高且快存储.

ES模块

Cluster

Cluster模块是Master节点执行集群管理的封装实现,管理集群状态,维护集群级(除了集群级,还有索引级分片级等级别)的配置信息。其主要功能包括:

  • 管理集群状态,将新生成的集群状态发布到集群的所有节点
  • 调用allocation模块执行分片分配感知,决策分片分配行为
  • 在集群各个节点直接迁移分片,保证数据平衡,shard rebalance

Allocation

此模块是实现了对节点分片的分配感知策略,新节点加入离开、动态扩容都需要分片分配感知,此模块由主节点调用,常见的使用场景如:跨机架强制感知实现高可用,冷热集群架构设计等。

Bootstrap

引导检查模块,

检查项:

  • 堆大小检查
  • 文件描述符检查
  • 内存锁检查
  • 最大线程数检查
  • 最大文件大小检查
  • 虚拟内存检查
  • 文件系统映射数检查
  • 客户端JVM检查
  • 串行收集器检查
  • 系统调用过滤器检查
  • OnError和OnOOMError检查
  • 早期访问检查
  • 所有权限检查
  • 发现配置检查

Ingest

预处理模块负责数据索引之前的一些预操作,比如数据类型处理、数据的结构转换等,很多场景下课替代logstash处理管道消息,Elastic认证考试考点之一。

Monitor

监控功能提供了一种方式来了解 Elasticsearch 集群的运行状况和性能

Discovery

发现模块负责管理如发现集群中新加入的节点,或者节点退出之后将状态信息移除,起作用类似于ZooKeeper。发现木块是用于elasticsearch和的内置发现模块 默认值。它提供单播发现,但可以扩展到 支持云环境和其他形式的发现

Gateway

负责说对收到Master广播下来的集群状态数据的持久化存储,并在集群完全重启时恢复他们

Indices

索引模块管理全局级索引配置,不包括索引级及索引以下级。集群启动阶段需要主副本分片恢复就是在这个模块完成的

HTTP

HTTP模块允许通过JSON over HTTP的方式访问ES的API,HTTP模块本质上是完全异步的,这一位置没有阻塞线程等待响应。使用异步通信进行HTTP的好处是解决了C10k的问题。

Transport

传输模块用于集群内部节点通信。传输模块使用TCP协议,每个节点都与其他节点维持若干个TCP长连接,通信本质也是完全异步的。

分片(shard)

Shard即数据分片,是ES的数据载体。在ES中数据分为primary shard(主分片)和replica shard(副本分片):

  • primary承载单个索引的一部分数据,分布于各个节点,
  • replica为某个primary的副本,即备份。

分片分配的原则是尽量均匀的分配在集群中的各个节点,以最大程度降低部分shard在出现意外时对整个集群乃至服务造成的影响。

分片创建策略

ES使用数据分片(shard)来提高服务的可用性,将数据分散保存在不同的节点上以降低当单个节点发生故障时对数据完整性的影响,同时使用副本(repiica)来保证数据的完整性。关于分片的默认分配策略,在7.x之前,默认5个primary shard,每个primary shard默认分配一个replica,即5主1副,而7.x之后,默认1主1副.

  • ES在分配单个索引的分片时会将每个分片尽可能分配到更多的节点上。
  • Paimary只能在索引创建时配置数量,而replica可以在任何时间分配,并且primary支持读和写操作,而replica只支持客户端的读取操作,数据由es自动管理,从primary同步。
  • ES不允许Primary和它的Replica放在同一个节点中,并且同一个节点不接受完全相同的两个Replica
  • 同一个节点允许多个索引的分片同时存在。

eg: 在3master,3data的集群中创建了一个分片为5,副本为2的索引kong_v1. es会尽可能的平衡分片的位置.

索引分区

创建时分片数量建议

  • 避免分片过多:大多数搜索会命中多个分片。每个分片在单个 CPU 线程上运行搜索。虽然分片可以运行多个并发搜索,但跨大量分片的搜索会耗尽节点的搜索线程池。这会导致低吞吐量和缓慢的搜索速度。
  • 分片越少越好:每个分片都使用内存和 CPU 资源。在大多数情况下,一小组大分片比许多小分片使用更少的资源。
  • 分片的合理容量: 10GB-50GB。在索引的生命周期管理中,一般设置50GB为单个索引的最大阈值。
  • 堆内存容量和分片数量的关联:小于20分片/每GB堆内存,一个节点可以容纳的分片数量与节点的堆内存成正比。GET _cat/nodes?v=true&h=heap.current 可以通过该命令查询节点的堆内存情况.
  • 避免重负载节点:如果分配给特定节点的分片过多,会造成当前节点为重负载节点

索引分片分配:Index Shard Allocation

分片均衡策略:shard rebalance

​ Elasticsearch 运行一个称为rebalancing 的自动过程,它在集群中的节点之间移动分片以改善其平衡。重新平衡遵循所有其他分片分配规则,例如分配过滤强制意识,这可能会阻止它完全平衡集群。

cluster.routing.rebalance.enable

(动态) 为特定类型的分片启用或禁用重新平衡:

  • all -(默认)允许对所有类型的分片进行分片平衡。
  • primaries - 只允许主分片的分片平衡。
  • replicas - 仅允许对副本分片进行分片平衡。
  • none - 任何索引都不允许进行任何类型的分片平衡。
PUT _cluster/settings
{
    "transient": {
        "cluster.routing.rebalance.enable": "all"
    }
}

cluster.routing.allocation.allow_rebalance

(动态) 指定何时允许分片重新平衡:

  • always - 始终允许重新平衡。
  • indices_primaries_active - 仅当集群中的所有主节点都已分配时。
  • indices_all_active -(默认)仅当集群中的所有分片(主分片和副本)都被分配时。
PUT _cluster/settings
{
    "transient": {
        "cluster.routing.allocation.allow_rebalance": "always",
        -- 执行分片重新平衡的并发数 默认是2.
        "cluster.routing.allocation.cluster_concurrent_rebalance": "2"
    }
}
分片平衡规则
  • cluster.routing.allocation.balance.shard:(动态)定义节点上分配的分片总数的权重因子(浮点数)。默认为0.45f.提高数值会增加集群节点中分片数量相等的趋势.

  • cluster.routing.allocation.balance.index: (动态)定义分配在特定节点(浮点数)上的每个索引的分片数的权重因子。默认为0.55f. 提高数值会增加集群节点中,每个索引的分片数量相等趋势.

  • cluster.routing.allocation.balance.threshold: (动态)应该执行的操作的最小优化值(非负浮点)。默认为1.0f. 提高数值集群在优化分片平衡方面不那么积极.

    与磁盘相关的规则

    当磁盘空间倾斜的时候,es需要自动调整。

    • cluster.routing.allocation.disk.threshold_enabled: (动态)默认为true。设置为false禁用磁盘分配决定器。

    • cluster.routing.allocation.disk.watermark.low: (动态)控制磁盘使用的低水位线。默认为0.85,这意味着 Elasticsearch 不会将分片分配给磁盘使用率超过 85% 的节点。也可用具体的存储大小指定,比如:500mb,100gb. 此参数对主分片无效.只对副本产生作用

    • cluster.routing.allocation.disk.watermark.high: (动态)控制高水位线。它默认为0.9,这意味着 Elasticsearch 将尝试将分片从磁盘使用率高于 90% 的节点,开始挪分片去其他节点。

    • cluster.routing.allocation.disk.watermark.flood_stage: (动态)控制洪峰水位线。它默认为0.95.当索引中有一块磁盘的超过洪峰线.索引将被锁定,只接受读取与删除请求,拒绝插入与更新请求. 被锁定的索引会被index.blocks.read_only_allow_delete:true 标记.

      -- 取消read_only标记,使索引恢复新增能力.
      PUT kong_v2/_settings
      {
        "index.blocks.read_only_allow_delete":null
      }
      
    • cluster.info.update.interval:(动态)Elasticsearch 应该多久检查一次集群中每个节点的磁盘使用情况。默认为30s.

延迟分配策略(默认1m)

当节点出于任何原因(有意或无意)离开集群时,主节点会做出以下反应

  • 将副本分片提升为主分片以替换节点上的任何主分片。
  • 分配副本分片以替换丢失的副本(假设有足够的节点)。
  • 在其余节点之间均匀地重新平衡分片。

这些操作旨在通过确保尽快完全复制每个分片来保护集群免受数据丢失。即使我们在节点级别集群级别限制并发恢复 ,这种“分片洗牌”仍然会给集群带来很多额外的负载,如果丢失的节点可能很快就会返回,这可能是不必要的.

分片过滤: Shard allocation filtering

控制分片存在节点的位置

  • index.routing.allocation.include.{attribute}:表示索引可以分配在包含多个值中其中一个的至少节点上。
  • index.routing.allocation.require.{attribute}:表示索引要分配在包含索引指定值的节点上(通常一般设置一个值)。
  • index.routing.allocation.exclude.{attribute}:表示索引只能分配在不包含所有指定值的节点上。
PUT kong_v2
{
  "settings": {
    "number_of_shards": 3,
    "number_of_replicas": 1,
    "index.routing.allocation.include._name": "node4,node5"
  }
}

分片过滤

分片分配感知: Shard Allocation Awareness

​ 通过自定义节点属性作为感知属性,让 Elasticsearch 在分配分片时将物理硬件配置考虑在内。如果 Elasticsearch 知道哪些节点位于同一物理服务器上、同一机架中或同一区域中,则它可以分离主副本分片,以最大程度地降低在发生故障时丢失数据的风险。

eg:

  1. 在节点中设置自定义属性.rack_id: rack_one
node.attr.rack_id: rack_one
  1. 在创建索引前设置集群配置使用rack_id这个自定义参数.
PUT _cluster/settings
{
  "persistent": {
    "cluster.routing.allocation.awareness.attributes": "rack_id"
  }
}

强制感知策略:Forced awareness

​ 默认情况下,如果一个区域发生故障,Elasticsearch 会将所有故障的副本分片分配给其他区域。但是剩余区域可能没有足够的性能冗余来承载这些分片。

为了防止在发生故障时单个位置过载,可以配置强制感知策略来影像副本分片的分配位置.

eg:

PUT _cluster/settings
{
  "persistent": {
      "cluster.routing.allocation.awareness.attributes": "zone",
      "cluster.routing.allocation.awareness.force.zone.values":"zone1,zone2"
  }
}

高可用性

​ 高可用性即:High Availability(HA),高可用性是分布式系统架构设计的重要因素之一,简单来说,可用性越高的集群在发生意外情况(如断电、节点宕机)的时候,服务发生故障而不可用的可能性越低,也就是降低了意外情况而对整体服务产生的影响的可能性.

原理

  • 通过“分布式”的概念实现多个节点的负载均衡,并且使服务具备可扩展能力。
  • 通过针对分片、节点的一列策略降低单个故障点对整体服务产生的影响。
  • 通过容灾机制,尽可能把故障点还原,以恢复服务的最大可用性。

容灾机制

​ 容错性可以理解系统容忍的局部发生异常情况的比率和当异常发生时自行恢复的能力。在ES中表现为对节点宕机的处理机制。

步骤:

  1. Master选举:选出集群中的Leader。
  2. Replica容错:新的Active Master会将丢失的Primary的某个Replica提升为Primary。
  3. 尝试恢复故障节点:Master尝试恢复故障节点。
  4. 数据同步:Master将宕机期间丢失的数据同步到重启节点对应的分片上去,从而使服务恢复正常。

高可用性集群

​ 高可用性的中心思想就是采取一切可能的策略,降低集群中任意一部分节点出现问题后导致服务整体不可用的概率。其包含数据的完整性,集群的存活概率以及选主等。

两节点集群

  • 如果出于硬件成本考虑,集群中只允许有两个节点,那么一般来说最好把两个节点都设置成数据节点。您还应该通过设置索引确保每个分片都在两个节点上冗余存储。每个非可搜索快照索引上的Number_of_replicas为1。这是默认行为,但可能会被索引模板覆盖。Auto-expand replicas也可以达到同样的效果,但是在这么小的集群中没有必要使用这个功能。
  • 推荐在两个节点之一设置node.master: false明确告知其不具备候选节点资格。目的是为了确定哪个节点是主节点。集群可以容忍另一个不具备候选资格的节点的丢失。如果不做此设置,这时两个节点都会具有候选资格,但是其中一个节点如果宕机,由于选主需要票数过半(票数>N/2+1),也就是票数必须是两票才能选出active master,所以会导致无法选主。此时集群无法容忍任何一个节点宕机
  • 默认情况下,ES会为每个节点分配所有角色,如果手动分配角色,一般建议为每个节点分配所有角色,如果其中一个节点宕机,另一个节点可以取而代之。

三节点集群 <HA的最低配置>

  • 三节点部署:如果整个集群中所有节点一共只有三个,建议把三个节点全部部署为数据节点和候选节点。虽然active master节点一般只负责轻量级任务不做数据节点。但是通常来说三节点集群一般不会承载很大的业务量,也就不必考虑那么多了。这也是处于成本考虑不得已而为之。三节点集群的容错能力是1,即允许一台节点故障。
  • 二加一部署:即两个候选节点,一个仅投票节点,若干数据节点。这种配置的最大好处就是在保证高可用的前提下性价比更高,适用于小规模集群。由于在避免脑裂的前提下,要选举出主节点的最小节点数量是3,也就是选主的必要条件是票数过半也就是2票。而候选节点一般是不负责其他的任务的,也就不会为其分配data角色,那么集群通常会出现三个节点不存放数据的局面。此时会产生造成资源浪费。因为active master只存在一个,另外两个master作为候选节点,在及群众仅仅是充当了负载均衡器。为了避免这种资源浪费,通常的做法是把其中一个候选节点设置为仅投票节点,即node.roles: [ data, master, voting_only ],此时,当前节点在选举过程中,仅有选举权而没有被选举权,这样就可以同时给他分配数据节点的角色,因为其不会被选举为active master。三节点集群中,三个节点必须都具有master角色,并且仅投票节点最多只能有一个。仅投票节点由叫仲裁节点起着决胜票的作用。

多节点集群

​ 一旦集群增长到三个以上的节点,可以开始根据它们的职责对这些节点做职责专一化。主要根据需要配置尽可能多的数据节点预处理节点机器学习节点等来均衡工作负载。随着集群变大,一般建议给每个角色使用专用节点,以便为每个任务独立扩展资源。

​ 但是,最好将集群中候选节点数量限制为三个。主节点不像其他节点类型那样扩展,因为集群总是只选择其中之一作为集群的主节点。如果有太多候选节点,那么主选举可能需要更长的时间才能完成。在较大的集群中,一般建议把候选节点设置为专用候选节点,即不分配其他角色,并避免向这些专用节点发送任何客户端请求。以免候选节点被不必要的额外工作所拖累导致集群服务不稳定。

​ 但是可以把候选节点之一配置为仅投票节点以便它永远不会被选为主节点。例如,集群可能有两个专用的候选节点和一个既是数据节点又是仅投票的候选节点的第三个节点。这第三个仅投票节点将在Master选举中投出决胜票,但是自己永远不会被选举为active master。

大规模单集群

  • 避免跨数据中心:ES对网络和宽带要求较高,并且一般来说要尽量避免服务跨多个数据中心。因为一旦遇到分区恢复问题,它必须重新同步任何丢失的数据并重新平衡集群。如果一定要跨多个数据中心,建议在每个数据中心部署独立集群,然后配置跨集群搜索跨集群复制
  • 部署分片分配感知:为了降低当集群出现单个或区域节点(比如一个机架)宕机对整个服务造成的影响,一般策略是通过分配感知来实现

双区集群

  • 如果集群部署在两个区域比如两个机房内,应该在每个区域中拥有不同数量的候选节点,这样在其中一个区域出现问题的时候,会增加另一个区域的存活概率。比如两个机房部署同一个集群,那么两个机房的候选节点避免相等,因为此时如果一个机房意外断电,两个机房的服务都会停止。配置单数投票节点可避免此问题。此时其中一个机房断电,服务可用的概率为50%。
  • 双区集群理论上能容忍一个区域的数据丢失,但不是任意一个区域,打个比方:服务部署在两个机房,机房A和机房B,要么是仅允许A机房出现故障而不允许B机房出现故障,也就是A机房断电服务可用,但是B机房断电服务中断;要么是仅允许B机房出现故障而不允许A机房出现故障,也就是B机房断电服务可用,但是A机房断电服务中断。从高可用的角度想,我们更希望任意一个机房断电,另一个机房的服务都不受影响,但是这是不可能的。因为没有断电的机房不知道出现故障的机房是断网了还是断电了,也就不知道应该是发起独立选举还是等待下去。如果两个机房都可以独立选主,那么就无法避免脑裂,可能会产生两个机房选出active master。解决办法是在两个区域中都配置一个仅投票节点并在独立的第三个区域添加一个额外的候选节点。这样两个区域其中之一断电,额外的投票节点就可以投出关键票。这个额外的节点也叫专用tiebreaker节点,此节点可以用低配服务器。

多区集群

​ 如果集群中有三个区域,那么每个区域中应该有一个候选节点。如果集群包含三个以上的区域,那么应该选择其中的三个区域,并在这三个区域中的每一个区域中放置一个候选节点。这意味着即使其中一个区域发生故障,集群仍然可以选举主节点。

多集群

​ Elasticsearch是主从结构,主节点能管理的节点上线一般不超过一千个,如果继续增加节点,可能会导致active master不稳定,如果集群想突破集群规模带来的性能瓶颈,一般可配置多集群,利用跨集群搜索单个超大集群拆分成多个小集群(相对小,千节点级别)来完成对集群的性能扩展。

总结

  • 集群应该至少有两个区域包含数据节点。
  • 除了主分片之外,每个 不是可搜索快照索引的索引都应该有每个主分片的至少一个副本。
  • 分片分配感知配置为避免将分片的所有副本集中在单个区域内。
  • 集群至少有三个候选节点。这些节点中至少有两个不是仅投票节点,均衡分配在至少三个区域中。
  • 客户端被配置为将其请求发送到多个区域中的节点,或者被配置为使用负载平衡器来平衡一组适当的节点之间的请求。

Master选举

中心思想

所有分布式系统都需要解决数据的一致性问题,处理这种问题一般都两种策略:

  • 避免发生数据不一致性问题.
  • 发生了数据不一致性问题后的处理策略.

ES的选举算法

  • Bully:Bully是Leader选举的基本算法之一,基本原理就是按照节点ID进行排序,任何时候当前Leader的节点ID都是集群中最高节点ID。该算法非常易于实现但是当Leader处于不稳定状态的时候,如因负载过重而假死,此时可能会触发选主,选出第二大ID的节点为新的Leader。ES通过推迟选举直到Master失效(Master放弃Active Master资格触发选举)来解决问题,但是会产生双主或多主(也就是脑裂)问题。

  • Paxos:Paxos非常强大,在选举方面的灵活性比Bully算法有很大的优势,但是其原理非常复杂。

  • Raft:Raft是一种使用较为广泛的分布式一致性的协议,在Raft中,节点可能的状态有三种:

    • Leader:主节点
    • Candidate:候选节点
    • Follower:跟随节点

    ​ 所有的节点开始都是跟随节点。如果跟随节点收不到领导节点的信号,则他们可以成为候选节点候选节点接着请求其他节点投票节点将以他们的投票回复候选节点如果候选节点获取到大多数节点的投票,则他将会成为领导节点此过程称为Leader选举。

0%