Elasticsearch架构原理(二)
一、节点职责
节点按照职责可以分为:
- master节点
- 数据节点
- 协调节点
节点类型可以进行单独配置。默认情况下,集群不会对节点角色进行划分,所有节点都是平等的,可以担任所有的职责。但是在生产环境中需要对这些节点的角色进行最优划分,否则在高并发请求的情况下,集群容易出现服务阻塞超时甚至服务崩溃的隐患。
master节点
master节点负责维护整个集群的相关工作,管理集群的变更,如创建/删除索引、节点健康状态监测、节点上/下线等。
master节点是由集群节点通过选举算法选举出来的,一个集群中只有一个节点可以成为master节点,但是可以有一个或多个节点参与master节点的选举。
在默认情况下,任意节点都可以作为master的候选节点,可以通过配置项node.master对当前节点是否作为master的候选节点进行控制。
数据节点
数据节点主要负责索引数据的保存工作,此外也执行数据的其他操作,如文档的删除、修改和查询操作。
数据节点的很多工作是调用Lucene库进行Lucene索引操作,因此这种节点对于内存和I/O的消耗比较大,生产环境中应多注意数据节点的计算机负载情况。
协调节点
客户端可以向ES集群的节点发起请求,这个节点叫作协调节点。
在默认情况下,协调节点可以是集群中的任意节点,此时它的生命周期是和一个单独的请求相关的。也就是说,当客户端向集群中的某个节点发起请求时,此时该节点被称为当前请求的协调节点;当它将响应结果返回给客户端后,该协调节点的生命周期就结束了。
如下图所示的左右两图分别表示两次不同的请求,因为请求时客户端指定的请求地址不同,所以左图中的请求协调节点是node1,右图中的请求协调节点是node3。协调节点根据具体情况将请求转发给其他节点,并将最终的汇总处理结果返回给客户端。
当然,为了降低集群的负载,可以设置某些节点作为单独的协调节点。在节点的配置文件中设置node.master和node.data配置项为false,此时,这个节点就不会被选中为master节点并且不再担任数据节点,而客户端就可以把这类节点作为协调节点来使用,把所有的请求都分发到这些节点上,如下图所示:
二、主分片和副分片
ES为了支持分布式搜索,会把数据按照分片进行切分。一个索引由一个或者多个分片构成,并且每个分片有0个甚至多个副分片。多个分片分布在不同的节点中,通过这种分布式结构提升了分片数据的高可用性和服务的高并发支持。
集群中的索引主分片和副分片在不同的计算机上,如果某个主分片所在的节点宕机,则原有的某个副分片会提升为主分片继续对外进行服务。
高可用支持
如下图所示的集群中,如果node1发生故障宕机,集群感知到分片0的主分片P0将要丢失,此时集群会立即将其他节点(如node3)上的分片0对应的副分片R0作为主分片P0进行服务。集群中由node2和node3对外提供服务,所有的分片相关的服务不受影响
如果node1恢复了服务并加入集群中,因为在node1上还保留有分片0的数据,此时node1上的分片P0会变成副分片R0,在此期间缺失的数据会通过node3上的主分片P0进行补充。并且node1上的分片R1和R2也会分别从node3和node2上对应的P1和P2分片上补充数据,如下图所示:
高并发性能
当客户端对某个索引的请求被分发到ES的协调节点时,协调节点会将请求进行转发,转发的对象是包含这个索引的所有分片的部分节点。
协调节点中有一份分片-节点路由表,该表主要存放分片和节点的对应关系。协调节点采用轮询算法,选取该索引的主/副分片所在的节点进行请求转发。
一个索引的主分片设定后就不能再修改,如果想继续提升索引的并发性能,则可以增加索引的副分片个数,此时协调节点会将这些副分片加入轮询算法中。
三、路由计算
当客户端向一个ES协调节点发送一条数据的写入请求时,协调节点会根据数据获取分片ID的计算公式【shard=hash(routing)%number_of_primary_shards】来确认当前数据应该存储在哪个节点。
其中:
routing代表每条文档提交时的参数,该值是可变的,用户可以自定义,在默认情况下使用的是文档的_id值;
number_of_primary_shards是索引中主分片的个数。
计算routing的哈希值后,除以索引的主分片数再取余,就是当前文档实际应该存储的分片ID。
获取到分片ID后,根据分片-节点路由表获取该分片的主/副分片节点列表,然后再转发请求进行分片内的数据写入。
通过分片ID公式可以观察到,主分片个数作为取余的分母不能进行更改,否则分片ID计算就会发生错误,进而导致找不到存储节点,这也是ES索引的主分片个数不能更改的原因。
四、文档读写过程
当ES协调节点接收到来自客户端对某个索引的写入文档请求时,该节点会根据一定的路由算法将该文档映射到某个主分片上,然后将请求转发到该分片所在的节点。
完成数据的存储后,该节点会将请求转发给该分片的其他副分片所在的节点,直到所有副分片节点全部完成写入,ES协调节点向客户端报告写入成功。
如下图所示,一个包含3个节点的ES集群,假设索引中只有3个主分片和6个副分片,客户端向节点1发起向索引写入一条文档的请求,在本次请求中,节点1被称为协调节点。节点1判断数据应该映射到哪个分片上。假设将数据映射到分片1上,因为分片1的主分片在节点2上,因此节点1把请求转发到节点2上。节点2接收客户端的数据并进行存储,然后把请求转发到副分片1所在的节点1和节点3上,当所有副分片所在的节点全部完成存储后,协调节点也就是节点1向客户端返回成功标志。
当ES协调节点接收到来自客户端的获取某个索引的某文档的请求时,协调节点会找到该文档所在的所有分片,然后根据轮询算法在主/副分片中选择一个分片并将请求转发给该分片所在的节点,该节点会将目标数据发送给协调节点,协调节点再将数据返回给客户端。
如下图所示,一个包含3个节点的ES集群,假设索引中只有3个主分片和6个副分片,客户端向节点1发起向索引获取文档的请求,在本次请求中,节点1被称为协调节点。节点1判断数据应该映射到哪个分片上。假设将数据映射到分片1上,分片1有主/副两种分片,分别在节点2、节点1和节点3上。假设此时协调节点的轮询算法选择的是节点3,那么它会将请求转发到节点3上,然后节点3会把数据传输给协调节点,也就是节点1,最后由节点1向客户端返回文档数据。