天天看點

持續可用與CAP理論 – 一個系統開發者的觀點

持續可用

本文主要針對金融資料庫,認為金融資料庫的持續可用包含兩點:一個是強一緻性;另外一個是高可用性。

資料庫系統必須是強一緻性的系統,這是因為資料庫系統有事務acid的基本要求,而弱一緻系統無法做到。業内也有一些流行的nosql系統,例如各種類dynamo系統,如開源的cassandra,對同一個最小資料機關(同一行資料)允許多台伺服器同時寫入,雖然采用nwr機制處理沖突,但是由于不可能解決多台伺服器之間的時序問題,而隻能支援弱一緻語義。弱一緻語義的問題很多,例如無法支援複雜功能,無法建構嚴謹的測試體系,無法應用到核心場景。雖然弱一緻性系統也有一定的應用場景,但本文認為其不符合核心業務持續可用的要求,不予讨論。

高可用性可以有很多種解釋,實踐中最常見的解釋為:在一台伺服器,一個交換機,一個機房,或者一個地區整體故障後,系統能夠在多長時間内恢複服務。當然,這裡的恢複服務是以保證強一緻性作為前提條件的。如果能夠在秒級(10秒左右)恢複服務,本文認為這個系統是高可用的,絕大部分應用系統都能夠容忍硬體故障導緻的秒級不可用。

cap理論

cap理論網上傳了很多版本,大緻的意思是:一緻性,可用性和分區可容忍性三者隻能取其二,不可兼得。由于分區可容忍性是不可選擇的,是以,系統設計時隻能在一緻性和可用性之間權衡。這就帶來了一個很悲觀的結論:持續可用無法實作。然而,事實是這樣嗎?

首先,我們回到cap理論的原始定義:

c(consistency):a read is guaranteed to return the most recent write for a given client

a(availability):a non-failing node will return a reasonable response within a reasonable amount of time (no error or timeout)

p(partition tolerance):the system will continue to function when network partitions occur.

cap理論的證明也比較直覺,如下:

持續可用與CAP理論 – 一個系統開發者的觀點

左圖中,假設有兩個節點n1和n2,n1和n2之間發生了網絡分區(p),n1寫入新值y,n2一直是老值x,為了保證一緻性(c),讀取n2總是傳回失敗,違反了可用性(a)要求:任何一個沒有發生故障的節點必須在有限時間内傳回結果,不允許為error或者timeout,系統隻能保證cp。

右圖中,從另外一個角度看,假設總是要保證可用性(a),那麼,讀到n2中的老值x,由于x和最新寫入的y不同,違反了一緻性(c)的要求,系統隻能保證ap。

cap中的a與高可用的ha

請讀者會到cap理論中關于a的定義:cap中的a要求任何一個沒有發生故障的節點必須在有限的時間内傳回結果。然而,如果系統能夠做到當某個節點發生網絡分區後,将它從系統中剔除,由其它節點繼續提供服務。雖然沒有滿足cap中a的要求,但是,隻要恢複時間足夠快,也符合高可用的要求。而高可用才是系統設計的本質需求,cap中的a隻是個理論上的需求。

paxos與持續可用 

八卦完了paxos,下面進入正題。lamport和jim gray分别是分布式系統和資料庫領域的代表任務,同屬微軟研究院,不過也是共事多年才坐在一起聊兩個領域的問題。高可用是分布式系統的長項,為了實作高可用,首先必須至少寫三份資料(一主兩備)。這是因為,如果隻寫兩份資料,當一份資料出現故障的時候,另外一份資料永遠無法證明自己是對,也無法證明自己是錯。這就是選舉的價值,類paxos選舉協定允許在超過半數(majority)節點正常的情況下提供服務。是以,當某台伺服器,某個交換機,某個idc甚至某個地區整體故障的時候,隻要不超過整個系統的半數,系統都能夠很快從錯誤中恢複過來,而且完全自動,無需人工幹預。

強一緻性是資料庫的長項,做法就是強同步,oracle,mysql 5.7,國内的mysql定制版本,例如阿裡、網易的mysql版本都支援強一緻性。強同步的問題在于性能損耗,例如傳統資料庫的執行模型(非線程池模型)一般為一個連接配接對應一個工作線程/程序,采用強同步模式後事務的延時必然延長,進而導緻工作線程/程序數增多,高并發情況下日志線程喚醒工作線程導緻的上下文切換開銷也非常大。另外,為了實作高可用,必須同步至少兩個備庫,使得情況進一步惡化。

采用paxos協定的持續可用系統有兩種常見的部署方式:

持續可用與CAP理論 – 一個系統開發者的觀點

第一種部署方式比較簡單,也最為常見。有一個全局paxos服務,例如zookeeper,它和其它機器之間保持租約。master和兩個slave之間保持強同步,事務至少要寫入到master和其中一個slave才可以傳回成功。同一時刻對于同一份資料隻有一個master,全局paxos服務負責選舉,當master出現故障時,選舉日志号最大的slave接替原來的master繼續提供服務。

持續可用與CAP理論 – 一個系統開發者的觀點

第二種部署方式比較純粹,隻出現在少量的分布式資料庫中,例如google spanner,oceanbase 1.0。leader(相當于master)和follower(相當于slave)之間直接采用paxos協定進行資料同步和選舉,相比第一種方案,這種方式實作複雜度要高很多,換來的好處是當機恢複時間更短,系統更優雅。

共享存儲與硬體解決方案

資料庫領域經常采用共享存儲來解決強一緻性問題,主庫将redo日志持久化到共享存儲,如果主庫故障,假設共享存儲是持續可用的,備庫可以從共享存儲中讀取日志恢複系統。共享存儲與share-nothing架構的強同步有何差別呢?共享存儲模式下隻需要部署一個主庫和一個備庫,而share-nothing架構下強同步至少需要一個主庫加兩個備庫。為什麼呢?假設share-nothing架構隻部署了一個主庫和一個備庫,隻要任何一台機器,即使是備庫當機,為了保證強一緻性,整個系統都無法提供服務。顯然,這樣的系統在網際網路業務中幾乎沒有應用場景。

共享存儲本質上是硬體解決方案,相比paxos解決方案,優勢是簡單成熟,在商用資料庫中廣泛使用。問題在于成本高,且依賴硬體本身高可靠和高性能,也無法跨idc部署,隻能容忍單台伺服器故障,無法容忍單個idc故障。

強同步性能

資料庫的性能分為兩個方面:

單個事務的延時:由于多了一次同步操作,單個事務送出的延時加長了。設計系統時能夠做的事情是将同步兩個備庫和主庫寫磁盤這三個操作完全并行起來,使得增加的額外延時隻是三個操作的最大值,而不是三個操作之和。

系統的吞吐量:本質上看,強同步是否影響吞吐量取決于主備之間的網絡帶寬是否成為瓶頸。在采用萬兆網卡或者兩塊千兆網卡的情況下,吞吐量基本沒有影響。

與性能相關聯的一個問題是成本。前面已經提到,基于paxos的持續可用方案至少需要一主兩備,如果資料總是有三份,确實比較浪費。一個做到極緻的系統應該能夠隻需要兩個副本,第三個副本隻存儲redo日志即可。

引入選舉的難點

假設在關系資料庫的基礎上引入全局paxos服務,是否能夠解決高可用問題呢?理論上确實是可以的,不過實施起來難度也不小。這是因為,即使是zookeeper這樣成熟的選舉服務,使用過程中總是會遇到各種各樣的問題,如果期望應用到核心業務,需要對zookeeper系統完全的掌控力。也就是說,假設zookeeper這樣的服務出現問題,需要能夠fix bug,而不是簡單重新開機解決。另外,也需要做一套模拟各種異常的測試系統,確定不會在異常的情況下出現一些嚴重的問題,例如zookeeper選出雙主導緻資料不一緻。總而言之,做一個持續可用的選舉服務并不是簡單地使用開源軟體,這是一個全局服務,要麼不做,要麼就深入下去做到完全掌控。

跨機房問題

跨機房問題分為兩類:同城以及異地。前面已經提到,無論如何實作,強同步方案中單個事務至少增加一次網絡同步延時。對于同城場景,如果網絡環境比較好,例如公司的資料庫服務有專用的光纖或者帶寬比較高,那麼,增加的延時在1~2ms(光折射傳播的時間 + 交換機處理時間),業務是完全可以接受的。是以,可以做到同城持續可用,單個idc故障時,能夠在保證強一緻的前提下很快恢複服務。

對于異地場景,由于網絡延時較大,例如100ms左右,業務往往不可接受。是以,無法做到跨地域持續可用,整個地區故障時,要麼犧牲一緻性,要麼犧牲可用性,如果選擇可用性時可能會丢失最後幾秒内的資料。當然,實際上業務上往往會組合使用各種柔性解決方案,例如涉及到錢的業務停服務,其它業務容忍極端情況下的資料丢失;或者在外部系統中記錄一些資訊,例如記錄哪些使用者的資料不一緻,出現問題是禁止這些使用者的寫服務,其它使用者正常提供服務;或者dba采用各種辦法補資料,等等。

小結

總而言之,在金融資料庫中,由于強一緻性是必選項,是以,要做到持續可用比較困難,但也并不是不可能,cap和持續可用并不沖突。成熟的商業資料庫都是基于共享存儲的,不過基于paxos的持續可用方案開始越來越多地應用到核心場景,例如google spanner,microsoft sql server雲版本,amazon dynamodb,而aliababa oceanbase也在金融核心場景得到了驗證。同時,筆者認為,采用paxos協定,雖然工程難度很高,但是,隻要在實作上做到極緻,在同城的情況下,可以容忍單個idc故障,且性能損耗非常小;而在異地的場景,考慮到光速不可突破,往往由業務在一緻性和可用性之間權衡。越來越多的雲資料庫将會采用paxos來實作持續可用。