踐與面試解析)
在分布式系統(tǒng)面試中Raft一致性算法及其在TiDB和Kafka中的實(shí)際應(yīng)用是高頻考點(diǎn)。很多候選人對(duì)Raft理論有所了解但被問(wèn)到具體落地細(xì)節(jié)時(shí)卻難以深入。本文將從工程實(shí)踐角度完整解析Raft在兩大主流分布式系統(tǒng)中的實(shí)現(xiàn)差異幫助你在面試中展現(xiàn)真正的技術(shù)深度。1. Raft協(xié)議核心概念解析1.1 什么是Raft一致性算法Raft是一種用于管理復(fù)制日志的一致性算法旨在替代Paxos算法通過(guò)更強(qiáng)的可理解性來(lái)簡(jiǎn)化分布式系統(tǒng)的構(gòu)建。與Paxos相比Raft將一致性問(wèn)題分解為三個(gè)相對(duì)獨(dú)立的子問(wèn)題領(lǐng)導(dǎo)選舉Leader Election、日志復(fù)制Log Replication和安全性Safety。在實(shí)際分布式系統(tǒng)中Raft通過(guò)選舉機(jī)制確保集群中始終存在一個(gè)主節(jié)點(diǎn)Leader來(lái)處理所有客戶端請(qǐng)求 follower節(jié)點(diǎn)同步Leader的數(shù)據(jù)變更從而保證整個(gè)集群的數(shù)據(jù)一致性。這種機(jī)制特別適合需要強(qiáng)一致性的數(shù)據(jù)庫(kù)系統(tǒng)和消息隊(duì)列系統(tǒng)。1.2 Raft的核心工作機(jī)制Raft協(xié)議的核心運(yùn)行機(jī)制基于以下幾個(gè)關(guān)鍵概念任期機(jī)制Raft將時(shí)間劃分為任意長(zhǎng)度的任期每個(gè)任期以選舉開始。如果候選人在選舉中獲勝它將在該任期內(nèi)擔(dān)任Leader角色。任期號(hào)單調(diào)遞增在RPC通信中攜帶用于檢測(cè)過(guò)期的信息。節(jié)點(diǎn)狀態(tài)轉(zhuǎn)換每個(gè)節(jié)點(diǎn)在集群中可能處于三種狀態(tài)之一Follower被動(dòng)節(jié)點(diǎn)響應(yīng)Leader和Candidate的RPC請(qǐng)求Candidate參與選舉的候選節(jié)點(diǎn)Leader處理所有客戶端請(qǐng)求負(fù)責(zé)日志復(fù)制選舉過(guò)程當(dāng)Follower在選舉超時(shí)時(shí)間內(nèi)沒有收到Leader的心跳就會(huì)轉(zhuǎn)變?yōu)镃andidate并開始新的選舉。它首先自增當(dāng)前任期號(hào)然后向其他節(jié)點(diǎn)發(fā)送RequestVote RPC。如果獲得大多數(shù)節(jié)點(diǎn)的投票就晉升為L(zhǎng)eader。1.3 Raft與Paxos的對(duì)比優(yōu)勢(shì)Raft相比Paxos的主要優(yōu)勢(shì)在于工程實(shí)現(xiàn)的便利性。Paxos算法雖然理論上優(yōu)雅但實(shí)際實(shí)現(xiàn)復(fù)雜難以保證正確性。Raft通過(guò)以下設(shè)計(jì)降低了實(shí)現(xiàn)難度強(qiáng)領(lǐng)導(dǎo)制任何時(shí)候只有一個(gè)Leader簡(jiǎn)化了日志管理日志連續(xù)性要求日志條目必須連續(xù)便于故障恢復(fù)成員變更安全性通過(guò)聯(lián)合共識(shí)機(jī)制安全處理配置變更這些特性使得Raft更適合在TiDB、Kafka等生產(chǎn)級(jí)系統(tǒng)中實(shí)現(xiàn)。2. TiDB中的Raft實(shí)現(xiàn)深度剖析2.1 TiDB整體架構(gòu)與Raft的定位TiDB作為分布式NewSQL數(shù)據(jù)庫(kù)采用分層架構(gòu)設(shè)計(jì)其中Raft協(xié)議在TiKV存儲(chǔ)層發(fā)揮核心作用。TiDB集群主要包含三個(gè)組件TiDB Server無(wú)狀態(tài)SQL層負(fù)責(zé)SQL解析和優(yōu)化PDPlacement Driver集群元數(shù)據(jù)管理和調(diào)度中心TiKV分布式鍵值存儲(chǔ)引擎基于Raft實(shí)現(xiàn)數(shù)據(jù)一致性在TiKV中數(shù)據(jù)被劃分為多個(gè)Region默認(rèn)96MB每個(gè)Region都是一個(gè)Raft組包含多個(gè)副本。這種設(shè)計(jì)使得TiDB能夠?qū)崿F(xiàn)數(shù)據(jù)的水平擴(kuò)展和高可用性。2.2 TiKV中Raft組的詳細(xì)工作流程TiKV中的Raft實(shí)現(xiàn)進(jìn)行了大量工程優(yōu)化主要體現(xiàn)在以下幾個(gè)方面Multi-Raft架構(gòu)每個(gè)TiKV節(jié)點(diǎn)可能同時(shí)參與多個(gè)Raft組既作為某些Region的Leader又作為其他Region的Follower。這種設(shè)計(jì)充分利用了硬件資源但同時(shí)也增加了實(shí)現(xiàn)的復(fù)雜性。// 模擬TiKV中Region的Raft狀態(tài)機(jī) public class TiKVRaftStateMachine { private long regionId; private RaftRole currentRole; private ListRaftLogEntry logEntries; private long committedIndex; private long lastAppliedIndex; public enum RaftRole { LEADER, FOLLOWER, CANDIDATE } // 處理客戶端寫入請(qǐng)求僅在Leader節(jié)點(diǎn) public RaftResponse handleWriteRequest(WriteRequest request) { if (currentRole ! RaftRole.LEADER) { throw new NotLeaderException(當(dāng)前節(jié)點(diǎn)不是Leader); } // 將操作封裝為Raft日志條目 RaftLogEntry logEntry createLogEntry(request); logEntries.add(logEntry); // 并行復(fù)制到其他Follower節(jié)點(diǎn) replicateLogToFollowers(logEntry); // 等待大多數(shù)節(jié)點(diǎn)確認(rèn) waitForMajorityAck(logEntry.getIndex()); // 提交日志并應(yīng)用到狀態(tài)機(jī) applyLogEntry(logEntry); return new RaftResponse(true, 寫入成功); } }Leader轉(zhuǎn)移優(yōu)化TiKV實(shí)現(xiàn)了優(yōu)雅的Leader轉(zhuǎn)移機(jī)制當(dāng)PD檢測(cè)到某個(gè)TiKV節(jié)點(diǎn)負(fù)載過(guò)高時(shí)會(huì)觸發(fā)Leader遷移到負(fù)載較低的節(jié)點(diǎn)這個(gè)過(guò)程不會(huì)影響業(yè)務(wù)可用性。2.3 TiDB中Raft的工程實(shí)踐特色TiDB在Raft實(shí)現(xiàn)上進(jìn)行了多項(xiàng)深度優(yōu)化這些也是面試中經(jīng)??疾斓牧咙c(diǎn)Raft Learner角色TiKV引入了Learner節(jié)點(diǎn)作為非投票成員同步數(shù)據(jù)用于實(shí)現(xiàn)彈性擴(kuò)展和異地容災(zāi)。Learner不參與選舉投票但可以同步日志在需要時(shí)快速提升為Follower。Region合并與分裂隨著數(shù)據(jù)增長(zhǎng)Region會(huì)自動(dòng)分裂反之?dāng)?shù)據(jù)刪除后小Region會(huì)合并。這個(gè)過(guò)程涉及Raft組的動(dòng)態(tài)變更TiDB通過(guò)ConfChange機(jī)制保證變更期間的數(shù)據(jù)一致性。熱點(diǎn)Region調(diào)度PD持續(xù)監(jiān)控各個(gè)Region的訪問(wèn)模式當(dāng)發(fā)現(xiàn)熱點(diǎn)Region時(shí)會(huì)自動(dòng)調(diào)度Leader或分裂Region來(lái)平衡負(fù)載。3. Kafka的Raft演進(jìn)與實(shí)踐3.1 Kafka從ZooKeeper到KRaft的架構(gòu)變革傳統(tǒng)Kafka集群嚴(yán)重依賴ZooKeeper進(jìn)行元數(shù)據(jù)管理這種架構(gòu)存在單點(diǎn)瓶頸和運(yùn)維復(fù)雜性等問(wèn)題。Kafka 2.8版本引入了KRaft模式使用Raft協(xié)議在Kafka集群內(nèi)部管理元數(shù)據(jù)實(shí)現(xiàn)了去ZooKeeper化。KRaft架構(gòu)的核心改進(jìn)包括元數(shù)據(jù)管理內(nèi)置化不再需要外部ZooKeeper集群控制器集群化多個(gè)Controller節(jié)點(diǎn)組成Raft集群選舉Leader性能提升減少網(wǎng)絡(luò)跳數(shù)降低元數(shù)據(jù)操作延遲3.2 KRaft模式下的Raft實(shí)現(xiàn)細(xì)節(jié)在KRaft模式下Kafka集群中的節(jié)點(diǎn)分為三種角色Controller節(jié)點(diǎn)負(fù)責(zé)管理集群元數(shù)據(jù)包括主題創(chuàng)建、分區(qū)分配、配置變更等。多個(gè)Controller節(jié)點(diǎn)組成Raft集群選舉出Leader Controller。Broker節(jié)點(diǎn)存儲(chǔ)消息數(shù)據(jù)處理生產(chǎn)消費(fèi)請(qǐng)求。在KRaft模式下Broker從Controller集群獲取元數(shù)據(jù)信息。Combined節(jié)點(diǎn)同時(shí)擔(dān)任Controller和Broker角色簡(jiǎn)化部署架構(gòu)。// Kafka KRaft模式下的Controller選舉模擬 public class KafkaRaftController { private final int nodeId; private final ListQuorumNode quorumNodes; private ControllerState currentState; private long currentEpoch; public void startControllerElection() { // 轉(zhuǎn)換為候選狀態(tài) transitionToCandidate(); // 向其他Quorum節(jié)點(diǎn)發(fā)送投票請(qǐng)求 VoteRequest voteRequest new VoteRequest(currentEpoch 1, nodeId); ListVoteResponse responses requestVotesFromPeers(voteRequest); // 統(tǒng)計(jì)投票結(jié)果 int grantedVotes countGrantedVotes(responses); if (grantedVotes quorumNodes.size() / 2) { // 贏得選舉成為L(zhǎng)eader Controller transitionToLeader(); startSendingMetadataUpdates(); } } // 處理元數(shù)據(jù)變更請(qǐng)求 public MetadataResponse handleMetadataChange(MetadataChange change) { if (currentState ! ControllerState.LEADER) { // 轉(zhuǎn)發(fā)到Leader節(jié)點(diǎn) return forwardToLeader(change); } // 將變更封裝為Raft日志 MetadataRecord record createMetadataRecord(change); // 復(fù)制到Follower節(jié)點(diǎn)并等待確認(rèn) replicateMetadataRecord(record); // 提交日志并更新內(nèi)存元數(shù)據(jù) commitMetadataRecord(record); return new MetadataResponse(record.getOffset()); } }3.3 KRaft帶來(lái)的優(yōu)勢(shì)與挑戰(zhàn)KRaft模式為Kafka帶來(lái)了顯著改進(jìn)但也引入了新的技術(shù)挑戰(zhàn)優(yōu)勢(shì)方面簡(jiǎn)化架構(gòu)減少外部依賴降低運(yùn)維復(fù)雜度提升性能元數(shù)據(jù)操作延遲降低吞吐量提升增強(qiáng)一致性Raft強(qiáng)一致性保證元數(shù)據(jù)操作的可靠性挑戰(zhàn)方面版本兼容性KRaft模式需要特定版本支持遷移存在兼容性問(wèn)題監(jiān)控調(diào)整原有的ZooKeeper監(jiān)控指標(biāo)需要調(diào)整為Raft相關(guān)指標(biāo)故障處理Raft集群的腦裂、網(wǎng)絡(luò)分區(qū)等故障需要新的處理機(jī)制4. TiDB與Kafka中Raft實(shí)現(xiàn)的對(duì)比分析4.1 設(shè)計(jì)目標(biāo)與應(yīng)用場(chǎng)景差異TiDB和Kafka雖然都使用Raft協(xié)議但由于設(shè)計(jì)目標(biāo)不同其實(shí)現(xiàn)存在顯著差異TiDB的強(qiáng)一致性優(yōu)先作為分布式數(shù)據(jù)庫(kù)TiDB優(yōu)先保證數(shù)據(jù)的ACID特性。TiKV中的Raft實(shí)現(xiàn)強(qiáng)調(diào)數(shù)據(jù)安全性和一致性所有寫入都必須經(jīng)過(guò)Raft日志復(fù)制和提交過(guò)程。Kafka的高吞吐量?jī)?yōu)先作為消息隊(duì)列Kafka更關(guān)注吞吐量和延遲。KRaft主要用于元數(shù)據(jù)管理消息數(shù)據(jù)本身仍然采用多副本異步復(fù)制機(jī)制在一致性和性能之間取得平衡。4.2 Raft配置參數(shù)的調(diào)優(yōu)差異兩種系統(tǒng)在Raft參數(shù)調(diào)優(yōu)上側(cè)重點(diǎn)不同TiDB的Raft參數(shù)調(diào)優(yōu)// TiKV中重要的Raft配置參數(shù) public class TiKVRaftConfig { // 選舉超時(shí)時(shí)間影響故障檢測(cè)速度 private long raftElectionTimeout 3000; // 3秒 // 心跳間隔Leader維持統(tǒng)治的關(guān)鍵參數(shù) private long raftHeartbeatInterval 500; // 500毫秒 // 最大日志大小影響批量復(fù)制效率 private long raftMaxSizePerMsg 1024 * 1024; // 1MB // 日志復(fù)制并發(fā)度 private int raftReplicationConcurrency 16; }Kafka KRaft的參數(shù)調(diào)優(yōu)// KRaft模式的關(guān)鍵配置 public class KafkaRaftConfig { // 元數(shù)據(jù)日志段大小 private long metadataLogSegmentBytes 100 * 1024 * 1024; // 100MB // 控制器選舉超時(shí) private int controllerQuorumElectionTimeout 1000; // 1秒 // 元數(shù)據(jù)副本拉取超時(shí) private int metadataMaxIdleInterval 500; // 快照保留策略 private long metadataLogMaxSnapshotInterval 3600 * 1000; // 1小時(shí) }4.3 故障恢復(fù)機(jī)制的異同兩種系統(tǒng)在Raft故障恢復(fù)方面都做了大量工作但側(cè)重點(diǎn)不同TiDB的Region故障恢復(fù)當(dāng)某個(gè)TiKV節(jié)點(diǎn)宕機(jī)時(shí)PD會(huì)檢測(cè)到故障并將宕機(jī)節(jié)點(diǎn)上的Leader Region遷移到健康節(jié)點(diǎn)。這個(gè)過(guò)程涉及Raft組的重新選舉和數(shù)據(jù)同步。Kafka的Controller故障恢復(fù)Controller Leader宕機(jī)時(shí)剩余的Controller節(jié)點(diǎn)會(huì)重新選舉。新的Leader需要從日志中恢復(fù)完整的元數(shù)據(jù)狀態(tài)然后通知所有Broker更新元數(shù)據(jù)緩存。5. 面試常見問(wèn)題深度解析5.1 Raft基礎(chǔ)理論相關(guān)問(wèn)題問(wèn)題1Raft如何保證日志的一致性Raft通過(guò)以下機(jī)制保證日志一致性領(lǐng)導(dǎo)唯一性每個(gè)任期最多一個(gè)Leader避免寫沖突日志匹配特性如果兩個(gè)日志條目有相同的索引和任期號(hào)則它們存儲(chǔ)相同的命令狀態(tài)機(jī)安全特性如果一個(gè)Leader在給定的索引處提交了一個(gè)日志條目那么其他服務(wù)器在該索引處不會(huì)應(yīng)用不同的命令問(wèn)題2Raft如何處理網(wǎng)絡(luò)分區(qū)網(wǎng)絡(luò)分區(qū)可能導(dǎo)致腦裂問(wèn)題Raft通過(guò)任期機(jī)制和選舉約束來(lái)應(yīng)對(duì)分區(qū)中的少數(shù)派無(wú)法選舉出Leader因?yàn)樾枰蠖鄶?shù)投票分區(qū)恢復(fù)后擁有更高任期號(hào)的Leader會(huì)強(qiáng)制其他節(jié)點(diǎn)同步日志客戶端請(qǐng)求只會(huì)被當(dāng)前任期的Leader處理過(guò)期的Leader會(huì)拒絕請(qǐng)求5.2 TiDB相關(guān)Raft面試題問(wèn)題3TiDB中Region分裂如何保證數(shù)據(jù)一致性Region分裂是TiDB的重要特性其一致性保證機(jī)制包括分裂操作由PD協(xié)調(diào)源Region的Leader執(zhí)行分裂前暫停源Region的讀寫操作在Raft日志中記錄分裂操作確保所有副本同步創(chuàng)建新的Region并更新路由信息分裂完成后恢復(fù)讀寫服務(wù)問(wèn)題4TiKV如何優(yōu)化Raft的寫入性能TiKV通過(guò)多種技術(shù)優(yōu)化Raft寫入批量提交將多個(gè)小寫入合并為一個(gè)Raft日志條目并行復(fù)制Leader并行向多個(gè)Follower發(fā)送日志條目流水線優(yōu)化不等前一個(gè)RPC響應(yīng)就發(fā)送下一個(gè)請(qǐng)求日志壓縮定期生成快照清理舊的日志條目5.3 Kafka KRaft面試題問(wèn)題5KRaft模式如何避免元數(shù)據(jù)腦裂KRaft通過(guò)Raft協(xié)議的核心特性避免元數(shù)據(jù)腦裂任期號(hào)機(jī)制每個(gè)Controller變更都攜帶任期號(hào)過(guò)期的請(qǐng)求被拒絕多數(shù)派原則只有獲得大多數(shù)Controller認(rèn)可的節(jié)點(diǎn)才能成為L(zhǎng)eader日志連續(xù)性所有元數(shù)據(jù)變更都通過(guò)Raft日志順序記錄和應(yīng)用問(wèn)題6從ZooKeeper遷移到KRaft需要注意什么遷移過(guò)程中需要重點(diǎn)關(guān)注版本兼容性確保所有節(jié)點(diǎn)支持KRaft模式數(shù)據(jù)一致性在元數(shù)據(jù)遷移期間避免配置變更回滾方案準(zhǔn)備好遇到問(wèn)題時(shí)回退到ZooKeeper模式的預(yù)案監(jiān)控告警更新監(jiān)控指標(biāo)和告警規(guī)則6. 生產(chǎn)環(huán)境中的Raft實(shí)踐要點(diǎn)6.1 部署架構(gòu)設(shè)計(jì)建議TiDB集群部署建議至少3個(gè)TiKV節(jié)點(diǎn)保證Raft多數(shù)派可用PD節(jié)點(diǎn)奇數(shù)個(gè)通常3或5個(gè)避免選舉僵局跨機(jī)架或跨可用區(qū)部署增強(qiáng)容災(zāi)能力監(jiān)控Raft相關(guān)指標(biāo)選舉次數(shù)、日志復(fù)制延遲、心跳異常等Kafka KRaft集群部署建議Controller節(jié)點(diǎn)至少3個(gè)分布在不同的物理節(jié)點(diǎn)生產(chǎn)環(huán)境建議使用Combined模式簡(jiǎn)化管理配置合理的日志保留策略避免元數(shù)據(jù)日志無(wú)限增長(zhǎng)設(shè)置適當(dāng)?shù)目煺臻g隔平衡恢復(fù)速度與存儲(chǔ)開銷6.2 性能調(diào)優(yōu)實(shí)戰(zhàn)經(jīng)驗(yàn)TiDB性能調(diào)優(yōu)重點(diǎn)// 監(jiān)控Raft性能的關(guān)鍵指標(biāo) public class TiKVRaftMetrics { // 日志復(fù)制延遲反映網(wǎng)絡(luò)狀況 private long raftReplicationLag; // 提案排隊(duì)時(shí)間反映處理能力 private long raftProposeDuration; // 應(yīng)用提交延遲反映狀態(tài)機(jī)性能 private long raftApplyLogDuration; // 選舉次數(shù)頻繁選舉影響穩(wěn)定性 private long raftLeaderElections; }Kafka KRaft調(diào)優(yōu)要點(diǎn)調(diào)整metadata.log.max.record.bytes.between.snapshots控制快照頻率監(jiān)控Controller切換頻率頻繁切換可能表明網(wǎng)絡(luò)問(wèn)題優(yōu)化元數(shù)據(jù)日志存儲(chǔ)使用高性能SSD提升讀寫速度6.3 故障排查與應(yīng)急處理常見Raft相關(guān)故障及處理頻繁Leader切換檢查網(wǎng)絡(luò)延遲和穩(wěn)定性調(diào)整選舉超時(shí)參數(shù)避免過(guò)于敏感檢查節(jié)點(diǎn)負(fù)載避免因資源不足導(dǎo)致心跳丟失日志復(fù)制延遲高檢查網(wǎng)絡(luò)帶寬和延遲優(yōu)化Raft批量大小參數(shù)檢查Follower節(jié)點(diǎn)IO性能腦裂問(wèn)題處理確認(rèn)網(wǎng)絡(luò)分區(qū)情況手動(dòng)干預(yù)強(qiáng)制指定Leader檢查配置一致性確保所有節(jié)點(diǎn)參數(shù)相同7. 擴(kuò)展學(xué)習(xí)與面試準(zhǔn)備建議7.1 深入學(xué)習(xí)路徑推薦要深入掌握Raft在分布式系統(tǒng)中的應(yīng)用建議按照以下路徑學(xué)習(xí)理論基礎(chǔ)階段閱讀Raft論文原文理解算法核心思想源碼分析階段選擇TiKV或Kafka KRaft的源碼分析Raft實(shí)現(xiàn)細(xì)節(jié)實(shí)踐驗(yàn)證階段搭建測(cè)試集群模擬各種故障場(chǎng)景觀察系統(tǒng)行為性能優(yōu)化階段學(xué)習(xí)調(diào)優(yōu)技巧理解參數(shù)對(duì)系統(tǒng)性能的影響7.2 面試準(zhǔn)備重點(diǎn)領(lǐng)域在準(zhǔn)備分布式系統(tǒng)相關(guān)面試時(shí)應(yīng)重點(diǎn)關(guān)注以下領(lǐng)域算法理解深度不僅要了解Raft流程還要理解其背后的設(shè)計(jì)哲學(xué)和權(quán)衡考慮。能夠?qū)Ρ萊aft與Paxos、Zab等算法的異同。工程實(shí)現(xiàn)細(xì)節(jié)掌握具體系統(tǒng)TiDB、Kafka中Raft的實(shí)現(xiàn)特色和優(yōu)化技巧。了解這些系統(tǒng)如何處理Raft協(xié)議之外的實(shí)際工程問(wèn)題。故障處理經(jīng)驗(yàn)積累實(shí)際運(yùn)維經(jīng)驗(yàn)了解常見故障現(xiàn)象、排查思路和解決方案。面試官往往更看重實(shí)際問(wèn)題解決能力。系統(tǒng)設(shè)計(jì)能力能夠基于Raft設(shè)計(jì)簡(jiǎn)單的分布式系統(tǒng)說(shuō)明在一致性、可用性、分區(qū)容錯(cuò)性之間的權(quán)衡選擇。7.3 實(shí)戰(zhàn)項(xiàng)目建議為了加深對(duì)Raft的理解可以嘗試以下實(shí)戰(zhàn)項(xiàng)目簡(jiǎn)化版Raft實(shí)現(xiàn)用Java或Go語(yǔ)言實(shí)現(xiàn)基本的Raft算法支持領(lǐng)導(dǎo)選舉和日志復(fù)制分布式鍵值存儲(chǔ)基于自實(shí)現(xiàn)的Raft構(gòu)建簡(jiǎn)單的分布式數(shù)據(jù)庫(kù)性能對(duì)比實(shí)驗(yàn)測(cè)試不同參數(shù)配置下Raft集群的性能表現(xiàn)故障注入測(cè)試模擬網(wǎng)絡(luò)分區(qū)、節(jié)點(diǎn)宕機(jī)等故障驗(yàn)證系統(tǒng)容錯(cuò)能力通過(guò)理論學(xué)習(xí)和實(shí)踐結(jié)合不僅能夠應(yīng)對(duì)面試考察更能為實(shí)際分布式系統(tǒng)開發(fā)運(yùn)維工作打下堅(jiān)實(shí)基礎(chǔ)。在面試過(guò)程中結(jié)合具體項(xiàng)目經(jīng)驗(yàn)闡述對(duì)Raft的理解往往比單純背誦理論更能展現(xiàn)技術(shù)深度。