Elasticsearch分布式一致性原理剖析之Data篇

“Elasticsearch分布式一致性原理剖析”系列将会对Elasticsearch的分布式一致性原理进行详细的剖析,介绍其实现方式、原理以及其存在的问题等(基于6.2版本)。前两篇文章介绍了ES中集群如何组成,master选举算法,master更新meta的流程等,并分析了选举、Meta更新中的一致性问题。本文会分析ES中的数据流,包括其写入流程、算法模型PacificA、SequenceNumber与Checkpoint等,并比较ES的实现与标准PacificA算法的异同。目录如下:

问题背景

数据写入流程

PacificA算法

SequenceNumber、Checkpoint与故障恢复

ES与PacificA的比较

小结

问题背景

用过ES的同学都知道,ES中每个Index会划分为多个Shard,Shard分布在不同的Node上,以此来实现分布式的存储和查询,支撑大规模的数据集。对于每个Shard,又会有多个Shard的副本,其中一个为Primary,其余的一个或多个为Replica。数据在写入时,会先写入Primary,由Primary将数据再同步给Replica。在读取时,为了提高读取能力,Primary和Replica都会接受读请求。

在这种模型下,我们能够感受到ES具有这样的一些特性,比如:

数据高可靠:数据具有多个副本。

服务高可用:Primary挂掉之后,可以从Replica中选出新的Primary提供服务。

读能力扩展:Primary和Replica都可以承担读请求。

故障恢复能力:Primary或Replica挂掉都会导致副本数不足,此时可以由新的Primary通过复制数据产生新的副本。

另外,我们也可以想到一些问题,比如:

数据怎么从Primary复制到Replica?

一次写入要求所有副本都成功吗?

Primary挂掉会丢数据吗?

数据从Replica读,总是能读到最新数据吗?

故障恢复时,需要拷贝Shard下的全部数据吗?

可以看到,对于ES中的数据一致性,虽然我们可以很容易的了解到其大概原理,但是对其细节我们还有很多的困惑。那么本文就从ES的写入流程,采用的一致性算法,SequenceId和Checkpoint的设计等方面来介绍ES如何工作,进而回答上述这些问题。需要注意的是,本文基于ES6.2版本进行分析,可能很多内容并不适用于ES之前的版本,比如2.X的版本等。

数据写入流程

首先我们来看一下数据的写入流程,读者也可以阅读这篇文章来详细了解:

https://zhuanlan.zhihu.com/p/34669354。

Replication角度: Primary -> Replica

我们从大的角度来看,ES写入流程为先写入Primary,再并发写入Replica,最后应答客户端,流程如下:

检查Active的Shard数。

finalString activeShardCountFailure=checkActiveShardCount();

写入Primary。

primaryResult=primary.perform(request);

并发的向所有Replicate发起写入请求

performOnReplicas(replicaRequest,globalCheckpoint,replicationGroup.getRoutingTable());

等所有Replicate返回或者失败后,返回给Client。

privatevoiddecPendingAndFinishIfNeeded(){

assertpendingActions.get()>0:"pending action count goes below 0 for request ["+request+"]";

if(pendingActions.decrementAndGet()==0){

finish();

}

}

上述过程在ReplicationOperation类的execute函数中,完整代码如下:

publicvoidexecute()throwsException{

finalString activeShardCountFailure=checkActiveShardCount();

finalShardRouting primaryRouting=primary.routingEntry();

finalShardId primaryId=primaryRouting.shardId();

if(activeShardCountFailure!=null){

finishAsFailed(newUnavailableShardsException(primaryId,

"{} Timeout: [{}], request: [{}]",activeShardCountFailure,request.timeout(),request));

return;

}

totalShards.incrementAndGet();

pendingActions.incrementAndGet();// increase by 1 until we finish all primary coordination

primaryResult=primary.perform(request);

primary.updateLocalCheckpointForShard(primaryRouting.allocationId().getId(),primary.localCheckpoint());

finalReplicaRequest replicaRequest=primaryResult.replicaRequest();

if(replicaRequest!=null){

if(logger.isTraceEnabled()){

logger.trace("[{}] op [{}] completed on primary for request [{}]",primaryId,opType,request);

}

// we have to get the replication group after successfully indexing into the primary in order to honour recovery semantics.

// we have to make sure that every operation indexed into the primary after recovery start will also be replicated

// to the recovery target. If we used an old replication grou

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农老K

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值