共识是分散式计算中重要的基础问题,目标是 让所有节点一致同意某些事情,共识会用在这 2 种情形上面:
Leader election
在 single-leader 资料库中,成为 leader 需要所有节点同意,如此就能在节点故障时,避免不好的 failover 发生(形成 split brain 情况)。
Atomic commit
若资料库能支援多节点的 transaction,我们会就可能会面临有些节点 commit 成功,有些节点 commit 失败的情形,如果我们要维持 transaction 原子性 (Day 1),势必要让所有节点同意 transaction 的结果才行,这个共识问题就是 atomic commit 问题。
首先要来介绍 二阶段 commit (two-phase commit),一个常用来解决 atomic commit 问题的共识演算法。
ACID 的原子性 (Day 1),能使资料库避免一半成功的结果,这在多物件更新 (Day 2) 情况上尤为重要。
transaction 执行在单一资料库节点上时,当使用者询问资料库是他们想 commit transaction,资料库为了让 transaction 更有耐用性,它会先预写 log 到硬碟上,然後再写入 commit 记录到硬碟上,如果资料库在过程中故障,transaction 就能在节点重启时从 log 中恢复状态。
因此,单一资料库节点的 transaction commit 的关键是依赖在资料写入硬碟的顺序上,若 commit 记录在故障前成功写入到硬碟上,就可视为成功 commit ,在此之前,transaction 都有机会中止。
那麽,多节点怎麽办呢?因为原子性的关系,我们无法只发送 commit 讯息到各节点上就好了(因为有些可能失败),所以要透过某种机制协调 & 强制的让所有节点都 commit 成功。
二阶段 commit 是一个实现多节点原子 transaction commit 的算法,能确保所有节点都 commit 或 中止 transaction,二阶段 commit 的基础流程如下图 9-9,让 commit 的过程拆分成二阶段,且多了一个新的元件角色:协调者 (coordinator)。
二阶段 commit 跟 Day 6 的二阶段锁不一样喔,别搞混了。
协调者的工作就是在阶段 1 发生 prepare request 给所有的节点(也称为参与者)问它们是否准备好要 commit 了没,依据节点们的回答,阶段 2 会有两个不同任务:
因为 Day 8 ~ Day 13 讲过的鬼故事,prepare 或 commit request 都有机会遗失,所以接下来就来细看 二阶段 commit 究竟为什麽可以做到所有节点同意某种结果。
因此,这个协定包含 2 个无法回头的关键点:
这些承诺确保了 二阶段 commit 的原子性。
如果协调者在发送 prepare request 前故障,参与者可以安全的中止 transaction,但是一旦参与者接收到了 prepare request 共投了 yes,它就不能单方面中止,它必须等待协调者给它 commit 或 abort 的讯息,如果协调者故障或网路延迟,该参与者什麽也不能做,只能等待,这个状态的参与者称为 in doubt 或 uncertain。
这个情况如下图 9-10,协调者决定 commit 并成功发送 commit request 给 Database 2, 但在发送给 Database 1 前故障了,所以 Database 1 不知道发生什麽状况只能等待。
原则上,参与者节点可以跟其他参与者节点互相沟通问结果,但那不在 二阶段 commit 协定的范畴。
这唯一的解决方法就是协调者节点要恢复,所以协调者才会写它的决定在 transaction log 中,以防从故障中恢复并检测所有在 in-dobut 的参与者节点,当协调者节点恢复时,协调者 log 中所有没有 commit 记录的 transaction 将会中止,所以,2PC 的 commit point 可被归在常规的协调者单一节点上 atomic commit 。
>>: #05 No-code 之旅 — Next.js 的 Pages 与 Routing
为甚麽 「需要」 Kubernetes? 一个走完开发流程之後所产出的软件应用程序(或称系统),都会...
前言 上一篇介绍了Java原生提供的api,这一篇开始介绍其他Reactive Programmin...
故事简述如下 国外小伙 Abada 致力於挖矿普及,到星爸爸喝咖啡、溜自制挖矿平台、顺便再接别人家的...
简单来说,就是呼叫函式内的函式,将记忆体封存在内层。 像这样,我们把 count 封装在 coun...
Golang Validator 资料验证 如果我们有需要做资料或者数据相关的检验,我们可以考虑使用...