Elasticsearch 分布式特性(集群、节点、分片)

一、es 分布式特性

es 支持集群模式,是一个分布式系统,其好处有两个:

  • 增大系统容量,如内存、磁盘,使得 es 集群可以支持 PB 级的数据
  • 提高系统可用性,即使部分节点停止服务,整个集群依然可以正常运行

es 集群由多个 es 实例组成

  • 不同集群通过集群名字来区分,可通过 cluster.name 进行修改,默认为 elasticsearch
  • 每个 es 实例本质是一个 JVM 进程,且有自己的名字,通过 node.name 进行修改

二、集群和节点

启动一个节点
bin/elasticsearch -E cluster.name=my_cluster -E node.name=node1
Cluster State

es 集群相关的数据称为 cluster state,主要记录如下信息:

  • 节点信息,比如节点名称、连接地址等
  • 索引信息,比如索引名称、配置等
Master Node
  • 可以修改 cluster state 的节点成为 master 节点,一个集群只能有一个
  • cluster state 存储在每个节点上,master 维护最新版本并同步给其他节点
  • master 节点是通过集群中所有节点选举产生的,可以被选举的节点称为 master-eligible 节点,相关配置是: node.master:true
Coordinating Node

处理请求的节点即为 coordinating 节点,该节点为所有节点的默认角色,不能取消。路由请求到正确的节点处理,比如创建索引的请求到 master 节点

Data Node

存储数据的节点即为 data 节点,默认节点都是 data 类型,相关配置:node.data:true

单点问题

如果集群只有一个节点,那么唯一的节点停止服务,集群也将停止服务

新增节点

运行如下命令可以启动一个 es 节点实例:

bin/elasticsearch -E cluster.name=my_cluster -E node.name=node2
提高系统可用性

1)服务可用性

  • 2 个节点的情况下,允许其中 1 个节点停止服务

2)数据可用性

  • 引入副本(Replication)解决
  • 每个节点都有完备的数据
增大系统容量

如何将数据分布于所有节点上?

  • 引入分片(Shard)解决问题

分片是 es 支持 PB 级数据的基石

  • 分片存储了部分数据,可以分布于任意节点上
  • 分片数在索引创建时指定,且后续不允许更改,默认为 5 个
  • 分片由主分片和副本分片之分,以实现数据的高可用
  • 副本分片的数据由主分片同步,可以有多个,从而提高读取的吞吐量

三、分片

以下演示 3 个节点的集群中 test_index 的分片分布情况,创建时我们指定了 3 个分片和 1 个副本

PUT test_index
{
  "setting":{
    "number_of_shards":3,
    "number_of_replicas":1
  }
}

关于上图有两个问题需要注意:

  • 此时增加节点是否能提高 test_index 的数据容量?

答案是不能的,因为只有 3 个分片,已经分布在 3 台节点上,新增的节点无法利用

  • 此时增加副本数是否能提高 test_index 的读取吞吐量?

答案也是不能的,因为新增的副本也是分布在这三个节点上,如下图所示,还是利用了同样的资源。如果要增加吞吐量,还要新增节点。

分片数的设定很重要,需要提前规划好,过小会导致后续无法通过增加节点实现水平扩容。过大会导致一个节点上分布过多分片,造成资源浪费,同时会影响查询性能

Cluster Health

通过如下 API 可以查看集群健康状况,包括一下三种:

  • green:健康状态,指所有主副分片都正常分配
  • yellow:指所有主分片,都正常分配,但是有副本分片未正常分配
  • red:有主分片未分配
故障转移

如下图集群有 3 个节点组成,此时集群状态是 green

突然 node1(master)所在机器宕机导致服务终止,此时集群会如何处理?

  • Node2 和 node3 发现 node1 无法响应一段时间后发起 master 选举,比如这里选择 node2 为 master 节点。此时由于主分片 P0 下线,集群状态转变为 Red。
  • node2 发现主分片 P0 未分配,将副本分片 R0 提升为主分片。此时由于所有主分片都正常分配,集群状态变为 yellow。
  • node2 为 P0 和 P1 生成新的副本,集群状态恢复为绿色

四、文档分布式存储

文档最终会存储在分片上,如下图所示:

PUT test_index/doc/1
{
  "title":"seina gao",
  "desc":"nothing here"
}  

doc1 最后存储在 P1 分片上

那么 doc1 是如何存储到分片 P1 的?选择 P1 的依据是什么?

需要文档到分片的映射,目的是使得文档均匀分布在所有分片上,以充分利用资源。

1)比如常见的随机选择还是 round-robin 轮训算法呢,显然是不可取的,存储的时候把 doc1 存到 P1 了,读取的时候需要一个地方来维护文档到分片的映射关系,大家都知道 es 是海量数据存储文档,比如有上亿个文档,那么维护成本巨大

2)根据文档值实时计算对应的分片,es 通过如下公式计算文档对应的分片

  • shard = hash(routing) % number_of_primary_shards
  • hash 算法保证可以将数据均匀地分散在分片中
  • routing 是一个关键参数,默认是文档 id,也可以自行指定
  • number_of_primary_shards 是主分片数

该算法与主分片数相关,这也是分片数一旦确定之后便不能更改的原因

文档创建的流程
  1. 用户像 node3 发起创建文档的请求
  2. node3 通过routing 机算该文档应该存储在 Shard1 上,查询 cluster state 后确认主分片 P1 在 node 2 上,然后转发创建文档的请求到 node2
  3. P1 接收并执行创建文档请求后,将同样的请求发送到副本分片 R1
  4. R1 接受并执行创建文档请求后,通知 P1 成功的结果
  5. P1 接收副本分片结果后,通知 node3 创建成功
  6. node3 返回结果给用户
文档读取的流程
  1. 用户向 node3 发起获取文档 1 的请求
  2. node3 通过 routing 计算该文档在 Shard1 上,查询 cluster state 后获取 Shard1 的主副分片列表,然后以轮询的机制获取一个 Shard,比如这里是 R1,然后转发读取文档的请求到 node1
  3. R1 接收并执行读取文档请求后,将结果返回 node3
  4. Node3 返回结果给用户
倒排索引的不可变更

倒排索引一旦生成,不能更改,其好处如下:

  • 不用考虑并发写文件的问题,杜绝了锁机制带来的性能问题
  • 由于文件不再更改,可以充分利用文件系统缓存,只需载入一次,只要内存足够,对该文件的读取都会从内存读取,性能高
  • 利于对文件进行压缩存储,节省磁盘和内存存储空间

坏处是需要写入新文档时,必须重新构建倒排索引文件,然后替换老文件,新文档才能被检索,导致文档实时性差。解决办法就是新文档直接生成新的倒排索引文件,查询的时候同时查询所有的倒排文件,然后做结果的汇总计算即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值