概念地圖・Chandy–Lamport 快照
分類:系統
這一頁不只是把一個概念解釋一遍——一張自己畫的結構圖,加上拿台灣情境從頭走一次的實例演練、這個框架什麼時候會騙你,以及它接回 P.A.I.N. 之後長什麼樣。一頁必須交付的三層 →
Lamport 快照:不停機,也能把帳兜得起來
三個點各自報的結存加起來,比昨天多出兩箱。沒有人多做、也沒有人少報,那兩箱是同一批貨,在路上被兩邊各數了一次。分散式系統天天在處理這件事:每個節點只看得到自己,東西還在通道上飛,你卻要一份加起來對得起來的全域帳。Chandy 與 Lamport 在一九八五年給的解法很土——不停機,也不對時鐘,而是沿著每一條通道丟一張標記,讓每個節點在收到標記的那一刻凍結自己,再把凍結前後收到的東西分成兩堆。這張圖畫的就是被那張標記切出來的那條線。
一次快照要收哪五樣
圖上每一種筆觸,各對應一樣要收進帳的東西。少收一樣,加總就會對不起來。
| 要收的東西 | 圖上長什麼樣 | 漏掉它,帳會怎麼壞 |
|---|---|---|
| 各站自己的結存 | 三條水平線上,紅點那一刻手上有的東西 | 沒有基準,後面全都無從對起 |
| 通道 | 站與站之間,那支斜箭頭走的路 | 貨走的路不只一條時,會有一整條路沒被盤到 |
| 標記 | 金色虛線,從發起的那一站往每條通道送出去 | 各站自己挑時間停,切出來的線會歪成不合法的形狀 |
| 在途的東西 | 第二支箭頭,跨過切面的那一批 | 送的人已經扣帳、收的人還沒入帳,總數短少 |
| 切面本身 | 朱紅鋸齒線,把上面四樣切成兩期 | 沒有一條共同的線,兩個人報的數字永遠可以各說各話 |
把這五樣擺在一起看,會發現一件反直覺的事:那條線是斜的,所以快照裡的三個結存並非同一秒鐘量的。它不追求同一秒——條件只有一個:不能出現一筆沒人送過的收貨紀錄。只要沒有任何箭頭從線的右邊指回左邊,這份帳就一定加得起來。
拍之前,先過這四關
這條線畫得成不成立,跟你的系統有多大沒關係,只跟下面四件事有關。每一關都附一句可以現在就問出口的自問。
一、同一條路上,先送的要先到。切面的邏輯建立在「標記後面的東西,一定排在標記後面」。路上只要有插隊,標記就攔不住那些超車的貨——急件另走一台車、系統另開一條快速佇列,都是插隊。自問:同一條路線上先送出去的東西,會不會比後送的晚到?
二、每個點都說得出「此刻手上有幾件」。凍結只佔一瞬間:把自己此刻的結存寫下來,櫃台照常運轉。有些單位平常根本沒有這個數字,只有月底結算才長出來——快照在這種點上跑不起來,因為它手上還沒有一個隨時說得出口的結存。自問:你的分點能不能在被問到的那一秒,說出手上有幾件?
三、在途那段路,帳要掛在人身上。圖上第二支箭頭是整張圖唯一沒有主人的東西:送的人已經放手,收的人還沒接到。快照把它記成通道的狀態,現實裡對應的是一張沒人在看的清單。自問:離開甲、還沒進乙的那一段,帳掛在誰身上?
四、標記要走跟貨同一條路。這是最常被便宜行事破掉的一關。標記若改用群組訊息通知,它會比貨先到,或比貨晚到——切面就切在一個沒有人真的經過的位置上。自問:你的通知走哪條路,貨又走哪條路?
一座市立圖書館的年度盤點,走一遍
底下這座台灣中部的市立圖書館與它的兩個分館,是為了把這個結構講清楚而編出來的示意情境,沒有指涉任何真實機構。過去的做法是閉館兩天清點,兩天等於少服務一千八百六十人次;今年他們決定不關門,改用一張紅色隔板卡當標記。
- 九點整,總館按下結帳鍵:在架與外借合計 12,480 冊,同一分鐘起,每一班調撥車上都放一張紅色隔板卡。帳的起點只有一個
- 十點十二分,分館 A 收到卡:先寫下自己的 6,150 冊,卡片之前到的書算這一期,卡片之後到的算下一期。前後兩堆分得乾淨
- 十一點四十,分館 B 才收到卡:那一班車誤點,B 在這一個半小時裡照常借還,櫃台一秒都沒停。結存 4,918 冊。不停機的價值就在這裡
- 三個運送籃,214 冊:卡片之前離開總館、卡片之後才進 B,兩邊的結存都沒把它算進去,只能記成在途。這一格是唯一沒人會主動報的數字
- 八點五十那一趟側門:一位館員自己開車把 12 冊預約書送去 A,沒有經過調撥車,也就沒有隔板卡。那 12 冊兩邊都沒算,也沒被記成在途
四項加起來是 23,762 冊,系統帳面 23,774 冊,差 12 冊。差額不必全館重盤,因為切面已經把嫌疑範圍縮到「沒有走在通道上的東西」——順著這條線問下去,十分鐘就找到側門那一趟。真正值得記住的接縫在這裡:這一天沒有任何一個館為了盤點停下來,而三份各自獨立寫下的數字,加上一格在途,居然可以互相對帳。館長原本以為要買一套更即時的系統,實際上缺的只是一張卡片,和一條「所有東西都得走同一條路」的規矩。以上為說明結構用的示意情境,僅供理解框架之用。
這條切線什麼時候會騙你
- 它給你的畫面,可能任何一秒鐘都沒有真的存在過。總館的數字是九點寫的,B 館的是十一點四十寫的,中間 B 又借出去好幾百冊。這份快照的價值在於加總對得起來,不在於還原現場。所以拿它回答「今天早上十點整全館到底有幾冊」,答案會是錯的——而它錯得很安靜,因為每一個數字看起來都很精確。
- 只要有人抄近路,這一刀就白切了。側門那 12 冊是規則被繞過留下的痕跡,跟統計誤差無關。演算法假設所有東西都走在被標記走過的通道上,現實裡卻永遠有順路、幫忙、急件這三種例外。快照抓得到差額,抓不到繞路的人——那要靠你把例外變成一條也會被標記經過的通道。
- 帳兜得起來,不保證東西擺在對的地方。總數 23,774 冊完全正確的同時,可能有六成的熱門預約書都積在 B 館,而排隊的人在總館。快照是一把量總量的尺,它對分布這件事完全沉默。看完快照的下一個動作,應該是把同一批數字按地點攤開再看一次。
用痛點的眼光問那幾箱在途
在途那一格,帳上是一個數字,現場是有人在等。
整張圖裡最容易被跳過的就是第二支箭頭。它在帳上只是 214,在現場卻是 214 本被人預約、系統顯示「調撥中」的書,其中有幾本已經調撥了九天。這張切面畫得出那 214 冊走到哪一段路,畫不出等它們的那幾十個人已經等了多久——結構看得見位置,看不見溫度。《痛點》那條線一直是同一句:能被算出來的是流程,算不出來的是誰在難受。所以這張圖真正的用法,是把它當成一份等待清單的入口——當月底對帳表的附件,是它最小的用途。今晚可以做的小動作只有一個:把在途那一欄按停留天數由久到近排一次,最上面那三筆,打電話問一句是誰在等。
關於不停機盤點,常被問到的幾件事
Chandy–Lamport 快照到底在解什麼問題?
解的是「多個點各看各的,怎麼取得一份可以互相對帳的全域狀態」。難處在於沒有共同的時鐘,也不能叫大家停下來。它的答案是沿通道傳一張標記,讓每個點在收到標記時凍結自己,並把凍結前還在路上的東西獨立記成通道狀態。收齊之後,各點結存加上各通道在途,就是一份合法的全域快照。
為什麼不是同一個時間點量的,也算數?
因為它保證的是因果關係不被破壞:快照裡不會出現「收到了、卻沒有人送過」這種紀錄。只要沒有這種紀錄,這份帳就等價於某一種真的可能發生過的執行順序,加總必然平衡。學術上叫一致切割。用圖書館的話講:三個館寫下數字的時刻不同沒關係,只要沒有一本書同時被兩邊算到、也沒有一本書兩邊都不算。
標記要送幾次,會不會沒完沒了?
每個節點對每一條出去的通道只送一次,收到重複的標記就不再轉送。所以總次數等於通道數,是有限的。實務上更常出問題的其實是收不齊——只要有一個點掉線,快照就一直懸著。做法通常是設一個等待上限,逾時就把那條通道標成不完整交給人看,別讓整份帳無限期懸在那裡。
這跟資料庫的快照隔離是同一件事嗎?
不同層次。資料庫的快照隔離活在單一個系統裡,有共同的交易序號可以依靠;Chandy–Lamport 處理的是好幾個各自獨立、只能靠傳訊息溝通的節點。串流系統的檢查點機制(例如 Flink 的 checkpoint)就是它的直系後代,連在資料流裡插一張標記的做法都一樣。
把上一次盤點的差異表翻出來,看短少的那幾筆是不是全在路上。想知道「誰先誰後」在沒有共同時鐘時怎麼定義,可以走一趟同一位作者的邏輯時鐘;想知道網路一斷、一致性要拿什麼去換,那筆帳算在 CAP 三角上。
喜歡這篇文章嗎?
每週幫你拆二本好書,把判斷力、好書金句、好問題,直送你的信箱。
不適合你可隨時退訂 · 每週兩封,陪你把書讀進生活。
送出即表示同意我們依隱私權政策使用你的 email。