身安不如心安,屋宽不如心宽 。

为什么es写数据是先发请求到primary shard,再将请求转给replica shard

Elasticsearch | 作者 wkdx | 发布于2020年03月15日 | 阅读数:3335

为什么es写数据是先发请求到primary shard,再将请求转给replica shard,为什么不是直接将写入primary shard的数据复制到replica shard呢?这样不是应该写入更快一些吗?
已邀请:

hapjin

赞同来自: wkdx novia wajika

这个问题属于客户端 "写确认" 的问题,这个问题redis官方文档有详细描述 redis的写确认是怎样子的。因为Redis是异步复制的,所以即使redis 客户端收到了 redis server返回的写入成功,这条消息也有可能是丢失了的。参考:Redis Cluster consistency guarantees


Redis Cluster is not able to guarantee strong consistency. In practical terms this means that under certain conditions it is possible that Redis Cluster will lose writes that were acknowledged by the system to the client.


 而对于ES来说,客户端向ES 索引 写一篇文档,根据文档ID(如果不指定会自动生成)murmur3 哈希选择该索引的某个primary shard,将这篇文档写入到primary shard上,然后再将文档同步到replica,这里的同步过程:我的理解是,同步给 In-sync 集合里面的副本。这样,当insync集合里面的replica都写入成功后,各个replica向primary shard返回确认,当primary shard 所在节点认为in-sync副本列表集合里面的rpelica都写入成功后,primary shard再向ES 客户端返回写入成功的响应。由于 replica 分布在不同的ES节点上,当某台节点宕机,就可以通过"副本"保证了数据不丢失。参考:ES replication models
 
关于这个 in-sync 同步副本列表集合,可以参考 Kafka 的 min.insync.replica 参数的意义,二者原理是相似的。至于哪些分片 属于 in-sync 集合,这个是集群的"元数据"信息,由ES的master节点来维护,由ZenDiscovery来保证一致性。
 至于 wait_for_active_shards 这个参数,它只是在请求前检查活跃的 分片数量,当活跃分片的数量大于等于wait_for_active_shards,就具有 写文档 的资格:


To improve the resiliency of writes to the system, indexing operations can be configured to wait for a certain number of active shard copies before proceeding with the operation. If the requisite number of active shard copies are not available, then the write operation must wait and retry, until either the requisite shard copies have started or a timeout occurs.


但是这个检查并写入并不是原子操作,因此有下面一段话:


It is important to note that this setting greatly reduces the chances of the write operation not writing to the requisite number of shard copies, but it does not completely eliminate the possibility, because this check occurs before the write operation commences.


 参考:index-wait-for-active-shards
 
 

novia - 1&0

赞同来自: byx313

primary shard的数据复制到replica shard呢?
你是指异步复制吗?这样的话,主分片已经返回给客户端,如果复制失败了,那数据就会不一致了。早起es好像就是用的这个机制,后面改为同步了

code4j - coder github: https://github.com/rpgmakervx

赞同来自:

之前看过 5.x的写入逻辑,写入主分片成功后会调用写replica。
 
个人的理解是这样:
其实你说的主分片复制到副本 我理解是一种异步的流程。而这么做如果复制失败了副本和主分片就不一样了。而elasticsearch有一个配置是确保有多少分片同步到数据后才结束一次写流程的,所以异步的方式应该是不满足这个需求的,需要再一次写流程中进行流量转发,等待请求完成。

byx313 - BLOG:https://www.jianshu.com/u/43fd06f9589c

赞同来自:

"为什么不是直接将写入primary shard的数据复制到replica shard呢"这句话的意思是?
你的意思是只要写入p shard就算成功,然后集群再异步同步?

caizhongao

赞同来自:

这样能保证主分片上的版本是最新的,如果同时进行,没法保证哪个分片的数据是最新,如果故障,就无法恢复

要回复问题请先登录注册