ElasticSearch7学习笔记之分布式

文章目录

  • 背景
  • 分布式模型
    • 分布式架构
    • 结点
    • CoordinateNode
    • DataNode
    • MasterNode
      • MasterEligibleNodes
      • 选主流程
    • 集群状态ClusterState
    • 脑裂问题
      • 解决方法
  • 分片及其生命周期
    • 倒排索引的不可变性:
    • LuceneIndex
    • Refresh
    • TransactionLog
    • Flush
    • Merge
  • 分片与集群的故障转移
    • PrimaryShard(主分片)——提升系统存储容量
    • ReplicaShard(副本分片)——提高数据可用性
    • 分片数的设定
    • 故障转移
    • 集群健康状态
  • 文档的分布式存储

背景

本文记录分布式ES7的学习笔记,包括分布式模型、分片、文档的分布式存储等内容。

分布式模型

分布式架构

不同的集群通过不同的名字来区分,默认名字"elasticsearch",可以通过配置文件修改,或者在命令行中通过-E cluster.name=myName来设定

结点

一个结点就是一个Elasticsearch实例,本质是一个java进程。一台机器上可以运行多个es进程,但生产环境一般建议一台机器上就运行一个即可。

每一个结点都有名字,可以通过配置文件配置,或者命令行中通过-E node.name=myName来设定
每一个结点启动之后,都会分配一个uid,保存在data目录下

CoordinateNode

CoordinateNode是处理请求的结点,它负责把请求路由到正确的结点,比如创建索引的请求,需要路由到Master结点

所有结点默认都是CoordinateNode,通过将其他类型设置成False,使其成为DedicatedCoordinatingNode

DataNode

DataNode是可以保存数据的结点。负责保存分片数据,而MasterNode来决定如何把分片分发到数据结点上

结点启动后,默认就是数据结点,可以通过设置node.data:false来禁止

可以通过增加数据结点来解决数据水平扩展和数据单点问题

MasterNode

MasterNode负责处理创建、删除索引等请求,决定分片被分配到哪个结点,以及维护更新ClusterState

由于Master结点很重要,所以在部署上需要考虑单点问题,可以为一个集群设置多个Master结点,每个结点只承担Master的单一角色。

MasterEligibleNodes

一个集群支持配置多个MasterEligible结点,这些结点在必要时(比如Master结点故障、网络故障)参与选主流程,成为Master结点

每个结点启动后,默认就是一个MasterEligible结点,可以通过设置node.master:false来禁止。

选主流程

当集群内第一个MasterEligible结点启动时,他会将自己选举成为Master结点

需要进行选主流程时,MasterEligible结点会相互ping对方,NodeId低的将会成为被选举的结点。
其他结点会加入集群,但不承担Master结点。一旦发现被选中的主结点丢失,就会选举出新的主结点

集群状态ClusterState

集群状态信息维护了一个集群中必要的信息,比如所有的结点信息、所有的索引好其相关的Mapping与Setting信息、分片的路由信息

每个结点都会保存集群的状态信息,但只有Master结点才能修改集群状态信息,并同步给其他结点,否则将导致集群状态信息的不一致

脑裂问题

脑裂问题时分布式系统的经典网络问题,因为当网络出现问题,一个结点将和其它结点无法连接
ElasticSearch7学习笔记之分布式_第1张图片

举例如上图所示,node1的网络断开,那么node2和node3会重新选举一个主结点,但是node1自己还是一个主结点,并且更新集群状态。这样会导致有两个主结点,一旦网络恢复,就会出现冲突

解决方法

限定一个选举条件,设置quorum仲裁,只有在MasterEligible结点数大于quorum时,才能进行选举。
quorum = (master结点数 / 2) + 1,比如当有三个MasterEligible结点时,设置discovery.zen.minimum_master_nodes = 2,即可避免脑裂

但是从es7开始,就无需这个配置,可以让es自己选择能仲裁的结点。典型的主结点选举现在只需要很短的时间就能完成,集群的伸缩变得更安全、更容易,而且可能造成丢失数据的系统配置选型就更少了。结点更清楚地记录它们的状态,有助于诊断为什么它们不能加入集群或为什么无法选举出主结点。

分片及其生命周期

分片是es的最小工作单元,也是一个LuceneIndex

倒排索引的不可变性:

倒排索引是不可变的,可以带来如下好处:
1)、无须考虑并发
2)、一旦读入内核的文件系统缓存,就会留在那里。只要文件系统空间足够,大部分请求就会直接请求内存,不会命中磁盘,极大地提升了性能
3)、缓存容易生成和维护,数据可以被压缩
它也带来了挑战:如果要让一个新文档可以被检索,需要重建整个索引

LuceneIndex

在es的Lucene算法中,单个倒排索引文件被称为Segment。Segment是自包含且不可变更的,多个Segment汇总在一起就是Lucene的index,对应的就是es中的分片。
当有新文档写入时,会生成多个segment,查询时会同时查询所有的segment,并且对结果汇总。Lucene中有一个文件叫做CommitPoint,用来存放所有的segment信息。
被删除的文档信息,回报存在.del文件中

Refresh

es在写入文档时,会先把index写入到indexBuffer中,而将indexBuffer写入segment的过程叫做refresh,refresh不会之下fsync操作。
refresh的频率默认1秒一次,可通过index.refresh_interval来设置。refresh后文档就可以被搜索到了,这也是为什么es被称为近实时搜索。
如果系统有大量的数据写入,就会产生很多的segment。如果indexBuffer被占满,也会触发refresh,indexBuffer的默认大小是jvm堆内存的10%

TransactionLog

segment写入磁盘的过程相对耗时,refresh时会借助文件系统缓存,先将segment写入缓存以开放查询。
为了保证数据不丢失,es在索引文档时,同时写入TransactionLog,高版本开始,TransactionLog默认落盘。每个分片都有一个TransactionLog
es在refresh时,indexBuffer会清空,但TransactionLog不会

Flush

Flush过程如下:
1)、调用refresh,indexBuffer清空
2)、调用fsync,将缓存中的segment写入磁盘
3)、情况TransactionLog

触发时机:默认30分钟调用一次,或者TransactionLog满的时候(默认大小512MB)

Merge

Segment很多,所以需要定期合并,从而减少segment,并且删除已经删除的文档。

合并操作是es和lucene自动进行的,但我们可以通过POST my_index/_forcemerge来手动强制合并

分片与集群的故障转移

PrimaryShard(主分片)——提升系统存储容量

分片是es分布式存储的基石,分为主分片和副本分片

通过主分片,可以将数据分布在所有结点上。PrimaryShard可以将一份索引的数据分散在多个数据结点上,实现存储的水平扩展。主分片数在索引创建时指定,后续默认不能更改,除非重建索引

ReplicaShard(副本分片)——提高数据可用性

可以通过引入副本分片提高数据可用性。一旦主分片丢失,副本分片可以提升成主分片。副本分片数可以动态调整,每个结点上都有完备的数据。如果不设置副本分片,一旦出现结点硬件故障,就可能造成数据丢失

副本分片由主分片同步,通过增加副本个数,一定程度上可以提高读取的吞吐量。

分片数的设定

如果主分片过少,那么当该索引增长很快时,集群无法通过增加结点来实现对这个索引的数据扩展
如果主分片过多,会导致单个分片容量很小,从而引发一个结点上有过多分片,影响性能;也会导致搜索的相关性算分不准(所以数据量不大时,建议把主分片数量设置为1,或者在搜索后面加上search_type=dfs_query_then_fetch参数,但这样会影响性能)

副本分片过多,就会降低集群的整体写入性能

故障转移

以下图为例
ElasticSearch7学习笔记之分布式_第2张图片
集群由三个结点组成,包含一个索引tmdb,索引设置了三个主分片和一个副本。此时结点1是主结点,并且出现故障,集群重新选举结点2为主结点。由于主分片0丢失,那么结点3上的副本0提升为主分片0,集群变黄,因为分片0和1没有了副本。然后副本0和副本1分别分配给结点2和结点3,此时所有分片的主分片和副本都在不同的机器上,从而集群变绿。这个过程就是故障转移

集群健康状态

绿色:健康,所有的主分片和副本分片都可用
黄色:亚健康,所有主分片可用,部分副本分片不可用
红色:不健康,部分主分片不可用

文档的分布式存储

文档会存储在具体的某个主分片和副本分片上,例如文档1存储在P0和R0上

文档到分片的映射算法需要确保文档能均匀分布在所有分片上,充分利用硬件资源

潜在的算法有:
1、随机/轮询,当查询某个文档,如果分片数很多,需要多次查询才能查到这个文档
2、维护文档到分片的映射关系,但当文档数据量大的时候,维护成本会变高
3、实时计算:通过某个文档的id,自动算出需要去哪个分片上获取文档

文档到分片的路由算法:shard = hash(_routing) % number_of_primary_shards
哈希算法确保文档均匀分布在分片中,默认的_routing值是文档id,也可以自行设置。这个算法也是创建索引后,主分片数不能被随意更改的根本原因。

你可能感兴趣的:(ElasticSearch,分布式,elasticsearch,大数据)