歡迎光臨
每天分享高質量文章

高可用簡史

我曾經訪問過一個網站,它有“幾個小時的運營時間”,只有當它的物體網站亮著燈的時候,它才會“開放”。我感到很困惑:電腦每天都能運行,為什麼網站不能每天都開放呢?我已經習慣了互聯網不可思議的可用性。 

然而,在互聯網之前,7*24 小時可用性可不是一件簡單的事。我們想要可用性,但不是從根本上認為應該擁有的東西。我們只在需要的時候才使用電腦;那些電腦是不會坐等一個偶然的請求的。隨著互聯網的發展,那些以前不常見的請求雖然是在當地時間凌晨3點發來,但在全球其他地方卻是黃金營業時間,確保一臺電腦能夠為這些請求提供服務是很重要的。

 

許多系統只依賴一臺計算機來實現這些請求 —— 我們都知道這是一個結局不太好的故事。通常為了保持系統正常運行,我們需要在多台計算機之間分配負載,以滿足我們的需求。然而,分佈式計算儘管有其眾所周知的優點,但也有其尖銳的缺點:特別是同步和冗錯系統中的部分故障。每一代工程師都在重覆這些解決方案,以滿足他們的時間需求。

 

如何將分佈式應用到資料庫中是一個特別有趣的問題,因為這是一個比計算機科學的其他領域發展慢得多的難題。當然,可以使用軟體在本地資料庫中跟蹤一些分佈式計算的結果,但是資料庫本身的狀態只會儲存在一臺機器上。為什麼呢?因為跨機器複製狀態是很難的。

 

在這篇文章中,我們來看看分佈式資料庫在歷史上是如何處理系統中的部分故障的,併在高層次上理解高可用性是什麼樣子的。

 

使用我們已有的武器:主動-被動

 

在過去,資料庫在單個機器上運行。只有一個節點,它處理所有的讀和寫。沒有所謂的“部分故障”;資料庫不是正常就是停機。

 

在互聯網時代的雙重問題考驗下,單一資料庫的方案是完全失效的:首先,計算機是全天候被訪問的,因此停機會直接影響用戶;其次,將計算機置於持續不斷的需求之下,它們更有可能失敗。這個問題顯然的解決方案是擁有多台能夠處理請求的計算機,這就是分佈式資料庫的真正開始。

 

生活在單節點世界中,最自然的解決方案是繼續讓單個節點服務於讀寫,並將其狀態同步到第二台被動機器上 —— 因此,主從備份誕生了。

 

 

主從備份通過在活動節點失敗的情況下使用最新的備份來提升可用性 —— 您可以輕易地開始將流量定向到從節點,從而將其提升為活動節點。只要有可能,您就會用一臺新的被動機器替換掉宕機的服務器(並希望主節點機器在此期間不會出現故障)。

 

 

首先,從主節點複製到從節點是一個同步過程,即在從節點確認複製完成之前,不會提交轉換。問題來了,如果從節點宕機了該怎麼辦?如果備份系統不可用,那麼整個系統就沒有意義了 —— 然而同步複製的確會發生這種情況。

 

 

為了進一步提高可用性,資料可以異步複製。雖然它的體系結構看起來相同,但是它能夠在不影響資料庫可用性的情況下處理主節點或從節點。

 

雖然異步主從備份是又一個進步,但仍有明顯的缺點:

 

  • 當活動節點宕機時,任何尚未複製到從節點的資料都可能丟失 —— 此時客戶端認為資料已完全提交。
  • 通過依賴一臺機器來處理流量,您仍然被限制到一臺機器的最大可用資源上。

 

追逐 5 個 9:擴展到多台機器

 

隨著互聯網的發展,商業需求的規模和複雜性都在增長。對於資料庫來說,這意味著它們需要能夠處理比任何單個節點都能處理的更多流量,提供“始終在線”的高可用性成為了一項重要任務。

 

鑒於許多工程師現在都有從事其他分佈式技術工作的經驗,很明顯,資料庫可以超越單節點主從備份設置,在許多機器上分佈式運行資料庫。

 

分片

 

再一次,最容易開始的地方就是調整你現有的設計,所以工程師通過開發分片將主從複製調整為可伸縮的複製。

 

在這個方案中,您將集群的資料按照某個值(例如行數或主鍵中的惟一值)進行分割,然後將這些段分佈到多個站點中,每個站點都有一個主從複製對。然後,在集群前面添加某種路由技術,將客戶機定向到正確的站點以滿足其請求。

 

 

分片可以讓您在許多機器之間分配工作負載,提高吞吐量,並通過容忍更多的分割槽故障來提供更高的可用性。

 

分片儘管有很多優點,但實現起來比較複雜,並且給團隊帶來了巨大的操作負擔。經過深思熟慮的分片演算法可能會變得非常繁重,以至於路由最終會悄悄進入應用程式的業務邏輯。更糟糕的是,如果您需要修改系統的分片方式(比如更改樣式),那麼通常需要進行大量的工程工作。

 

單節點主從複製系統也提供了事務支持(即使不是強一致性)。然而,在各片之間協調事務的困難是如此複雜,許多分片系統決定完全放棄它們。

 

多活方案

 

考慮到分片資料庫難以管理且功能不全,工程師們開始開發至少能解決其中一個問題的系統。出現的系統仍然不支持事務,但是管理起來非常容易。隨著應用程式正常運行時間需求的增加,幫助團隊滿足 SLA 是一個明智的決定。

 

這些系統背後的原理是,每個站點可以包含集群資料的一部分(或全部),併為其提供讀寫服務。每當一個節點收到寫操作時,它就會將更改傳播到所有需要它的副本的其他節點。為了處理兩個節點收到相同鍵的寫操作的情況,在提交之前需將其他節點的轉換輸入到衝突解決演算法中。考慮到每個站點都是“活動的”,它被稱為多活方案。

 

 

因為每個服務器都可以處理所有資料的讀寫,所以分片更容易實現演算法,部署也更容易管理。

 

就可用性而言,多活方案非常好。如果某個節點失敗,只需將客戶機重定向到另一個包含資料的節點。只要資料的一個副本是實時的,您就可以為它提供讀寫服務。

 

 

雖然這個方案在可用性方面非常出色,但是它的設計從根本上沒法做到一致性。因為每個站點都可以處理鍵的寫入(在故障轉移場景中也是如此),所以在處理資料時保持資料完全同步是非常困難的。相反,這種方法通常是通過衝突解決演算法來協調站點之間的衝突,該演算法對如何“消除”不一致做出粗粒度的決策。

 

因為這個解決方案是在事後完成的,在客戶端已經收到關於某個過程的響應 —— 並且理論上已經基於響應執行了其他業務邏輯之後 —— 多活複製很容易在資料中生成異常。

 

但是,考慮到正常運行時間的溢價,停機的成本被認為大於潛在異常的成本,因此多活成為了主要的備份方案。

 

大規模部署中的一致性問題:一致性和多活可用性

 

雖然多活方案似乎解決了基礎設施面臨的主要問題 —— 可用性,但它只是通過放棄事務來實現的,這使得需要強一致性的系統沒法選擇它。

 

例如,谷歌的廣告業務使用了一個龐大而複雜的 MySQL 分片系統,它嚴重依賴 SQL 來任意查詢資料庫。因為這些查詢常常依賴於二級索引來提高性能,所以它們必須與它們派生的資料保持完全一致。

 

最終,系統變得足夠大,以至於它開始給使用分片的 MySQL 帶來問題,因此他們的工程師開始設想如何能夠同時擁有一個可大規模伸縮的系統,同時能夠提供他們業務所需的強一致性。多活方案缺乏事務支持,這意味著它不是一個可選項,因此他們不得不設計一些新的東西。他們最終得到的是一個基於共識複製的系統,這將保證一致性,也可以提供高可用性。

 

使用一致複製,向節點提交寫操作,然後複製到一些其他節點。一旦大多數節點確認了寫入,就可以進行提交。

 

 

一致性與高可用性

 

這裡的關鍵概念是,一致複製是位於同步複製和異步複製之間的折中方案:需要任意數量的節點來實現同步,但這些節點是什麼並不重要。這意味著集群可以容忍少數節點宕機,而不會影響系統的可用性。(對於宕機的機器的流量狀況等提出警告)

 

 

但是,協商一致的代價是,它需要節點與其他節點通信來執行寫操作。雖然可以採取一些步驟來減少節點之間的延遲,例如將節點放在相同的可用性區域中,但是這會在可用性方面發生權衡。例如,如果所有節點都在同一個資料中心中,那麼它們之間的通信速度很快,但是您無法在整個資料中心宕機的情況下存活下來。將節點分散到多個資料中心會增加寫操作所需的延遲,但可以在整個資料中心離線時不影響應用程式,以此提高可用性。

 

多活可用性

 

CockroachDB 實現了從谷歌 Spanner 論文中獲得的大部分知識(值得註意的是,它不需要原子鐘),其中包括除了一致複製之外的其他特性,這些特性使可用性變得更加簡單。為了描述這是如何工作的,並將其與雙活區分開來,我們創造了多活可用性這個術語。

 

雙活 vs 多活

 

雙活方案通過讓集群中的任何節點為讀寫提供服務來實現可用性,但是只在提交寫操作之後才將它接受的更改傳播到其他節點。

 

而多活方案允許任何節點服務於讀和寫,但確保大多數副本在寫上保持同步(docs),並且只服務於最新版本的副本的讀(doc)。

 

就可用性而言,雙活只需要一個副本就可以同時為兩個寫操作提供服務,而多活方案則需要大多數副本在線以達成一致(這仍然允許系統內部出現部分故障)。

 

然而,這些資料庫的可用性的區別是一致性的差異。雙活資料庫在大多數情況下都能很好地接受寫操作,但是不能保證客戶端能夠在現在或將來讀取資料。另一方面,多活資料庫只有在能夠保證以後可以以一致的方式讀取資料時才接受寫操作。

 

昨天,今天,明天

 

在過去 30 年裡,資料庫可用性已經取得了重大進展,現在已支持全球範圍的部署,這些部署讓我們覺得服務永遠不會停機。該領域的首次嘗試通過主從複製奠定了重要的基礎,但最終,我們需要更好的可用性和更大的規模。

 

在此基礎上,該行業開發了兩種占主導地位的資料庫範例:雙活(Active-Active),用於關註快速寫操作的應用程式;多活(Multi-Active),用於需要一致性的應用程式。

 

我們都能期待有一天可以利用量子糾纏技術,進入管理分佈式狀態的下一個範式。

    赞(0)

    分享創造快樂