Alluxio的Raft HA实现

前言


Alluxio在HA的实现上,早期实现的方式是基于ZK(用来做领导选举)+shared journal storage(状态同步)的方式来达到其服务高可用性的,这种方式和HDFS的HA实现十分类似。不过后来Alluxio社区实现了基于Raft协议的新的HA实现方式,这里的Raft实现依赖了开源Raft Java实现库Apache Ratis。作为全新的HA实现,本文笔者结合Alluxio相关代码来简单聊聊里面的一些实现细节。

基于Raft实现的要点


Raft一致性协议算法目前逐渐被越来越多的大型系统所使用,比如对象存储系统Apache Ozone。Ozone内部的数据一致性控制依赖的实现也是Apache Ratis。

对于同样要依赖Apache Ratis做Raft HA实现的Alluxio系统来说,它需要特别关注哪几个要点的实现呢?这里笔者结合之前对于Ozone以及Apache Ratis的了解,列出以下几点:

  • StateMachine,状态机的定义,不同的系统它所谓的状态机的概念是不同的。比如以存储系统而言,大部分情况可理解为为master元数据的控制更新
  • Leader/Follower节点的选举,重新选举时的回调执行操作

以上两点是笔者认为做Raft实现需要尤其考虑实现的点,其它的部分我们再结合实际的系统实现做对应逻辑的适配修改。比如本文今天所讲述的这样的一个系统就是Alluxio。

Alluxio Raft HA实现的相关角色类


下面我们结合Alluxio的代码做Alluxio Raft HA实现的介绍。

首先一个主要的中心控制类RaftJournalSystem,此类里包括了状态机,raft journal writer等等与Raft journal HA实现的相关角色类。

RaftPrimarySelector, Primary选举监听类,当有新的leader选举时,此类会监听回调对应的执行执行。

RaftJournalWriter,Raft Journal信息的写出类。此类会调用Raft Client向其它master server组进行journal信息的写出。

JournalStateMachine,状态机的定义实现类,此类负责master状态的更新以及snapshot的定期take操作。

BufferedJournalApplier,负责apply journal信息到master的类。此类内部额外维护了一个suspend buffer队列,用类临时存放暂停时间段待apply的raft journal信息。

SnapshotReplicationManager,snapshot管理类,在Raft server中,Follower会进行snapshot的take并upload snapshot到Leader的Raft Server里。

Alluxio Raft HA部分场景分析


Leader重新选举监听处理


当发生了新的Leader选举时,Alluxio的master目前是怎么样的一个action操作?

首先我们来看与此相关的角色类,RaftPrimarySelector,代码如下:

/**
 * A primary selector backed by a Raft consensus cluster.
 */
@ThreadSafe
public class RaftPrimarySelector extends AbstractPrimarySelector {
   

  /**
   * Notifies leadership state changed.
   * @param state the leadership state
   */
  public void notifyStateChanged(State state) {
   
    setState(state);
  }

  @Override
  public void start(InetSocketAddress address) throws IOException {
   
    // The Ratis cluster is owned by the outer {@link RaftJournalSystem}.
  }

  @Override
  public void stop() throws IOException {
   
    // The Ratis cluster is owned by the outer {@link RaftJournalSystem}.
  }
}

此类基本继承父类的实现,只是对外方法里额外重置了一个状态。我们在基于ZK做Leader选举的时候,ZK是有提供对应接口监听得到新的Leader信息的。同理基于Raft实现的Apache Ratis同样有这么一个接口方法。

在JournalStateMachine的notifyLeaderChanged方法里,能监听到这个动作,随之会调用到RaftPrimarySelector#notifyStateChanged方法的执行,相关代码如下:

  @Override
  public void notifyLeaderChanged(RaftGroupMemberId groupMemberId, RaftPeerId raftPeerId) {
   
    if (mRaftGroupId == groupMemberId.getGroupId()) {
   
      mIsLeader = groupMemberId.getPeerId() == raftPeerId
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值