1. 程式人生 > >Google的分散式關係型資料庫F1和Spanner

Google的分散式關係型資料庫F1和Spanner

 

F1是Google開發的分散式關係型資料庫,主要服務於Google的廣告系統。Google的廣告系統以前使用MySQL,廣告系統的使用者經常需要使用複雜的query和join操作,這就需要設計shard規則時格外注意,儘量將相關資料shard到同一臺MySQL上。擴容時對資料reshard時也需要儘量保證這一點,廣告系統擴容比較艱難。在可用性方面老的廣告系統做的也不夠,尤其是整個資料中心掛掉的情況,部分服務將不可用或者丟資料。對於廣告系統來說,短暫的宕機服務不可用將帶來重大的損失。為了解決擴容/高可用的問題,Google研發了F1,一個基於Spanner(看這裡)的跨資料中心的分散式關係型資料庫,支援ACID,支援全域性索引。2012年初已上線。

F1的幾個特性

高可用

可以說,幾乎都是Spanner搞定的,Spanner通過原子鐘和GPS接收器實現的TrueTime API搞定了跨資料中心時鐘誤差問題,進而搞定了分散式事務的時序問題,從而搞定了對外部的一致性。多個副本的一致通過Paxos搞定。

全域性索引

基於Spanner提供的分散式讀寫事務(嚴格的兩階段鎖+兩階段提交),F1實現了全域性索引。索引表和資料表實際上是兩張表,這兩張表一般來說存在不同的Spanner機器上,兩張表的一致性通過Spanner的分散式讀寫事務解決。在這裡,同一個事務中涉及的全域性索引不宜過多,因為每多一個全域性索引,相當於多一個兩階段提交中的participant,對於分散式事務來說,participant越多,效能越差,並且事務成功的概率越小。

級聯Schema

思想和MegaStore類似,表和表之間有層次關係。將相關表中的相關資料儲存在一臺機器上。比如對於廣告系統來說,就是將一個廣告客戶以及他的compaign等儲存在一起,廣告客戶作為一張表,compaign作為另外一張表,廣告客戶表中每行代表一個廣告客戶,廣告客戶表叫做root表,compaign表叫做子表,廣告客戶表中的每行叫做root記錄,compaign表中行叫做子記錄,那麼同一個廣告客戶下所有的compaign和這個廣告客戶都儲存在同一臺Spanner機器上。這樣做的好處就是一個操作就可以取到所有的相關資料,join很快,不用跨機。

三種事務

  1. 快照讀。 直接利用Spanner提供的快照讀事務
  2. 悲觀事務。 直接利用Spanner提供的讀寫事務,加兩階段鎖
  3. 樂觀事務。 基於Spanner的悲觀事務實現的。這樣的事務分為兩個階段,第一個階段是讀階段,持續時間不限,不加任何鎖,第二個階段是寫階段,即commit事務階段。基本思想是在讀階段將訪問的所有行的最後一次修改時間儲存在F1客戶端,寫階段將所有的時間發到F1,F1開啟一個Spanner的讀寫事務,這個讀寫事務會重新讀取這些行的最後一次修改時間進行check,如果已經變了,說明檢測到了寫寫衝突,事務abort。

F1預設使用樂觀事務,主要考慮瞭如下幾個方面:

  1. 由於讀階段不加鎖,能容忍一些客戶端的誤用導致的錯誤
  2. 同樣,讀階段不加鎖,適合F1中一些需要和終端互動的場景。
  3. 對於一些出錯場景,可以直接在F1 Server進行重試,不需要F1 Client參與。
  4. 由於所有的狀態都在F1 Client端維護的,故某個F1 Server掛掉後,這個請求可以發給其他的F1 Server繼續處理。

當然,這會帶來兩個問題:

  1. 對於不存在的行,沒有最後一次修改時間,那麼在其他讀事務執行期間,同一條語句執行多次返回的行數可能不一樣,這種情況在repeatable read這種隔離級別下是不允許的,這個問題典型的解決方案是gap鎖,即範圍鎖,在F1中,這個鎖可以是root表中root記錄的一列,這個列代表一把gap鎖,只有拿到這把鎖,才能往child表中某個範圍插入行。
  2. 對同一行高併發修改效能低。顯然,樂觀協議不適合這種場景。

部署

Google將廣告系統使用的F1和Spanner叢集部署在美國的5個數據中心,東海岸兩個,西海岸兩個,中間一個。相當於每份資料5個副本,其中東海岸一個數據中心被作為leader資料中心。在spanner的paxos實現中,5個副本中有一個leader副本,所有的對這個副本的讀寫事務都經過它,這個leader副本一般就存在leader資料中心中。由於paxos協議的執行只需要majority響應即可,那麼一次paxos操作的延時基本取決於東海岸的leader資料中心和東海岸另外一個數據中心,和中間那個資料中心之間的延時。從這裡也可以看出,對於寫比較多的F1 Client來說,F1 Client和F1 Server都部署在leader資料中心效能最好。在這個配置下,F1使用者的commit延時大概在50ms到150ms之間。讀延時大約5~10ms。

參考資料

F1: A Distributed SQL Database That Scales

Spanner: Google’s Globally-Distributed Database

分散式事務實現-Spanner

Google NewSQL之F1

F1是Google開發的分散式關係型資料庫,主要服務於Google的廣告系統。Google的廣告系統以前使用MySQL,廣告系統的使用者經常需要使用複雜的query和join操作,這就需要設計shard規則時格外注意,儘量將相關資料shard到同一臺MySQL上。擴容時對資料reshard時也需要儘量保證這一點,廣告系統擴容比較艱難。在可用性方面老的廣告系統做的也不夠,尤其是整個資料中心掛掉的情況,部分服務將不可用或者丟資料。對於廣告系統來說,短暫的宕機服務不可用將帶來重大的損失。為了解決擴容/高可用的問題,Google研發了F1,一個基於Spanner(看這裡)的跨資料中心的分散式關係型資料庫,支援ACID,支援全域性索引。2012年初已上線。

F1的幾個特性

高可用

可以說,幾乎都是Spanner搞定的,Spanner通過原子鐘和GPS接收器實現的TrueTime API搞定了跨資料中心時鐘誤差問題,進而搞定了分散式事務的時序問題,從而搞定了對外部的一致性。多個副本的一致通過Paxos搞定。

全域性索引

基於Spanner提供的分散式讀寫事務(嚴格的兩階段鎖+兩階段提交),F1實現了全域性索引。索引表和資料表實際上是兩張表,這兩張表一般來說存在不同的Spanner機器上,兩張表的一致性通過Spanner的分散式讀寫事務解決。在這裡,同一個事務中涉及的全域性索引不宜過多,因為每多一個全域性索引,相當於多一個兩階段提交中的participant,對於分散式事務來說,participant越多,效能越差,並且事務成功的概率越小。

級聯Schema

思想和MegaStore類似,表和表之間有層次關係。將相關表中的相關資料儲存在一臺機器上。比如對於廣告系統來說,就是將一個廣告客戶以及他的compaign等儲存在一起,廣告客戶作為一張表,compaign作為另外一張表,廣告客戶表中每行代表一個廣告客戶,廣告客戶表叫做root表,compaign表叫做子表,廣告客戶表中的每行叫做root記錄,compaign表中行叫做子記錄,那麼同一個廣告客戶下所有的compaign和這個廣告客戶都儲存在同一臺Spanner機器上。這樣做的好處就是一個操作就可以取到所有的相關資料,join很快,不用跨機。

三種事務

  1. 快照讀。 直接利用Spanner提供的快照讀事務
  2. 悲觀事務。 直接利用Spanner提供的讀寫事務,加兩階段鎖
  3. 樂觀事務。 基於Spanner的悲觀事務實現的。這樣的事務分為兩個階段,第一個階段是讀階段,持續時間不限,不加任何鎖,第二個階段是寫階段,即commit事務階段。基本思想是在讀階段將訪問的所有行的最後一次修改時間儲存在F1客戶端,寫階段將所有的時間發到F1,F1開啟一個Spanner的讀寫事務,這個讀寫事務會重新讀取這些行的最後一次修改時間進行check,如果已經變了,說明檢測到了寫寫衝突,事務abort。

F1預設使用樂觀事務,主要考慮瞭如下幾個方面:

  1. 由於讀階段不加鎖,能容忍一些客戶端的誤用導致的錯誤
  2. 同樣,讀階段不加鎖,適合F1中一些需要和終端互動的場景。
  3. 對於一些出錯場景,可以直接在F1 Server進行重試,不需要F1 Client參與。
  4. 由於所有的狀態都在F1 Client端維護的,故某個F1 Server掛掉後,這個請求可以發給其他的F1 Server繼續處理。

當然,這會帶來兩個問題:

  1. 對於不存在的行,沒有最後一次修改時間,那麼在其他讀事務執行期間,同一條語句執行多次返回的行數可能不一樣,這種情況在repeatable read這種隔離級別下是不允許的,這個問題典型的解決方案是gap鎖,即範圍鎖,在F1中,這個鎖可以是root表中root記錄的一列,這個列代表一把gap鎖,只有拿到這把鎖,才能往child表中某個範圍插入行。
  2. 對同一行高併發修改效能低。顯然,樂觀協議不適合這種場景。

部署

Google將廣告系統使用的F1和Spanner叢集部署在美國的5個數據中心,東海岸兩個,西海岸兩個,中間一個。相當於每份資料5個副本,其中東海岸一個數據中心被作為leader資料中心。在spanner的paxos實現中,5個副本中有一個leader副本,所有的對這個副本的讀寫事務都經過它,這個leader副本一般就存在leader資料中心中。由於paxos協議的執行只需要majority響應即可,那麼一次paxos操作的延時基本取決於東海岸的leader資料中心和東海岸另外一個數據中心,和中間那個資料中心之間的延時。從這裡也可以看出,對於寫比較多的F1 Client來說,F1 Client和F1 Server都部署在leader資料中心效能最好。在這個配置下,F1使用者的commit延時大概在50ms到150ms之間。讀延時大約5~10ms。

參考資料

F1: A Distributed SQL Database That Scales

Spanner: Google’s Globally-Distributed Database

分散式事務實現-Spanner

Google NewSQL之F1