《Spanner: Google’s Globally-Distributed Database》論文總結


Spanner 總結

說明:本文為論文 《Spanner: Google’s Globally-Distributed Database》 的個人理解,難免有理解不到位之處,歡迎交流與指正 。

論文地址Spanner Paper


0. 簡介

Spanner 是由 Google 設計和研發的一款分布式數據庫。它將數據分布在全球范圍內,並支持外部一致性的分布式事務。對於讀寫事務,它使用基於 Paxos 復制容錯的 2PC ;對於只讀事務,它不使用鎖機制,且允許從本地副本執行讀操作,從而提高了只讀事務處理效率。


1. 結構

1.1 Spanner 服務器組織

  • 一個 Spanner 部署稱為一個 universe

  • Spanner 被組織成許多個 zone 的集合

  • zone 是管理部署的基本單元,當新的數據中心加入服務、或者老的數據中心被關閉時,zone 可以被加入到一個運行的系統中,或從中移除。zone 也是物理隔離的單元,在一個數據中心中可能有一個或多個 zone(當屬於不同應用的數據必須被分區存儲到同一數據中心的不同服務器集合中時,一個數據中心就會有多個 zone)。

  • 一個 zone 包含一個 zonemaster 和多個 spanserver

  • zonemaster 把數據分配給 spanserverspanserver 把數據提供給客戶端

  • 客戶端使用每個 zone 上面的 location proxy 來定位可以為自己提供數據的 spanserver

  • universemaster 主要是一個控制台,它顯示了關於 zone 的各種狀態信息,可用於相互之間的調試

  • placement driver 會周期性地與 spanserver 進行交互,來發現那些需要被轉移的數據(或是為了滿足新的副本約束條件、或是為了進行負載均衡)

1.2 SpanServer 構成

  • 在底部,每個 spanserver 負載管理100-1000個稱為 tablet 的數據結構的實例, tablet 實現映射:(key:string, timestamp:int64)->string
  • tablet 的狀態會被存儲到 Colossus 分布式文件系統中
  • 為了支持復制,每個 spanserver 會在每個 tablet 上面實現一個單個的 Paxos 狀態機,每個狀態機都會在相應的 tablet 中保存自己的元數據和日志
  • 副本的集合被稱為 Paxos Group ,即一個數據分片(shard)對應一個 Paxos Group
  • 寫操作要從 Paxos leader 開始執行,讀操作可以從足夠新的副本中直接執行
  • 對於每個是 leader 的副本而言,每個 spanserver 會實現一個 lock table 來實現並發控制
  • 對於每個是 ledaer 的副本而言,每個 spanserver 會實現一個 transaction manager 來支持分布式事務。Paxos Group 中的 leaderparticipant leader,其他副本為 participant slave ;如果一個事務包含了多個 Paxos Group ,其中一個 Paxos Group 會被選為 coordinator ,該組 leadercoordinator leader ,該組其他副本為 coordinator slaves (這些設置是為了支持 two phase commit)。

1.3 目錄

Spanner 支持 目錄,它是包含公共前綴的連續鍵的集合。對目錄的支持,可以讓應用通過選擇合適的鍵來控制數據的局部性。

一個目錄是數據放置的基本單元,屬於一個目錄的所有數據都具有相同的副本配置。當數據在不同的 Paxos Group 之間移動時,會一個目錄一個目錄地轉移。


2. 分布式事務

2.1 讀寫事務

讀寫事務的提交,采用 基於Paxos的兩階段提交 (2PC)

以下述事務為例:

BEGIN:
	x = x + 1
	y = y - 1
END

上圖中一個黃色矩形框為一個 Data ShardPaxos Group ,每個綠圈為一個副本,存儲在不同的 Data Center 。黑色矩形框中的副本為各 Paxos Group 中的 leader

上述讀寫事務的執行過程為(過程與圖中序號對應):

  1. client 為每個事務設置一個事務 IDTID
  2. client 發送讀操作給到 XY 所在 Paxos Groupleader。讀操作執行前要先獲得對應記錄的鎖,鎖由 lock table 提供
  3. 兩個 leader 返回 XY 的當前值給 client
  4. 提交前,先選擇一個 Paxos Group 作為2PCtransaction coordinator (TC) (圖中紅框即為 TC leader),其余 Paxos Grouptransaction participant (TP)。接着,client 發送寫操作給兩個 Paxos Groupleader
  5. 每個 leader 獲取對應記錄的鎖,通過 PaxosPaxos Group 中記錄 PREPARE
  6. 如果記錄好PREPARE,各 leader 回復 TC YES ;若出現故障,恢復 TC NO
  7. TC 接收到所有 TP leader 的回復之后,決定是提交還是中斷。將決定通過 Paxos 記錄在本 Paxos Grouplog 中,發送 COMMIT 通知給所有 TP leader
  8. 每個 TP leader 通過 PaxosTC 的決定記錄在 log 中,之后釋放占用的鎖

2.2 只讀事務

只讀事務可能包含多個讀操作,讀取數據可能位於多個 Paxos Group ,但不包含寫操作。

因為只讀事務占比比較大,所以希望只讀操作執行更快。

對於只讀事務,Spanner 進行了兩個方面的優化:允許從本地副本讀取不使用鎖、2PC、事務管理器

2.2.1 允許從本地副本讀取

Spanner 允許 client 從本地副本讀取數據,這樣就避免了很多 Paxos 以及 data center 之間的通信,可以加快只讀事務的處理速度。

但是本地副本可能不是最新的(由於 Paxosmajority 機制),為解決這個問題,使用 safe time

  • 每個副本都會跟蹤記錄一個值,稱為 safe time\(t_{safe}\)),它是一個副本最近更新后的最大時間戳
  • 如果一個讀操作的時間戳是 \(t\) ,當滿足 \(t<=t_{safe}\) 時,這個副本就可以被這個讀操作讀取

2.2.2 不使用鎖、2PC和事務管理器

Spanner 支持不加鎖的只讀事務,這一特性同樣避免了很多 Paxos 以及 data center 之間的通信,並且不會減慢讀寫事務的處理。

對於不加鎖的只讀事務,為保證正確性,必須滿足:

  • 可序列化:雖然多個事務會並發執行,但是執行結果等同於它們按照一定順序逐一執行的結果
  • 外部一致性:如果 T1T2 開始前提交,則 T2 必須看到 T1 寫操作的結果。

保證正確性的方法是采用 快照隔離 (Snapshot Isolation)

  • 首先同步所有服務器的時鍾
  • 為每一個事務設置一個時間戳
    • 讀寫事務:以提交開始時間作為時間戳
    • 只讀事務:以事務開始時間作為時間戳
  • 事務並發執行的效果與以時間戳順序逐一執行的效果相同
  • 每個副本對於每條記錄都存儲多個時間戳版本,所有讀寫事務的寫操作都是相同的時間戳
  • 只讀事務能看到本事務時間戳之前的數據版本

3. TrueTime

由上述內容可以看到,時間戳在 Spanner 中起到了一個很重要的作用。但是如果不同服務器上的時鍾不同步,則可能導致一些問題:

  • 如果一個只讀事務的時間戳過大,會導致它的時間戳大於副本的 safe time ,讀操作就會阻塞
  • 如果一個只讀事務的時間戳過小,會漏讀一些在該事務准確時間戳之前提交的數據版本(即讀到的數據是過期的),這樣違背了外部一致性

為進行時間同步,Spanner 在每個 data center 設置一些 time master server 。每個 time master 含有一個 GPS receiver 或一個 atomic clock 。其他 server 會從幾個 time master server 中收集投票,獲得時間參考值,從而減少誤差。但是由於網絡延遲原因,得到的時間也會有一定幅度偏移(時間不確定性問題)。

針對時間不確定性問題,Spanner 提供了一個 TrueTime API ,它將時間顯示表達為 TTinterval ,它是一個時間區間,具有有界限的時間不確定性,保證了當前准確時間在這個區間里。TTinterval 的端點是 TTstamp 類型。API 提供了三個方法:

為保證 外部一致性Spanner 設定了兩條規則:

  • Start rule:設事務時間戳為 TT.now().lastest。對於讀寫事務,TT 為開始提交的時間戳;對於只讀事務,TT 為事務開始時間。
  • Commit wait:對於讀寫事務,延遲到 TS < TS.now().earliest 時再提交,保證事務時間戳TS 已經完全過去。

6. 特點

  1. 數據分片存儲在跨越全球的 Paxos 狀態機上,通過並發訪問來提高吞吐量
  2. Spanner 提供了讀和寫操作的外部一致性,以及在一個時間標准下的全球一致性的讀操作
  3. 隨着數據變化和服務器變化,Spanner 可以自動對數據進行重新分片,以進行負載均衡和失敗處理
  4. 應用可以對數據的副本進行控制,如指定哪些數據中心包含哪些數據
  5. Spanner 可以為事務分配全球范圍內有意義的提交時間戳,這些時間戳反映事務序列化的順序,用以滿足外部一致性的要求
  6. 提出了 TrueTime APISpanner 時間戳的保證就是取決於這個 API 的界限
  7. 只讀事務不采用鎖機制,且可以從最新副本上直接讀取數據。由於只讀事務占比大,因此顯著提升了事務處理效率

5. 和 Aurora 的比較

Spanner Aurora
架構 Shared Nothing Shared Disk
可用性 Paxos-based Quorum-based
寫擴展 T F
分庫分表透明性 T F
分布式事務 T F
MySQL/Postgres兼容性 F T

Aurora:主要用於雲上業務,兼容 MySQL/PostgresSQL。通過共享存儲方案避免了二階段提交、分布式事務等復雜的實現,因此開發周期較短。

Spanner:是一種重新設計的數據庫,基於 Paxos 的強同步、對分布式事務的支持以及利用 TrueTime 機制實現的全局一致性讀都是比較強大的功能。但是對 SQL 的兼容性不夠好。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM