ES入门篇4--核心机制

1,234 阅读8分钟

1.分片机制

primary shard不能和自己的replica shard放在同一个节点上

创建index,并指定shards和relicas都为4

PUT /test_index
{
   "settings" : {
      "number_of_shards" : 4,
      "number_of_replicas" : 4
   }
}

如果此时有4台机器,总分片数量为16,分片机制表现为:

创建index,并指定shards为3,replicas为2

PUT /test_index2
{
   "settings" : {
      "number_of_shards" : 3,
      "number_of_replicas" : 2
   }
}

分片机制表现为:

1.1 分片机制特性

  1. Elasticsearch隐藏了复杂的分片机制,开发人员不用关心数据分配到哪个shard中,只需要关心document插入和搜索。
  2. cluster discovery:集群发现机制。ES入门篇4中,index的status从yellow转green的实验里,启动第二个es节点,这个节点会自动加入集群中,作为replica同步shard的所有document)
  3. shard负载均衡(举例,假设现在有3个node,总共有6个shard要分配到3个节点上去,es会自动进行均匀分配,以保持每个节点的均衡的读写负载请求)
  4. 请求路由:例如上图中的3 shard 、2 replica,当请求ElasticSearch--01的document时,发现数据落到shard 3,这时ElasticSearch--01节点会根据负载均衡去ElasticSea rch--02或ElasticSearch--03取数据返回给客户端。
  5. reblance:shard重分配,当集群扩容时ES会自动把shard、replica从现有的node移动到后面加入集群的node,以保证shard、replica分配均匀。

2. Elasticsearch的垂直扩容与水平扩容

2.1. 垂直扩容

使用更强大的服务器替换老服务器或者给服务器增加内存、硬盘空间、换SSD等硬件。

优点:

扩展简单,用户量不大的公司可快速解决性能瓶颈

缺点:

成本高昂,对于用户量增长快的公司来说很快就会面临下一次性能瓶颈。当面临下一次性能瓶颈的时候还得买更强大的服务器。性能越强服务器价格呈指数增长,性价比非常低。

2.2 水平扩容

多采购几台性能一般的服务器,但是很多普通服务器组织在一起,就能构成强大的计算和存储能力。这是业界采用比较多的方案

PS:增减或减少节点时shard会rebalance

优点:

扩容了之后shard会rebalance,每个节点上的shard数量会变少,这样就会每个shard能使用的内存、磁盘空间更大,整个系统性能会更好

缺点:

集群机器越多维护成本越高、管理起来更难

3. shard&replica机制

  1. index会被分配到多个shard/replica中
  2. 每个shard/replica都是最小工作单元(lucene实例),保存着部分index数据,拥有完整的能力(例如建立索引、查询索引、删除索引、删除索引)
  3. 增减节点时,ES会rebalance,使shard在nodes中负载均衡
  4. primary shard和replica shard,一个document只能存在于一个primary shard不能存在于多个primary shard中。假如primary shard有n个对应的replica shard,那么这个document会复制到n个replica shard中。
  5. replica shard是primary shard的副本,负责容错,以及承担读请求负载
  6. primary shard的数量在创建索引的时候就固定了,replica shard的数量可以随时修改
  7. primary shard的默认数量是5,replica默认是1,默认有10个shard,5个primary shard,5个replica shard
  8. primary shard不能和自己的replica shard放在同一个节点上(否则节点宕机,primary shard和副本都丢失,起不到容错的作用),但是可以和其他primary shard的replica shard放在同一个节点上
  9. index在建立的时候就已经指定了shard、replica的数量(自定义shard数量第三章有介绍),shard的数量一旦确定了就不能更改,replica数量可以随意扩容。

4. 容灾机制

(4 shard、4 replica)场景

ElasticSearch--01挂了:

自动容灾:

ElasticSearch--01恢复后:

如上图所示ElasticSearch--01挂了,ES是怎么自动容灾的呢?

  1. primary shard 1这个主shard挂了,需要从与之对应的剩余replica shard 1中选出一个变成primary shard 1。此时index的集群状态为yellow
  2. ElasticSearch--02、ElasticSearch--03、ElasticSearch--04会进行master竞选,通过分布式一致性算法选出一个master负责执行。(如果ElasticSearch--01不是master则不用选举,直接跳到第三步)假设选的是ElasticSearch--02
  3. master选出一个最合适(数据丢失最少)的replica shard 1并把它切换成replica shard 1。假设选的是ElasticSearch--03
  4. 新的replica shard 1把数据同步到其他的replica shard(此时index的集群状态变成green)
  5. 当ElasticSearch--01恢复时,shard 1会变成relica 1。ElasticSearch--01会从master获取地址,把shard 1、replica 2、replica 3、replica 4的地址的数据同步到最新的;
  6. ElasticSearch--01重新作为一个正常节点提供读操作;

5. 路由机制

客户端:可以是java客户端、kibana、curl命令等等

5.1 查询document路由机制

流程:

  1. 客户端发送请求到ES节点上,查询document
  2. 定位document坐标,一个查询请求往往会有多个document
  • 根据index查询(GET /goods),就会找到goods这个index下所有的type,然后根据type找到下面所有的document坐标
  • 根据id查询(GET /goods/_doc/1),就会直接定位到id为1的这个document坐标
  • 根据条件查询
GET /goods/_search
{
 "query": {
   "match": {
     "name": "zhonghua yagao"
   }
 }

就会根据name倒排索引定位到包含zhonghua、yagao、zhonghua yagao的document坐标

  1. 拿到所有document坐标,根据一致性hash算法算出它们的hash值
  2. 根据hash值 % primary shard节点数,算出此document落在哪个节点上

这也是后文中说的 index在建立的时候就已经直接或默认指定primary shard数量,而一旦确定了primary shard数量就不允许改的原因。因为一旦改了,取模的时候返回值不同了,就会到错误的shard搜索数据,当然查不到数据

  1. 当连接的客户端要访问的document刚好落在连接的ES节点上时,ES节点可以直接返回数据给客户端,不需要路由到其他ES节点上。
  2. 如果连接的ES节点上没有此document数据时。如下图:这时ES01会根据round_rabbin负载均衡算法自动去ES02或者ES03读数据,然后把结果返回给ES01,ES01返回给客户端

这时ES01被称为协调节点( coordinate node )

5.2 新增、修改document路由机制

  1. 客户端发送请求到ES节点上,写document
  2. 定位document坐标
  3. 根据一致性hash算法算出document的hash值
  4. 根据hash值 % primary shard节点数,算出此document落在哪个节点上
  5. 当连接的客户端要访问的document刚好落在连接的ES节点上时,ES节点可以直接执行新增、修改操作,返回操作结果给客户端,不需要路由到其他ES节点上
  6. document落在不落在连接节点上。如上图这时ES01会根据round_rabbin负载均衡算法自动去ES02或者ES03写数据,然后把结果返回给给ES01,ES01返回给客户端

这时ES01被称为协调节点( coordinate node )

6. 写一致性机制

consistency参数:

  • one(primary shard)
  • all(all shard)
  • quorum(default)

我们在执行增删改操作的时候,都可以带上一个consistency参数,指定想要的写一致性是什么?

put /index/type/id?consistency=quorum

one:只要有一个primary shard是active状态就可以执行 all:必须所有的primary shard和replicashard都是active状态,才可以执行这个写操作 quorum:默认,要求大部分的shard都是active状态,才可以执行这个写操作

6.1 quorum机制

quorum机制:写之前必须确保大多数shard都可用,如果quorum不齐全时,会等待满足quorum数量,或者直到超时(默认1分钟)

算法:quroum = int( (primary + number_of_replicas) / 2 ) + 1,并且number_of_replicas>1时才生效

举个例子,3个primary shard,number_of_replicas=1,总共有3 + 3 * 1 = 6个shard quorum = int( (3 + 1) / 2 ) + 1 = 3 所以,要求6个shard中至少有3个shard是active状态的,才可以执行这个写操作

ES的特性:primary shard不能和自己的replica shard放在同一个节点上。如果节点挂了比较多,剩余的shard不满足quorum数量,会导致无法执行任何写操作

3个primary shard,replica=1,要求至少3个shard是active,3个shard按照之前学习的shard&replica机制,必须在不同的节点上,如果说只有1台机器的话,是不是有可能出现说,3个shard都没法分配齐全,此时就可能会出现写操作无法执行的情况

如果配置的是primary shard为1、replica为1,那么quorum=((1 + 1) / 2) + 1 = 2,如果这个时候只剩1台机器了,会出现什么情况呢?

因为primary shard不能和自己的replica shard放在同一个节点上,剩下的这台机器就只有primary shard,replica shard是不能继续保存在这里的。这时再往里面写数据的话,ES会一直等待其他机器加入集群加入replica shard,一直到超时。

在使用quorum的时候建议加上timeout参数

put /index/_doc/id?timeout=10s