raft算法的原理-raft 算法原理
想象一下,你手里拿着一个刚烤好的大奶黄包,面糊在锅里晃晃悠悠,热的、粘的。
这时候你突然手一抖,把它扔进了隔壁那口正在冒烟的凉油里。你心里肯定慌:完了,肯定炸了。 这时候,你的大脑就会本能地启动一个“救命程序”。你启动观察:那个锅底是不是焦了?油是不是冒了烟?你手里的面团是不是还在晃?
什么的,要是面团还在晃,那道焦痕可能只是瞬间的火花? 这就涉及到了 Raft 算法在计算机领域的一个核心隐喻:共识就是稳态。 在大量系统里,比如你启动那个大奶黄包(投票),要么你程序里的某个节点想拉闸断电(请求),但这些东西不能随意乱来。
要是只有一个主节点说了算,那这锅包就糊了,要么断电瞬间,你所有的进程都崩溃了。大家务必得先“站成队”,大家得先“喊一声:我应允”。 Raft 的核心思想就是这种“排队喊话”的节奏。它不像好办的投票,那忒武德了,大家可能是一脸懵逼。Raft 把过程拆成了四步,每一步都有严格的顺序,像是个四步舞曲。 第一步,Leader(老大)。 你先把整个系统盯住,给个 Leader。
这个 Leader 要负责: 1.啥时候启动投票,啥时候终止,每个节点得听清的。 2.哪位要是想断电,得先跟 Leader 打招呼,问“老哥,我能操票了吗?”,Leader 得点头。 3.哪位要是想重启,也得先找 Leader 问“老哥,我还能开机吗?”。 4.最关键的是,Leader 要把大家拉起来。
哪儿出了难题,它得把难题明确指出,然后告诉大家:“我目前把票借给那个没事的节点,它接着干,我回去修。” 这就像你炸奶黄包的时候,你得先问“老哥,我能把火关掉吗?”要是锅底都烧红了,你还能关火吗?这时候你得确认是那个特定的油斑在冒烟,而不是整个锅都在喷火。 第二步,Followers(跟班)。 一旦 Leader 启动工作,那些跟班节点(Follower)就得赶紧找机会跳出来。 Raft 有个挺妙的机制,叫 2-2 原则。 假设你有 4 个节点,一个 Leader,三个跟班。 跟班节点一上来,就得主动找 Leader 说:“老哥,我应允你当老大。” 与此同时,跟班之间也得互相看看:“嘿,你也应允我?咱俩站在一起,挺保险嘛。” 只要你俩站在一起,你就保险了。 可是,要是跟班节点认定 Leader 有难题(比如油忒热),它务必得主动站出来抵制。 这就形成了 2-2 的局面: 跟班 A 找 Leader 说应允,Leader 找跟班 B 说应允。 跟班 B 找 Leader 说抵制,Leader 找跟班 A 说抵制。 最终,Leader 说:“老 A,你应允我;老 B,你抵制我。” 这时候,哪位说了算? 好办点说,只要 Leader 手里有一票赞成(比如 A 和 B 都应允它),它就能持续当老大。
要是 Leader 自己抵制了,那它自己都没票,它自己也出不去。 这个“2-2"的博弈,实际上就是让跟班节点之间先互相“站队”,把内部矛盾先消掉,然后再去跟 Leader 争。 第三步,Leader 的稳定性。 这时候,Leader 还得稳住。 Raft 里有个著名的"3-3"原则。 Leader 手里有 3 个跟班节点(比如 A、B、C)。 跟班 A、B、C 之间先互相投票,哪位应允哪位就证了(A 和 B 应允,A 和 C 应允,B 和 C 应允)。 然后,Leader 去找跟班 A 问:“老 A,你应允我?我应允你。” 跟班 A 找跟班 B 问:“老 B,你应允我这个 Leader?我应允你。” 跟班 B 找跟班 C 问:“老 C,你应允我这个 Leader?我应允你。” 第三轮,跟班 C 找跟班 A 问:“老 A,你应允我这个 Leader?我应允你。” 要是四人都应允,Leader 就稳了。 要是有人说抵制,Leader 就得重新找那些应允它的人。 这就挺严格:要是 Leader 丧失了 2 个跟班的应允,要么新加入的跟班说抵制了它,它就务必退位。退位之后,系统里剩下的跟班(比如 A 和 B),就得重新进行一轮 2-2 的互证。 这时候,A、B 在一起了,又搞定了 2-2 的互证。 哪位接着做 Leader? 要是 A 说:“我应允 B 当老大。”B 说:“我应允 A 当老大。”那哪位还能做? 这就有点意思了,这时候系统里可能就没有 Leader 了。 这时候就得看系统里有没有“新来的”。
要是有新节点 C 加入,且 C 证明白 A 和 B 都应允它,那 C 就赢了。 要是 A 和 B 手里没人了(比如 A 退位,B 也没人),那系统就得重头再来,重新进行 2-2 互证。 这个循环往复,直到有人站出来确认“我应允”,要么有人站出来确认“我不应允”,Leader 就无路可退了。 第四步,New Nodes 的加入。 新来的节点(New Node)如何混进系统? 新节点先把自己拍个照(同步日志),拍完再启动投票。 新节点的投票对象是哪位? 它得先看看系统里哪位是对的。新节点自己不能自己审自己,得先看 Leader。 Leader 说:“我应允你,我先以你的名字投票。” 可是,Leader 务必确保自己手里的票数还在。
也就是说,要是 Leader 自己都退位了,那它之前的票数就不存有了。 故此,新节点的顺序是: 1.确认 Leader 还在位(Leader 的 2-2 互证过程没中断)。 2.确认 Leader 应允你。 3.要是 Leader 应允,新节点就拿着 Leader 的票去跟其他节点混。 这就好比新节点 A 想加入系统,它先问“哪位是对的?”,发现 Leader 还在位且应允它,那它就有资格了。
然后它就能够往 Leader 的队列里排队,要么跟其他跟班节点拼凑团队。 这实际上是个挺残酷的过程,但也保证了系统的鲁棒性。 比如,要是 Leader 突然死了,系统不会直接崩溃。 新节点进来,一看 Leader 不在,那就跳过 Stage 1,直接启动 2-2 互证(新节点跟剩下的跟班互证)。 要是互证成功,它就直接接管 Leader 的职位。 出于 Leader 死了,它自己没票了,它自己没法做 Leader。 这时候,剩下的跟班(比如 A、B)得重新进行 2-2 互证。 要是 A 和 B 都应允了新节点 C,那 C 就成了新的 Leader。 系统持续,没人关心哪位上次是老大,哪位下上次是老大,只要目前大家都在排队应允,系统就稳了。 这就解释了为啥 Raft 如此稳。它不是靠运气,是靠流程。 哪怕系统里某个节点在那儿抽搐、宕机、掉线,只要流程没断,新的节点进来就能通过 2-2 互证要么新节点的逻辑,无缝衔接上。 它把“哪位说了算”这个难题,拆解成了“先内部互证,再外部调度”的阶梯。 就像烤奶黄包,要是你把面糊挤破了,你得先确认是哪个锅,哪个油斑。你没法直接往平底锅里倒面糊,你得先确认是那个大奶黄锅,否则整个锅就糊了。 Raft 就是那个确保你手里那团面糊,不会在锅里突然爆炸的程序逻辑。它通过 Leader 的调度、Followers 的互证、New Nodes 的排队,把所有可能让系统“炸裂”的因素都按住了。 自然,这个逻辑在纯软件世界里,就是靠代码的严谨来实现的。 比如,你写代码的时候,每个函数都得根据类(Class)要么接口(Interface)来调用。你不能直接改底层的 API,你得通过中间件要么框架来调用。
这就好比新节点不能直接修改 Leader 的代码,它得通过 Leader 供给的 API 来操作系统,要么通过新节点逻辑里的规则来操作。 要是代码直接破坏了底层的通信协议,那整个系统就回不去了。 再想想网络。 你在做视频会议。你要开视频,你得先跟对方说“应允”,然后对方也得说“应允”。 你突然发现对方断网了,要么对方在开会,你没法直接“强行”拉通。 你得等对方重新接入,重新发起握手,重新进行那轮 2-2 互证(网络层的握手)。 要是两个节点都应允,视频就通了。 要是两个节点都不应允,那网络就断了。 Raft 算法就是在模拟这个不断重握手、重确认的过程。它不会让节点在毛病状态下运行,也不会让毛病状态持续下去。 故此,Raft 这个名字实际上挺有道理的。 它不是那种一下子给你个结论的算法,而是一个持续的过程。它像一个主持人,确保每一轮对话都有秩序,每个人都先听听别人的声音,再把自己的声音说出来。 最终,当所有人都应允的时候,你才会拿到你想要的结局。 这就是为啥分布式系统要把网络和物理的稳定性结合起来,把软件协议的严谨性,加上数据的一致性校验,最终才拿到一个稳定的共识。 它让系统在面对毛病的时候,不是炸锅,而是冷静下来,重新调整座位,重开那轮 2-2 互证,直到有人站出来确认“我应允”。 这才是它真正的力量所在。
声明:演示网站所有内容,若无特殊说明或标注,均来源于网络转载,仅供学习交流使用,禁止商用。若本站侵犯了你的权益,可联系本站删除。
