1.分片机制
primary shard不能和自己的replica shard放在同一个节点上
创建index,并指定shards和relicas都为4
PUT /test_index
{
"settings" : {
"number_of_shards" : 4,
"number_of_replicas" : 4
}
}
如果此时有4台机器,总分片数量为16,分片机制表现为:
PUT /test_index2
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 2
}
}
分片机制表现为:
1.1 分片机制特性
- Elasticsearch隐藏了复杂的分片机制,开发人员不用关心数据分配到哪个shard中,只需要关心document插入和搜索。
- cluster discovery:集群发现机制。ES入门篇4中,index的status从yellow转green的实验里,启动第二个es节点,这个节点会自动加入集群中,作为replica同步shard的所有document)
- shard负载均衡(举例,假设现在有3个node,总共有6个shard要分配到3个节点上去,es会自动进行均匀分配,以保持每个节点的均衡的读写负载请求)
- 请求路由:例如上图中的3 shard 、2 replica,当请求ElasticSearch--01的document时,发现数据落到shard 3,这时ElasticSearch--01节点会根据负载均衡去ElasticSea rch--02或ElasticSearch--03取数据返回给客户端。
- 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机制
- index会被分配到多个shard/replica中
- 每个shard/replica都是最小工作单元(lucene实例),保存着部分index数据,拥有完整的能力(例如建立索引、查询索引、删除索引、删除索引)
- 增减节点时,ES会rebalance,使shard在nodes中负载均衡
- primary shard和replica shard,一个document只能存在于一个primary shard不能存在于多个primary shard中。假如primary shard有n个对应的replica shard,那么这个document会复制到n个replica shard中。
- replica shard是primary shard的副本,负责容错,以及承担读请求负载
- primary shard的数量在创建索引的时候就固定了,replica shard的数量可以随时修改
primary shard的默认数量是5,replica默认是1,默认有10个shard,5个primary shard,5个replica shardprimary shard不能和自己的replica shard放在同一个节点上(否则节点宕机,primary shard和副本都丢失,起不到容错的作用),但是可以和其他primary shard的replica shard放在同一个节点上- index在建立的时候就已经指定了shard、replica的数量(自定义shard数量第三章有介绍),shard的数量一旦确定了就不能更改,replica数量可以随意扩容。
4. 容灾机制
(4 shard、4 replica)场景
ElasticSearch--01挂了:
自动容灾:
ElasticSearch--01恢复后:
如上图所示ElasticSearch--01挂了,ES是怎么自动容灾的呢?
- primary shard 1这个主shard挂了,需要从与之对应的剩余replica shard 1中选出一个变成primary shard 1。此时index的集群状态为yellow
- ElasticSearch--02、ElasticSearch--03、ElasticSearch--04会进行master竞选,通过分布式一致性算法选出一个master负责执行。(如果ElasticSearch--01不是master则不用选举,直接跳到第三步)
假设选的是ElasticSearch--02 - master选出一个最合适(数据丢失最少)的replica shard 1并把它切换成replica shard 1。
假设选的是ElasticSearch--03 - 新的replica shard 1把数据同步到其他的replica shard(此时index的集群状态变成green)
- 当ElasticSearch--01恢复时,shard 1会变成relica 1。ElasticSearch--01会从master获取地址,把shard 1、replica 2、replica 3、replica 4的地址的数据同步到最新的;
- ElasticSearch--01重新作为一个正常节点提供读操作;
5. 路由机制
客户端:可以是java客户端、kibana、curl命令等等
5.1 查询document路由机制
流程:
- 客户端发送请求到ES节点上,查询document
- 定位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坐标
- 拿到所有document坐标,根据一致性hash算法算出它们的hash值
- 根据hash值 % primary shard节点数,算出此document落在哪个节点上
这也是后文中说的 index在建立的时候就已经直接或默认指定primary shard数量,而一旦确定了primary shard数量就不允许改的原因。因为一旦改了,取模的时候返回值不同了,就会到错误的shard搜索数据,当然查不到数据
- 当连接的客户端要访问的document刚好落在连接的ES节点上时,ES节点可以直接返回数据给客户端,不需要路由到其他ES节点上。
- 如果连接的ES节点上没有此document数据时。如下图:这时ES01会根据round_rabbin负载均衡算法自动去ES02或者ES03读数据,然后把结果返回给ES01,ES01返回给客户端
这时ES01被称为协调节点( coordinate node )
5.2 新增、修改document路由机制
- 客户端发送请求到ES节点上,写document
- 定位document坐标
- 根据一致性hash算法算出document的hash值
- 根据hash值 % primary shard节点数,算出此document落在哪个节点上
- 当连接的客户端要访问的document刚好落在连接的ES节点上时,ES节点可以直接执行新增、修改操作,返回操作结果给客户端,不需要路由到其他ES节点上
- 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