千家信息网

nacos RaftCore中MasterElection的原理及应用

发表于:2025-01-31 作者:千家信息网编辑
千家信息网最后更新 2025年01月31日,本篇内容主要讲解"nacos RaftCore中MasterElection的原理及应用",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"nacos Raft
千家信息网最后更新 2025年01月31日nacos RaftCore中MasterElection的原理及应用

本篇内容主要讲解"nacos RaftCore中MasterElection的原理及应用",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"nacos RaftCore中MasterElection的原理及应用"吧!

本文主要研究一下nacos RaftCore的MasterElection

RaftCore

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftCore.java

@Componentpublic class RaftCore {                //......    @PostConstruct    public void init() throws Exception {        Loggers.RAFT.info("initializing Raft sub-system");        executor.submit(notifier);        long start = System.currentTimeMillis();        raftStore.loadDatums(notifier, datums);        setTerm(NumberUtils.toLong(raftStore.loadMeta().getProperty("term"), 0L));        Loggers.RAFT.info("cache loaded, datum count: {}, current term: {}", datums.size(), peers.getTerm());        while (true) {            if (notifier.tasks.size() <= 0) {                break;            }            Thread.sleep(1000L);        }        initialized = true;        Loggers.RAFT.info("finish to load data from disk, cost: {} ms.", (System.currentTimeMillis() - start));        GlobalExecutor.registerMasterElection(new MasterElection());        GlobalExecutor.registerHeartbeat(new HeartBeat());        Loggers.RAFT.info("timer started: leader timeout ms: {}, heart-beat timeout ms: {}",            GlobalExecutor.LEADER_TIMEOUT_MS, GlobalExecutor.HEARTBEAT_INTERVAL_MS);    }        //......}
  • RaftCore的init方法通过GlobalExecutor.registerMasterElection(new MasterElection())注册了MasterElection

GlobalExecutor

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/misc/GlobalExecutor.java

public class GlobalExecutor {        //......    public static final long TICK_PERIOD_MS = TimeUnit.MILLISECONDS.toMillis(500L);    public static void registerMasterElection(Runnable runnable) {        executorService.scheduleAtFixedRate(runnable, 0, TICK_PERIOD_MS, TimeUnit.MILLISECONDS);    }    //......}
  • registerMasterElection方法每隔TICK_PERIOD_MS毫秒调度一次runnable

MasterElection

nacos-1.1.3/naming/src/main/java/com/alibaba/nacos/naming/consistency/persistent/raft/RaftCore.java

    public class MasterElection implements Runnable {        @Override        public void run() {            try {                if (!peers.isReady()) {                    return;                }                RaftPeer local = peers.local();                local.leaderDueMs -= GlobalExecutor.TICK_PERIOD_MS;                if (local.leaderDueMs > 0) {                    return;                }                // reset timeout                local.resetLeaderDue();                local.resetHeartbeatDue();                sendVote();            } catch (Exception e) {                Loggers.RAFT.warn("[RAFT] error while master election {}", e);            }        }        public void sendVote() {            RaftPeer local = peers.get(NetUtils.localServer());            Loggers.RAFT.info("leader timeout, start voting,leader: {}, term: {}",                JSON.toJSONString(getLeader()), local.term);            peers.reset();            local.term.incrementAndGet();            local.voteFor = local.ip;            local.state = RaftPeer.State.CANDIDATE;            Map params = new HashMap<>(1);            params.put("vote", JSON.toJSONString(local));            for (final String server : peers.allServersWithoutMySelf()) {                final String url = buildURL(server, API_VOTE);                try {                    HttpClient.asyncHttpPost(url, null, params, new AsyncCompletionHandler() {                        @Override                        public Integer onCompleted(Response response) throws Exception {                            if (response.getStatusCode() != HttpURLConnection.HTTP_OK) {                                Loggers.RAFT.error("NACOS-RAFT vote failed: {}, url: {}", response.getResponseBody(), url);                                return 1;                            }                            RaftPeer peer = JSON.parseObject(response.getResponseBody(), RaftPeer.class);                            Loggers.RAFT.info("received approve from peer: {}", JSON.toJSONString(peer));                            peers.decideLeader(peer);                            return 0;                        }                    });                } catch (Exception e) {                    Loggers.RAFT.warn("error while sending vote to server: {}", server);                }            }        }    }
  • MasterElection实现了Runnable方法,其run方法在peers都是ready而且local.leaderDueMs减去TICK_PERIOD_MS小于等于0的时候会开始选举;它首先resetLeaderDue及resetHeartbeatDue,然后执行sendVote方法;sendVote方法首先重置peers,递增localPeer的term,并设置voteFor为自己,然后更新state为RaftPeer.State.CANDIDATE,最后遍历peers.allServersWithoutMySelf(),将自己的vote信息异步post给其他peer;如果其他peer返回成功则执行peers.decideLeader(peer),返回1,否则返回0

小结

RaftCore的init方法通过GlobalExecutor.registerMasterElection(new MasterElection())注册了MasterElection;registerMasterElection方法每隔TICK_PERIOD_MS毫秒调度一次;MasterElection实现了Runnable方法,其run方法在peers都是ready而且local.leaderDueMs减去TICK_PERIOD_MS小于等于0的时候会开始选举;它首先resetLeaderDue及resetHeartbeatDue,然后执行sendVote方法

到此,相信大家对"nacos RaftCore中MasterElection的原理及应用"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0