Elasticsearch主分片不可以修改的原因

时间:2024-03-16 17:46:10

Elasticsearch中,一个index一般会有多个主分片(Primary shard),每个主分片存储该索引的一部分数据,一个文档(document)数据,只会在其中一个分片上,所有主分片的文档合并在一起就是整个索引的数据。而每个主分片都会有副本分片(Replica shard),用作数据备份,实现高可用以及提供读功能,当出现高并发大量读请求时,通过协调节点负载均衡,减小服务器压力。

这里假设一个index有3个Primary shard(P0,P1,P2)和1个Replica shard(R0,R1,R2),所以总分片数是:3+3*1=6,
应用程序对es发出写文档请求:
Elasticsearch主分片不可以修改的原因
从图里可以很直观的看到,由于索引对文档的增删改操作不会直接作用到备份分片,而是先修改主分片,然后再把修改点同步到备份分片上,所以id为3的文档被路由到了P0,id为1的文档被路由到了P1,id为2的文档被路由到了P2。

这里是通过路由算法:shard=hash(routing)%number_of_primary_shards 来计算出文档应该被路由到哪个主分片上

routing的值默认是文档的_id值,可以手动指定,也可以自动生成,特别强调,相同的routing值,每次hash(routing)时,值都是相同的

number_of_primary_shards就是创建索引时指定的主分片数量,7.x前默认是5个主分片,7.x后是1个主分片,当然也可以自己手动设置分片数。

比如上图的_id为1的文档,通过路由算法,假设hash(routing)的值是1,1%3=1,所以这个文档被路由到分片一(P1)中。

读documet的路由图:

Elasticsearch主分片不可以修改的原因
从图里可以看出,应用程序要得到_id为3的document,通过路由算法,可以知道P0和R0都可以提供这个文档,具体这次请求由哪个分片处理,则由协调节点通过负载均衡轮询来决定

协调节点:上面的两张图都忽略了协调节点的图解,所以这里解释下协调节点。这里请求发到哪个节点上哪个节点就是协调节点,每次请求发到的节点可能都不同,一般情况下,人人都可以是协调节点,每个节点都知道其他节点的信息,所以协调节点在收到请求后能知道这个文档应该去哪个节点里的哪个分片做增删改查操作,但是增删改只能操作主分片,然后通过负载均衡轮询,找到一个分片,处理这个请求,分片会把查请求得到的数据或者增删改的响应发回给协调节点,由协调节点统合,然后响应给客户端。

知道了document的路由原理之后,就可以知道为什么Primary shard不可以修改了,假设我们在上面的3个主分片的基础上又加了一个主分片:
Elasticsearch主分片不可以修改的原因

之前_id为3的文档是路由到P0和R0分片的,但是加了个主分片后,该文档被路由到P3和R3了,这样就间接的导致了数据丢失,所以主分片数量不能修改,当然了,备份分片数是可以修改的,因为备份分片和路由算法无关哈。

这里有一个问题,之前我觉得要是新增主分片的话,es把数据平均分配不就可以了,然后查了下,原因是分片的切分成本和重新建立索引的成本差不多,所以官方干脆建议直reindex。