成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Google Spanner 實現全球分布式的事務

云計算 分布式
Spanner 的出現,雄辯地證明了在全球范圍內提供具有強一致性保證的分布式事務是切實可行的。它的核心思想,特別是 TrueTime 的設計,為構建更強大的分布式系統開辟了新的道路。

今天我們來聊聊一個在分布式數據庫領域鼎鼎大名的系統:Google Spanner。這篇 2012 年的論文石破天驚,因為它實現了一件被認為極其困難甚至不切實際的事情: 全球分布式的事務 。

想象一下,你的數據分布在全球各地的數據中心,但你卻可以像操作一臺電腦上的數據庫一樣,執行跨越這些數據中心的事務,并且保證數據的一致性。這聽起來是不是很酷?Spanner 就做到了這一點。

核心挑戰:從 F1 廣告系統說起

要理解 Spanner 為何如此設計,我們得先看看它最初要解決的問題。Google 的廣告后端系統,代號 F1,最初是構建在手動分片的 MySQL 數據庫上的。隨著業務增長,數據集達到了幾十個 TB,手動對這個支撐核心收入的數據庫進行分片和擴容,變成了一場噩夢。上一次折騰,花了兩年多的巨大努力,協調了數十個團隊。

這里的 數據分片(Sharding) 是一種數據庫分區技術,也常被稱為“水平分區”。想象你有一個巨大的、包含數億用戶信息的表,如果把這張表存在一臺服務器上,查詢和寫入的壓力很快就會讓這臺服務器不堪重負。

數據分片就是將這個大表“水平”切開,分成許多更小的、更容易管理的部分,每一部分就叫做一個 分片(shard) 。

在 F1 廣告系統的舊 MySQL 架構中,分片就是 按客戶(customer) 來進行的:

  • 假設 Google 有三個廣告客戶:A、B 和 C。
  • 系統可以將客戶 A 的所有相關數據(比如廣告活動、賬單信息等)全部存放在  Shard 1 ,將客戶 B 的所有數據存放在 Shard 2 ,將客戶 C 的所有數據存放在 Shard 3 。
  • 這樣一來,當需要查詢客戶 A 的數據時,請求會直接路由到管理 Shard 1 的服務器上,而不會影響到其他服務器。這就將巨大的讀寫壓力分散到了多臺服務器上。當客戶數量和數據量持續增長時,這種手動管理和重新分片的過程變得極其復雜和昂貴,這也是 F1 團隊遷移到 Spanner 的主要原因之一。

F1 團隊迫切需要一個新的系統,這個系統需要滿足幾個關鍵需求:

  • 更靈活的分片 :再也不想手動搞數據分片了。
  • 同步復制和自動故障轉移 :MySQL 的主從復制在故障轉移時很麻煩,還可能丟數據。
  • 跨分片的強一致性事務 :業務邏輯需要跨任意數據的事務和一致性讀取。

當時主流的 NoSQL 系統無法滿足 F1 對強事務語義的要求。于是,Spanner 應運而生。

Spanner 藍圖:Paxos、分片與復制

Spanner 的基本架構是將數據分片(sharded),然后將每個分片的副本(replicas)分布在多個地理位置不同的數據中心。這么做的好處顯而易見:

  • 高可用性 :一個數據中心掛了,服務不受影響。
  • 低延遲 :用戶可以就近讀取本地數據中心的副本,速度飛快。

數據的復制和一致性由 Paxos 共識算法來管理,每個數據分片都是一個獨立的 Paxos 組,擁有自己的 log 。

一個 Paxos 組就是負責管理一個數據分片的一組副本(replicas)。 這組副本使用 Paxos 共識算法來就所有的數據修改達成一致,確保數據的一致性和高可用性。每個 Paxos 組都有一個 Leader,負責處理寫入請求。

一個 Paxos 組的多個副本被 刻意地 分布在地理位置分散的多個數據中心里。這正是 Spanner 實現高可用性和災難恢復能力的關鍵。例如,一個 Paxos 組可能有 5 個副本,分布在 3 個不同的數據中心,即使其中一個數據中心因為地震或斷電而完全失效,剩下的副本依然可以選舉出新的 Leader,繼續提供服務。

這里你可能會問, Spanner 可以用 Raft 算法替代 Paxos 嗎?

當然可以。從這篇論文的層面來看,兩者沒有區別。不過,在 Spanner 被設計和構建的那個年代,Raft 算法還沒誕生,而 Google 內部已經有了一套調優得非常好、穩定可靠的 Paxos 實現。所以,選擇 Paxos 是一個非常自然且實際的工程決策。

處理讀寫事務:加了“保險”的兩階段提交

一個分片包含一部分特定的數據,比如客戶 A、B、C 的數據。這些數據 整體 由一個 Paxos 組來管理。數據 D、E、F 可能屬于另一個分片,因此由 另一個獨立的 Paxos 組 來管理。所以,數據 ABC 不會 同時存在于其他分片上。一個事務可能會需要 同時訪問 多個分片的數據(比如從客戶 A 的賬戶轉賬到客戶 D 的賬戶),這種情況下,該事務就需要與多個 Paxos 組(管理客戶 A 的組和管理客戶 D 的組)進行協調。

對于需要修改數據的 讀寫事務(read-write transactions) ,Spanner 沿用了經典的 兩階段提交(Two-Phase Commit, 2PC) 協議,并將其構建在 Paxos 之上,以保證原子性。

過程大致如下:

  1. 客戶端選擇一個 Paxos 組作為 事務協調者(Transaction Coordinator, TC) 。
  2. 所有要寫入的分片(參與者),首先會在其 Leader 副本上獲取 鎖(locks) 。
  3. 接著,參與者通過 Paxos 把“準備”記錄(prepare record)寫入日志,這相當于把鎖和要寫入的新值持久化并復制到了多數副本。
  4. 所有參與者都“準備”好后,協調者會通過 Paxos 記錄一個最終的“提交”或“中止”決定。
  5. 最后,協調者通知所有參與者,參與者記錄最終決定并釋放鎖。

傳統 2PC 的一個巨大痛點是,如果協調者宕機,所有參與者都會持有鎖并陷入阻塞狀態,整個系統可能被卡住。Spanner 的巧妙之處在于, 協調者本身的狀態也是通過 Paxos 復制的 。這意味著即使協調者的 Leader 掛了,Paxos 組內部會選出一個新的 Leader,它能從 log 中恢復狀態,繼續推動事務完成,從而解決了 2PC 的阻塞問題。

當然,這套流程涉及多次跨數據中心的網絡通信,所以讀寫事務的延遲并不低,在美國東西海岸之間完成一次事務,延遲大約在 100 毫秒左右。

快速只讀事務的魔法:快照隔離與時間戳

F1 的工作負載中,絕大部分是 只讀事務(read-only transactions) 。為了極致的性能,Spanner 希望只讀事務能夠:

  • 無鎖 :不使用鎖,避免和讀寫事務互相阻塞。
  • 本地讀 :直接讀取本地數據中心的副本,避免跨數據中心通信。

這就帶來一個核心難題:本地副本的數據可能不是最新的,如何保證讀取到一致的數據呢?

Spanner 的答案是 快照隔離(Snapshot Isolation) 。簡單來說,就是給每個事務分配一個 時間戳(timestamp) 。讀寫事務在提交時獲得一個時間戳,其所有寫入操作都將關聯這個時間戳。只讀事務在開始時獲得一個時間戳,它只能看到所有時間戳早于它的事務的寫入結果,就像在那個時間點給整個數據庫拍了一張快照。

這樣一來,只讀事務就可以在不加鎖的情況下,讀到一份完整且一致的數據。

Spanner 的定海神針:TrueTime API

快照隔離解決了并發事務的視圖問題,但一個新的、更棘手的問題出現了: 時間 。分布式系統中的每臺機器都有自己的時鐘,它們不可能完美同步。如果時鐘不準,會發生什么?

  • 如果只讀事務的時間戳 過大 ,它可能需要等待數據同步,導致延遲增加,但結果是對的。
  • 如果只讀事務的時間戳 過小 ,它可能會讀到一份“舊”的快照,從而錯過一些實際上已經提交的修改。這就違反了 Spanner 承諾的 外部一致性(external consistency) 。

這里,我們就要引出 Spanner 的核心創新,也是它的“定海神針”—— TrueTime 。

TrueTime API 并不返回一個精確的時間點,而是返回一個時間區間 TT.now() = [earliest, latest] 。它保證 真實的絕對時間 一定落在這個區間內。這個區間的寬度(epsilon)代表了時鐘的不確定性,通常只有幾毫秒。Google 通過在每個數據中心部署帶有 GPS 接收器或原子鐘的時間主服務器(time master)來實現這一點。

有了 TrueTime ,Spanner 通過兩條規則來保證外部一致性:

  1. 時間戳分配 :為讀寫事務分配的提交時間戳 ts,是調用 TT.now().latest 的結果。
  2. 提交等待(Commit Wait) :一個讀寫事務在提交并釋放鎖之前,必須等待,直到 TT.now().earliest > ts 。這個等待確保了當事務的寫入結果對外部可見時,它的時間戳 ts 在真實時間中已經成為過去時。

這個“提交等待”機制是關鍵。它保證了如果事務 T1 在真實時間里先于 T2 完成,那么 T1 的時間戳一定小于 T2 的時間戳。這就保證了外部一致性。

Spanner 關于時間的假設與證明

Spanner 的天才之處在于,它并 不追求 完美的時鐘同步,而是 承認并量化 時鐘的不確定性,并在此基礎上構建出嚴格的數學保證。

TrueTime 的保證是什么?

TrueTime API 的核心承諾是:它返回的區間 [earliest, latest]一定包含 真實的絕對時間。我們不知道真實時間在區間的哪個點,但可以 100% 確定它就在這個區間內。這個保證依賴于底層的物理設施—— GPS 和原子鐘的穩定運行,以及對網絡延遲等不確定因素的精確計算。

可以假設時間主服務器(time master)一定準確嗎?

在 Spanner 的模型中,我們必須 信任 這個時間體系能夠提供一個正確的時間 區間 。如果時間主服務器本身發生故障,給出了一個完全錯誤的、與真實時間毫無交集的區間,那么 Spanner 的外部一致性保證確實會被打破。這相當于整個系統的“信任根基”被動搖了。因此,Google 在時間基礎設施的穩定性和糾錯能力上投入了巨大努力,來確保這個基礎假設的成立。

Spanner 如何基于“不確定”的時間實現“確定”的一致性?

關鍵在于 提交等待(Commit Wait) 規則。Spanner 并沒有神奇地消除時間的不確定性,而是通過 等待 來抵消掉這份不確定性。

舉個例子:

  • 一個讀寫事務 T1 準備提交,它獲得了一個時間戳 ts = TT.now().latest
  • 假設此刻的 TrueTime 區間是 [10:00:00.004, 10:00:00.006],那么 ts = 10:00:00.006
  • Commit Wait 規則要求,T1 必須暫停,不能馬上讓其他事務看到它的寫入結果。它必須等到 TT.now().earliest 越過 10:00:00.006 這個時間點。
  • 比如,它一直等到 TrueTime 區間變為 [10:00:00.007, 10:00:00.009] 時,因為 007 > 006,等待結束,T1 的提交才真正對外可見。

通過這個等待,Spanner 保證了當 T1 的寫入結果可見時,它的時間戳 ts 在真實世界里 一定已經成為了過去時 。任何在這之后開始的新事務 T2,獲取到的時間戳一定會晚于 ts,從而保證了 T2 一定能看到 T1 的寫入,實現了外部一致性。

總結一下 :Spanner 并不是假設時鐘是完美的。它將時鐘的不確定性(epsilon)轉化為性能開銷(等待時間)。不確定性越大,Commit Wait 的時間就越長,性能就越差。但無論如何,只要 TrueTime 提供的區間是正確的,外部一致性的 正確性 就能得到保證。

外部一致性到底是什么?

我們剛才反復提到外部一致性。 它和我們常說的線性一致性、可串行化有什么關系呢?

外部一致性(External Consistency) 要求,如果事務 T1 在真實時間中先于事務 T2 開始執行并完成,那么在數據庫的事務歷史中,T1 也必須排在 T2 前面。它的效果等同于將 線性一致性(linearizability) 的概念應用于整個事務,而不僅僅是單個操作。它也等同于 嚴格可串行化(strict serializability) ,即可串行化的順序必須與真實時間的發生順序一致。

那為什么外部一致性如此重要呢?

我們來看一個生動例子。假設你在圣何塞的數據中心,通過一個網頁服務修改了你們團隊共享賬號的密碼。然后你馬上轉身,把新密碼告訴了坐在你旁邊的同事。你的同事立即在圣馬特奧的另一個數據中心嘗試用新密碼登錄。

如果沒有外部一致性,你的同事可能會連接到一個還沒同步到新密碼的數據副本上,導致登錄失敗,系統提示密碼錯誤。這顯然不符合用戶的直覺和預期。外部一致性則保證了你的同事一定能看到你剛剛完成的密碼修改,登錄成功。它保證了系統的行為和真實世界的時間順序是一致的。

Spanner 在真實世界中的應用

最后,我們來回答一個大家可能關心的問題: 真的有人在用 Spanner 嗎?

答案是肯定的,而且是大規模使用。

  • Google 內部有數百個服務依賴 Spanner,包括我們前面提到的 F1 廣告系統,以及 Zanzibar 授權系統等。
  • 它作為 Cloud Spanner ,已經成為 Google Cloud 平臺上的一項核心服務,開放給外部客戶使用。
  • 它的設計思想也深刻影響了業界,比如開源分布式數據庫 CockroachDB 就是基于 Spanner 的設計理念構建的。

Spanner 的出現,雄辯地證明了在全球范圍內提供具有強一致性保證的分布式事務是切實可行的。它的核心思想,特別是 TrueTime 的設計,為構建更強大的分布式系統開辟了新的道路。


責任編輯:武曉燕 來源: Piper蛋窩
相關推薦

2012-09-20 09:58:11

分布式分布式數據庫數據庫

2012-09-29 13:18:23

分布式數據庫Google Span

2022-06-27 08:21:05

Seata分布式事務微服務

2017-07-26 15:08:05

大數據分布式事務

2022-06-21 08:27:22

Seata分布式事務

2020-03-31 08:05:23

分布式開發技術

2019-10-10 09:16:34

Zookeeper架構分布式

2021-12-09 10:45:19

分布式事務框架

2023-01-06 09:19:12

Seata分布式事務

2009-06-19 15:28:31

JDBC分布式事務

2009-09-18 15:10:13

分布式事務LINQ TO SQL

2021-09-29 09:07:37

分布式架構系統

2013-08-09 09:27:31

2019-08-19 10:24:33

分布式事務數據庫

2023-12-26 08:59:52

分布式場景事務機制

2023-09-11 15:40:43

鍵值存儲云服務

2021-02-01 09:35:53

關系型數據庫模型

2025-05-13 02:10:00

2019-06-26 09:41:44

分布式事務微服務

2025-04-29 04:00:00

分布式事務事務消息
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲欧美日韩中文字幕一区二区三区 | 天天澡天天狠天天天做 | 久久另类 | 全部免费毛片在线播放网站 | 久久免费观看一级毛片 | 久久99网| 亚洲免费精品 | www久久久| www.亚洲| 国产精品久久久久久久岛一牛影视 | 精品一区在线 | 亚洲成人一区二区 | 国产精品久久久av | 精品一区二区三区在线视频 | 天堂一区 | 国产欧美日韩精品在线观看 | www.蜜桃av.com| 色婷婷综合久久久中字幕精品久久 | 久久精品国产一区二区三区不卡 | 嫩草网| 欧美成人免费在线视频 | cao在线| 蜜桃日韩 | 日本精品免费 | 国产区精品视频 | 蜜桃在线播放 | 成年人国产在线观看 | 久久精品一级 | 中文字幕av在线播放 | 亚洲成人自拍 | 久久青视频 | 国产一区二区在线免费观看 | 午夜精品在线 | 精品一区二区三区四区在线 | 国产综合在线视频 | 亚洲国产精品第一区二区 | 成人av一区二区三区 | 中文字幕精品视频在线观看 | 日韩中文字幕2019 | 国产激情视频在线免费观看 | 成年免费大片黄在线观看岛国 |