凌晨三點(diǎn),你剛睡著。手機(jī)突然震動(dòng)——支付系統(tǒng)告警,某數(shù)據(jù)庫分片故障。你盯著屏幕,腦子里只有一個(gè)問題:現(xiàn)在遷移數(shù)據(jù),要停服多久?
Stripe的工程師Jimmy Morzaria在QCon舊金山給出了一個(gè)反直覺的答案:零。不是"幾乎零",不是"用戶無感知",是字面意義上的零停機(jī)。他們的支付系統(tǒng)扛著500萬QPS,可靠性達(dá)到5個(gè)9(99.999%),卻能在用戶刷卡的同時(shí),把整個(gè)數(shù)據(jù)庫搬走。
![]()
機(jī)場擴(kuò)建的啟示
Morzaria先講了個(gè)看似無關(guān)的故事。亞特蘭大機(jī)場連續(xù)24年穩(wěn)居全球客運(yùn)量第一,每天起降1700架航班。去年他們干了件瘋狂的事:擴(kuò)建使用了近50年的D航站樓——把寬度從60英尺拉到99英尺,長度增加288英尺。
約束條件是:不能關(guān)航站樓。航空公司要賺錢,乘客要登機(jī),施工隊(duì)要在旁邊拆墻砌磚。他們的解法是:在遠(yuǎn)處預(yù)制700噸的模塊化建筑,再用自行式模塊運(yùn)輸車橫向平移1英里,精準(zhǔn)對(duì)接。
「這和我們的數(shù)據(jù)庫遷移一模一樣。」Morzaria說。Stripe的DocDB(文檔數(shù)據(jù)庫)面臨的困境是:數(shù)據(jù)量在漲,查詢模式在變,硬件會(huì)老化,但支付不能停。每一筆交易背后是一連串的余額校驗(yàn)、風(fēng)控判定、資金劃轉(zhuǎn)——強(qiáng)一致性(strict consistency)是底線,不是可選項(xiàng)。
DocDB的底層設(shè)計(jì)
Stripe沒有直接用現(xiàn)成的MongoDB或Cassandra,而是自研了一套文檔數(shù)據(jù)庫。核心邏輯很樸素:把數(shù)據(jù)按租戶(tenant)分片,但允許跨分片的原子操作。這意味著一個(gè)用戶的錢包余額和交易記錄可能物理上存儲(chǔ)在不同節(jié)點(diǎn),但扣款和記賬必須同時(shí)成功或同時(shí)失敗。
這種設(shè)計(jì)讓水平擴(kuò)展(horizontal sharding)變成剛需。當(dāng)單個(gè)分片的QPS或存儲(chǔ)逼近上限,你得把數(shù)據(jù)切開,搬到新節(jié)點(diǎn)。傳統(tǒng)做法是:鎖表→導(dǎo)出→導(dǎo)入→切換——停機(jī)窗口從分鐘到小時(shí)不等。對(duì)于Stripe,這意味著全球商戶的收款中斷。
Morzaria團(tuán)隊(duì)的做法是邏輯復(fù)制層。他們在源集群和目標(biāo)集群之間搭了一座橋:寫操作先記日志,異步回放;讀操作根據(jù)遷移階段智能路由。關(guān)鍵是狀態(tài)機(jī)——每個(gè)分片處于"源端服務(wù)""雙寫驗(yàn)證""切換中""目標(biāo)端服務(wù)"四種狀態(tài)之一,狀態(tài)轉(zhuǎn)換由協(xié)調(diào)器控制,可回滾。
零停機(jī)的三重場景
Morzaria分享了三個(gè)真實(shí)用例。
第一,水平分片。某租戶數(shù)據(jù)膨脹,需要拆成兩個(gè)分片。遷移過程中,新寫入同時(shí)落到源和目標(biāo),讀請求根據(jù)鍵范圍路由。驗(yàn)證階段比對(duì)校驗(yàn)和,差異率低于閾值才切換。全程支付接口響應(yīng)時(shí)間P99波動(dòng)控制在5%以內(nèi)。
第二,版本升級(jí)。數(shù)據(jù)庫引擎的大版本迭代往往涉及存儲(chǔ)格式變更。Stripe的做法是:用新版本部署一套空集群,邏輯復(fù)制追平數(shù)據(jù),灰度切流。舊集群作為熱備保留72小時(shí),發(fā)現(xiàn)問題秒級(jí)回切。
第三,多租戶遷移。這是最復(fù)雜的場景——把租戶A從物理集群X搬到集群Y,同時(shí)租戶B留在原地。需要保證跨租戶的聚合查詢(比如平臺(tái)級(jí)風(fēng)控統(tǒng)計(jì))結(jié)果一致。他們的解法是:遷移期間,這類查詢走聯(lián)邦層,實(shí)時(shí)合并源和目標(biāo)的結(jié)果集,去重后返回。
「最難的不是技術(shù),是操作紀(jì)律。」Morzaria強(qiáng)調(diào)。每次遷移前必須跑通自動(dòng)化測試矩陣,包括模擬網(wǎng)絡(luò)分區(qū)、磁盤慢IO、時(shí)鐘漂移。生產(chǎn)環(huán)境的每一次狀態(tài)轉(zhuǎn)換都有審計(jì)日志,可追溯到具體工程師和工單。
從5個(gè)9到"無感"的代價(jià)
5.5個(gè)9的可靠性意味著什么?年均停機(jī)時(shí)間不超過2.6分鐘。Stripe把這個(gè)指標(biāo)拆解到每個(gè)子系統(tǒng):網(wǎng)絡(luò)層、存儲(chǔ)層、復(fù)制層、協(xié)調(diào)層。DocDB的零停機(jī)遷移平臺(tái)本身也要滿足同樣的SLA。
Morzaria沒有透露具體代碼量,但提到一個(gè)細(xì)節(jié):復(fù)制層的沖突解決模塊經(jīng)歷了17次重大重構(gòu)。早期版本依賴時(shí)間戳排序,在跨數(shù)據(jù)中心場景下出現(xiàn)因果反轉(zhuǎn);后來改用向量時(shí)鐘,又帶來存儲(chǔ)開銷問題;最終方案是混合邏輯時(shí)鐘(Hybrid Logical Clock),兼顧性能和正確性。
這套系統(tǒng)支撐了什么?Stripe年處理支付額以萬億美元計(jì)。每一筆背后可能觸發(fā)多次DocDB查詢——余額檢查、交易創(chuàng)建、狀態(tài)更新。500萬QPS不是峰值,是日常水位。
特別聲明:以上內(nèi)容(如有圖片或視頻亦包括在內(nèi))為自媒體平臺(tái)“網(wǎng)易號(hào)”用戶上傳并發(fā)布,本平臺(tái)僅提供信息存儲(chǔ)服務(wù)。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.