內容目錄
Toggle前言
隨著資料量的增加以及資料庫讀寫流量的增加,傳統資料庫的常見的瓶頸也會開始出現。資料複製(Data Replication)是一種有效解決瓶頸的方法,可以通過在多個節點上複製資料來提高資料庫的效能、可擴展性和可用性。本文將介紹資料複製的三種主要模型:主從複製(Single-leader replication)、多領導者複製(Multi-leader replication)和點對點複製(Leaderless replication),並分析它們的優缺點。
對於基礎資料庫知識還不熟悉的讀者,可以參考此文章 資料庫基礎介紹 – 系統設計 08。對於可擴展性、可用性不熟悉的讀者,也可以參考此文章 軟體設計非功能性特性 – 系統設計 03。
資料複製(Data Replication)
資料複製是一種將資料的副本保留在多個節點上的技術,主要是為了實現以下目的:
- 提高效能:通過將資料分散在多個節點上,可以提高資料庫的讀取和寫入效能。
- 提高可擴展性:隨著資料量的增長,可以通過添加更多節點來擴展資料庫。
- 提高可用性:如果一個節點發生故障,其他節點仍然可以提供資料服務。
資料複製在許多應用程式中都有應用,例如:
- 線上交易處理(OLTP):在 OLTP 系統中,資料複寫可以用來提高資料庫的效能和可用性,用來滿足高並發(High Concurrency)讀寫的需求。
- 災害修復:在無預警的災害中,資料複製可以用來將資料複製到異地備份,防止資料遺失。
複製(Replication)
複製是指在各個節點上,保留多個資料備份,並且最好是地理上有差異的節點,例如:不同國家資料庫的備份。透過這些資料複製,用來實現可用性、可擴展性和效能。
讀者可以思考一個情境,如果今天在單一資料庫的情況下,當資料庫損毀,則整個系統都會受到影響。反之,如已經有多份資料複製在不同的資料庫,則即便一個資料庫損毀,也不會影響到整個系統。
不過以上都是資料複製的優點,但資料複製也帶來了複雜性,以下是我簡單舉出的複雜性例子:
- 如何保持多個資料彼此是一致?
- 應該使用同步複製還是異步複製?
- 如何處理並發寫入?
這篇文章會深入講解資料複製的細節,同首先來解釋同步和非同步複製。
同步複製與非同步複製 (Synchronous versus asynchronous replication)
如果要實現複製,會分成以下兩種,分別為:同步複製以及非同步複製。
這兩者有何主要差異呢?
在同步複製中,主節點(Leader Node)會等待輔助節點(Follower Node)更新資料的確認請求。當主節點收到所有輔助節點的確認後,會像向客戶端(Client Side)回報成功確認。而在非同步複製中,主節點不會等待輔助節點的確認,而是直接更新資料後,向客戶端報告成功。
同步複製優缺點 Synchronous Pros & Cons
同步複製的優點是所有輔助節點(Follower Node)都與主節點(Leader Node)完全同步。但是,優點往往伴隨著缺點,如果輔助節點(Follower Node),因為故障或是其他原因而沒有進行確認,則主節點就會無法回覆用戶端,直到收到成功確認為止。因此這樣的缺點,會導致從主節點到客戶端的回應出現較高的延遲(High Latency)。
非同步複製優缺點 Asynchronous Pros & Cons
非同步複製的優點是即使所有輔助節點(Follower Node)都當機了,主節點(Leader Node)也能繼續運作。相反的,這樣的缺點則是,如果主節點發生故障,未複製到輔助節點的寫入將會遺失。
這邊提供資料庫聖經 Designing Data-Intensive Applications 的圖例,其中 Leader 就是主節點,而Follower 則是輔助節點。
資料複製模型 (Data Replication Models)
接下來我會分別針對以下資料庫複製的模型,來比較其優缺點:
單主/主從複製 (Single Leader / Primary-Secondary Replication)
在主從複製中,一個節點被指定為主節點。主節點負責處理資料寫入,並且將所有寫入發送到輔助節點並保持它們同步。
主從複製非常適合,讀取負載量很大的時候,例如:Youtube 隨時都有成千上萬的人需要去觀看影片,但是比起觀看影片,上傳影片的量不是很多,因此主從複製的模型很適合這樣的情況。我們也可以使用此模型,隨著使用者的增加而擴展資料庫,提高系統的擴展性。當然,如果將資料複製給許多輔助節點,也會可能會有瓶頸。最後如果我們的寫入負載量很大,則主從複製是不合適的。
主從複製的另一個優點是它具有讀取彈性,例如:在主節點發生故障的情況下,輔助節點仍然可以處理讀取請求,因此,對於讀取量很大的系統來說,這是一種不錯的解決資料庫模型。
另外,如果我們使用非同步複製,則會帶來資料複製不一致的問題。可以試想一種情況,如果主節點發生故障,無法將更新的資料傳遞到到輔助節點,則從不同的資料庫讀取的資料可能會看到不一致的資料。因此,如果主節點發生故障,任何資料複製的更新,在輔助節點尚未接收與回覆的情況下,都可能會遺失。
主從複製方式 (Primary-secondary replication methods)
主從複製可以有許多不同的實作方式:
基於語句的複製 (Statement-based replication)
基於語句的複製(Statement-based replication)以下會簡稱為 (SBR),因為我實在找不太到針對繁體中文的翻譯,SBR 是 MySQL 資料庫中使用的方法。在這種實作方式下,主節點可以執行INSERT、UPDATE、DELETE…等等的SQL語法,然後將這些語法寫入日誌檔案。接下來,日誌檔案就會被傳送到輔助節點執行。
雖然SBR,可以解決從主節點複製資料到輔助節點的問題,但其實也有缺點。例如:使用不確定(nondeterministic)的函式,可能會導致主節點和輔助節點上的寫入是不相同的。
何謂不確定(nondeterministic)函式?例如:NOW()獲得當前時間、RAND()獲得一個隨機數,都是不確定函式,每次執行函式都會獲得不同的結果。
預寫日誌 (Write-Ahead Log)
預寫日誌 (Write-Ahead Log)以下會簡稱為(WAL),WAL 是 PostgreSQL 和 Oracle 中,使用的資料複製技術。在WAL中,當交易(transaction)發生時,它最初被記錄在交易日誌檔案(transactional log file)中,然後該日誌檔案被寫入資料庫。接下來,在主資料庫上執行紀錄操作,然後傳送到輔助節點執行。
與 SBR 不同,WAL 將交易日誌去做處理,而不是 SQL 語法,這樣的好處是確保遇到非確定性(nondeterministic)函數時的一致性。另外,WAL 將資料直接寫入磁碟也有助於在發生故障時進行復原。
例如:PostgreSQL 中執行 UPDATE 等操作時,它會先寫入交易日誌檔案和磁碟,然後才處理資料庫。交易日誌中包含交易 ID、資料型別、有被影響的tabla,接下來將變更複製到輔助節點。
當然有優點就有缺點,WAL 的缺點是與資料庫內部結構的緊密耦合,主節點與輔助節點如果要進行軟體升級版本的時候,就會變得複雜。
邏輯複製(Logical Replication)
邏輯複製(Logical Replication) 也有些人會稱為基於行(Row-Based)複製,此方法用在各種關聯式資料庫,包括 PostgreSQL 和 MySQL。在這種方法中,對資料庫所做的操作與修改都會被紀錄,然後複製到輔助節點。
例如,當執行 INSERT 或 UPDATE 等操作時,會在主節點上擷取整個受影響的Row,其中包含指定Row 的所有列值。然後,擷取下來的變更就會在輔助節點上執行,以確保資料與主節點上的資料保持一致。
多領導者複製(Multi-leader replication)
前面介紹完了主從複製,各位應該也會發現,使用非同步複製的主從複製有一個很致命的缺點。當只有一個主節點,所有的寫入操作都必須經過它,這會大幅阻礙其效能。如果主節點發生故障,輔助節點可能就不會更新的資料庫。
多領導者複製則是另一種模型,可以用來解決這種高併發系統的問題。多領導者複製顧名思義,有多個主節點處理寫入並將其發送到其他主節點和輔助節點進行複製。
這種複製模型,對於離線狀態也可以繼續運作的系統來說,是很有優勢的。我們也可以在維運多的資料中心時,使用這個模型,可以使每一個資料中心都有一個主節點。
衝突
多領導者複製比單一領導者複製提供了更好的效能和可擴展性,但此模型也有一個缺點。因為所有主節點都可能同時處理寫入請求,因此它們有可能會修改相同的資料,這樣的情境就稱之為衝突。
例如:假設兩個使用者同時編輯相同的資料欄位。在這種情況下,如果不另外處理這種情境的話,我們就無法得知最終資料的正確性。以下也提供幾種常見處理衝突的方法:
避免衝突
一個很簡單的想法,如果我們要處理衝突,就應該先防止衝突發生。如果系統可以確保特定記錄的所有寫入,都是通過同一個主節點,那就不會有衝突的問題。我們可以將客戶端的請求,導到相同資料中心,這樣就不會有不同資料中心的兩個使用者修改同一份文檔
但是,如果使用者移動到不同的位置,並且現在位於不同的資料中心附近,則一樣會發生衝突。如果發生這種情況,我們需要重新處理請求的流量。在這種情況下,衝突避免方法會失敗並導致同時寫入。
最後寫入獲勝
所有節點使用節點本身的本地端時間,來為每次更新分配一個時間戳記(Timestamp)。當發生衝突時,選擇最新時間戳記去進行更新。不過這種方法也會有盲點,因為在分散式系統中,節點之間的時間是有可能不同的,如果希望做到時間同步,是會有難度的。也因為時間可能不同,時間偏差就會導致資料遺失。
多領導者複製拓撲(Topology)
以下是多領導者複製的拓撲,包含:環形拓撲、星型拓撲、全對全拓撲等。最常見的是全對全拓樸。在星形和圓形拓樸中,也存在類似的缺點,如果其中一個節點發生故障,可能會影響整個系統。這就是為什麼全對全是最常用的拓樸。
點對點/無領導者複製(Peer-to-peer/leaderless replication)
在主從複製中,主節點如果發生問題,就會造成資料庫故障。除了多領導者複製以外,也有另一個模型,點對點(Peer-to-peer Replication) 也可以幫助系統與資料庫實現讀取的可擴展性,但無法提供寫入可擴展性。換言之,可以提供高流量讀取的擴展性。
點對點複製模型透過非主節點來解決這些問題。所有節點權重相等,可以接受讀寫請求。Cassandra 就是使用這樣的資料庫複製模型。
與主從複製一樣,這種複製也會產生不一致,因為當多個節點接受寫入請求時,可能會導致並發寫入。
結語
資料庫複製是一種有效的解決資料庫瓶頸的方法,可以提高資料庫的效能、可擴展性和可用性。但是,不同的複製模型具有不同的優缺點,因此在選擇複製模型時,需要根據具體需求進行權衡。如果喜歡系統設計內容的讀者,可以參考其他相關文章。
相關文章
系統設計元件介紹 Building Block – 系統設計 05
Back-of-the-envelope 封底計算 – 系統設計 04
引用
Designing Data-Intensive Applications