爱收集资源网

FSAC 未来超级架构师:架构师总动员,实现架构转型,摆脱中年危机

爱收集资源网 2024-09-27 18:12

Raft算法,其名仿若远古图腾,实则现代分布式系统中承载心跳与选举的关键机制。于此算法中,节点间交互宛如一场编排周密的舞蹈,而远程过程调用(RPC)则充当着舞蹈的节拍。

心跳不止是心跳

在Raft架构中,心跳不仅是生理现象,更是生命的隐喻,代表着领导者对追随者的信息交流。通过AppendEntriesRPC,领导节点向其他节点传播日志条目,这些条目如同心跳的节律,保证所有节点同步并维持一致性。这种一致性不仅涉及数据同步,还象征系统的脉动,确保每节点都能体验系统生机。

然而,心跳功能存在限制。随着日志规模的增大,心跳的步伐亦会变得笨重。此刻,InstallSnapshotRPC成为关键。它充当应急工具,能在心跳失效之际,迅速恢复节点状态。此全量复制机制确保,在最恶劣情境下,系统亦能迅速复原,恢复运行。

选举不只是选举

在Raft算法中,领导权争夺激烈,各节点竞相争取。RequestVote远程过程调用(ROP)成为晋升领导者的入场券,各节点借此展现诉求。选举不仅是权力的博弈,更是责任的继任。领导地位赋予重任,需保障系统一致性,确保节点日志精准复制,数据安全无虞。

然而,选举过程亦存在潜在风险。一旦出现流程问题,系统可能陷入混乱。此时,Raft领导者的不一致性处理机制便能发挥关键作用。通过强制让跟随者同步日志,它确保了系统的一致性。这一机制犹如一场及时救援,迅速恢复系统秩序。

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);
}

负载均衡:不只是分发请求

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协议的编排中,负载均衡扮演着类似指挥家角色,保障各节点公平分配任务。一致性哈希技术使得请求均等分配至节点,维持系统活力。然此机制亦存在短板,未能细察节点实际性能,导致请求分发可能失衡。

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);
}
}
}

git clone https://github.com/alibaba/nacos.git

在此情境下,负载均衡器发挥了关键作用,采用异步模式、支持响应式编程,并依托SpringWebFlux进行客户端负载均衡操作。一旦RestTemplate或WebClient被标注为@LoadBalanced,SpringCloud自动为其生成代理,并于HTTP请求中植入负载均衡功能,以确保请求高效分发,防止资源不均衡分配。

心跳与选举的实际应用

在各类分布式系统中,Raft协议的心跳及选举功能得到广泛部署。在微服务架构中,该功能有助于维护数据一致性。心跳功能用于实时监测服务健康状况,保障系统稳定性;选举功能则在领导者节点故障时,快速选任新领导者,确保系统持续运作。

Raft的心跳及选举过程可融入数据库体系。心跳监控帮助数据库及时掌握节点状态,保障数据一致性。选举过程能在主节点故障时迅速选出新主,确保数据可用性。

public class ArrayMetric implements Metric {

private final LeapArray data;

public ArrayMetric(int sampleCount, int intervalInMs, boolean enableOccupy) {
if (enableOccupy) {
this.data = new OccupiableBucketLeapArray(sampleCount, intervalInMs);
} else {
this.data = new BucketLeapArray(sampleCount, intervalInMs);
}
}
}

心跳与选举的未来展望

public abstract class LeapArray<T> {

//每一个窗口的时间间隔,单位为毫秒
protected int windowLengthInMs;
//抽样个数,就一个统计时间间隔中包含的滑动窗口个数
protected int sampleCount;
//一个统计的时间间隔
protected int intervalInMs;
//滑动窗口的数组,滑动窗口类型为 WindowWrap
protected final AtomicReferenceArray> array;
private final ReentrantLock updateLock = new ReentrantLock();

public LeapArray(int sampleCount, int intervalInMs) {
this.windowLengthInMs = intervalInMs / sampleCount;
this.intervalInMs = intervalInMs;
this.sampleCount = sampleCount;
this.array = new AtomicReferenceArray<>(sampleCount);
}
}

随着分布式技术的发展,Raft的心跳与选举功能亦持续更新。展望未来,预期将出现更为智能化的心跳与选举机制,能够根据系统状况灵活调整心跳频率和选举策略。同时,亦有望引入更高效的负载均衡策略,依据节点性能合理分配请求,以维护系统整体性能。

public class MetricBucket {
/**
* 存储各事件的计数,比如异常总数、请求总数等
*/

private final LongAdder[] counters;
/**
* 这段事件内的最小耗时
*/

private volatile long minRt;
}

在Raft算法的演进中,心跳与选举虽然形式简单,却构成了分布式系统的核心支柱,维护着系统的稳定与数据一致性。

public enum MetricEvent {
PASS,
BLOCK,
EXCEPTION,
SUCCESS,
RT,
OCCUPIED_PASS
}

public long get(MetricEvent event) {
return counters[event.ordinal()].sum();
}

面试通过 走流程是否会被