まず、いかだアルゴリズムの概要
理解することと比較して、それを実装する方が簡単パクシプロトコル筏に、一貫性のあるプロトコルログ管理を適用いかだ。
理解を向上させるためには、ラフトの整合性アルゴリズムを選択リーダーシップ(リーダーの選択)、ログのレプリケーション(ログのレプリケーション)、セキュリティ(安全性)を含むいくつかの部分に分けて、検討する必要性を減らすために大きいの一貫性を利用しています状態。
パクシ、ラフトアルゴリズムは、より直感的に理解するために比較。
ラフトサーバアルゴリズムは、3つの状態に分割され、またはロールと呼ばれることがあります。
リーダー
クライアントの相互作用の原因と一つにシステムで同時に存在を複製してログインします。フォロワー
要求RPCに受動的な応答、RPCへの要求を開始することはありません。候補者
しばらく自分自身の一時的な役割は、候補者の中に、だけにしてリーダーの選挙相、ノードがリーダーになることを望んで、ポーリング要求に存在しています。選挙が成功した場合、それがフォロワーに候補者、または他のリターンとなり
:次のように循環の状況や役割
いかだには、への問題:リーダーシップの選択、ログの複製、およびセキュリティの変更のメンバー。
マシンは、ログをコピーすることによって達成された状態をコピーします。
ログ:各マシンは、ログを維持するために、クライアントの要求からのログは、コマンドのシリーズが含まれ
、これらのコマンドを実行するために、ステート・マシン:ステートマシンを
一貫性モデル:複数のマシンのログが同じであることを確認するために、分散環境を、状態へのこのような再生状態マシンは、と一致しています
ラフトアルゴリズムは、メインフローを選択しました
用語の概念で筏は、項類推王朝は中国の歴史の中で、ラフトアルゴリズムは、異なる長さ(用語)に任意の時間の期間となります。
選挙プロセス
1、follower增加当前的term,转变为candidate。
2、candidate投票给自己,并发送RequestVote RPC给集群中的其他服务器。
3、收到RequestVote的服务器,在同一term中只会按照先到先得投票给至多一个candidate。且只会投票给log至少和自身一样新的candidate。
关于Raft更详细的描述,可以查看这里,从分布式一致性到共识机制(二)Raft算法
二、Nacos中的CP一致性
Spring Cloud Alibaba Nacos 在 1.0.0 正式支持 AP 和 CP 两种一致性协议,其中的CP一致性协议实现,是基于简化的 Raft 的 CP 一致性。
如何实现Raft算法
Nacos server在启动时,会通过RunningConfig.onApplicationEvent()方法调用RaftCore.init()方法。
启动选举
public static void init() throws Exception {
Loggers.RAFT.info("initializing Raft sub-system");
// 启动Notifier,轮询Datums,通知RaftListener
executor.submit(notifier);
// 获取Raft集群节点,更新到PeerSet中
peers.add(NamingProxy.getServers());
long start = System.currentTimeMillis();
// 从磁盘加载Datum和term数据进行数据恢复
RaftStore.load();
Loggers.RAFT.info("cache loaded, peer count: {}, datum count: {}, current term: {}",
peers.size(), datums.size(), peers.getTerm());
while (true) {
if (notifier.tasks.size() <= 0) {
break;
}
Thread.sleep(1000L);
System.out.println(notifier.tasks.size());
}
Loggers.RAFT.info("finish to load data from disk, cost: {} ms.", (System.currentTimeMillis() - start));
GlobalExecutor.register(new MasterElection()); // Leader选举
GlobalExecutor.register1(new HeartBeat()); // Raft心跳
GlobalExecutor.register(new AddressServerUpdater(), GlobalExecutor.ADDRESS_SERVER_UPDATE_INTERVAL_MS);
if (peers.size() > 0) {
if (lock.tryLock(INIT_LOCK_TIME_SECONDS, TimeUnit.SECONDS)) {
initialized = true;
lock.unlock();
}
} else {
throw new Exception("peers is empty.");
}
Loggers.RAFT.info("timer started: leader timeout ms: {}, heart-beat timeout ms: {}",
GlobalExecutor.LEADER_TIMEOUT_MS, GlobalExecutor.HEARTBEAT_INTERVAL_MS);
}
在init方法主要做了如下几件事:
- 获取Raft集群节点 peers.add(NamingProxy.getServers());
- Raft集群数据恢复 RaftStore.load();
- Raft选举 GlobalExecutor.register(new MasterElection());
- Raft心跳 GlobalExecutor.register(new HeartBeat());
- Raft发布内容
- Raft保证内容一致性
选举流程
其中,raft集群内部节点间是通过暴露的Restful接口,代码在 RaftController 中。
RaftController控制器是raft集群内部节点间通信使用的,具体的信息如下
POST HTTP://{ip:port}/v1/ns/raft/vote : 进行投票请求
POST HTTP://{ip:port}/v1/ns/raft/beat : Leader向Follower发送心跳信息
GET HTTP://{ip:port}/v1/ns/raft/peer : 获取该节点的RaftPeer信息
PUT HTTP://{ip:port}/v1/ns/raft/datum/reload : 重新加载某日志信息
POST HTTP://{ip:port}/v1/ns/raft/datum : Leader接收传来的数据并存入
DELETE HTTP://{ip:port}/v1/ns/raft/datum : Leader接收传来的数据删除操作
GET HTTP://{ip:port}/v1/ns/raft/datum : 获取该节点存储的数据信息
GET HTTP://{ip:port}/v1/ns/raft/state : 获取该节点的状态信息{UP or DOWN}
POST HTTP://{ip:port}/v1/ns/raft/datum/commit : Follower节点接收Leader传来得到数据存入操作
DELETE HTTP://{ip:port}/v1/ns/raft/datum : Follower节点接收Leader传来的数据删除操作
GET HTTP://{ip:port}/v1/ns/raft/leader : 获取当前集群的Leader节点信息
GET HTTP://{ip:port}/v1/ns/raft/listeners : 获取当前Raft集群的所有事件监听者
RaftPeerSet
心跳机制
Raft中使用心跳机制来触发leader选举。心跳定时任务是在GlobalExecutor 中,
通过 GlobalExecutor.register(new HeartBeat())注册心跳定时任务,具体操作包括:
- 重置Leader节点的heart timeout、election timeout;
- sendBeat()发送心跳包
public class HeartBeat implements Runnable {
@Override
public void run() {
try {
if (!peers.isReady()) {
return;
}
RaftPeer local = peers.local();
local.heartbeatDueMs -= GlobalExecutor.TICK_PERIOD_MS;
if (local.heartbeatDueMs > 0) {
return;
}
local.resetHeartbeatDue();
sendBeat();
} catch (Exception e) {
Loggers.RAFT.warn("[RAFT] error while sending beat {}", e);
}
}
}
简单说明了下Nacos中的Raft一致性实现,更详细的流程,可以下载源码,查看 RaftCore 进行了解。源码可以通过以下地址检出:
git clone https://github.com/alibaba/nacos.git
扫码关注公众号:架构进化论,获得第一手的技术资讯和原创文章