分散式資料庫數據一致性原理說明與實現

前言

分散式資料庫的數據一致性管理是其最重要的內核技術之一,也是保證分散式資料庫滿足資料庫最基本的ACID特性中的

「一致性」(Consistency)的保障。在分散式技術發展下,數據一致性的解決方法和技術也在不斷的演進,本文就以作者實際研發的分散式資料庫作為案例,介紹分散式資料庫數據一致性的原理以及實際實現。

1.數據一致性

1.1數據一致性是什麼

大部份使用傳統關係型資料庫的DBA在看到「數據一致性」時,第一反應可能都是數據在跨表事務中的數據一致性場景。但是本文介紹的「數據一致性」,指的是「數據在多份副本中存儲時,如何保障數據的一致性」場景。

由於在大數據領域,數據的安全不再由硬體來保證,而是通過軟體手段,通過同時將數據寫入到多個副本中,來確保數據的安全。資料庫在同時向多個副本寫入記錄時,如何確保每個副本數據一致,稱為「數據一致性」。

1.2關係型資料庫如何保障數據一致性

傳統的關係型資料庫對於運行環境--硬體要求都比較高,例如Oracle會建議用戶使用小型機+共享存儲作為資料庫的運行環境,DB2 DPF也同樣建議用戶採用更好的伺服器+高端存儲來搭建資料庫的運行環境。所以在數據存儲安全的技術要求下,傳統關係型資料庫更多是依賴硬體的技術來保障數據的安全性。

因為關係型資料庫的數據安全是基於硬體來保障,並且數據也不會通過同時存儲多份來保障數據的安全,所以關係型資料庫的用戶默認認為數據存儲是一致的。

1.3分散式存儲如何保障數據一致性

本文在討論分散式存儲時,主要指的是大數據產品中的分散式文件系統和分散式資料庫,例如:SequoiaDB和HDFS。

用戶在搞明白分散式存儲的數據一致性原理時,必須要先明白為什麼他們就需要數據一致性,和分散式存儲的數據存儲與關係型資料庫的數據存儲又有什麼區別。

大數據技術的誕生,確確實實讓系統的性能有新的突破,並且支持硬體以水平擴展的方式來獲得線性增長的性能和存儲。這些都是過去傳統關係型資料庫所無法提供的。另外,大數據技術也拋棄了運行環境必須足夠好的硬性要求,而是允許用戶通過批量廉價X86伺服器+本地磁碟的方式搭建規模集群,從而獲得比過去依賴硬體垂直擴展所提供的更強的計算能力和更多的存儲空間。

大數據技術的核心思想就是分散式,將一個大的工作任務分解成多個小任務,然後通過分散式並發操作的方式將其完成,從而提高整個系統的計算效率或者是存儲能力。而在分散式環境下,由於硬體的要求降低,必然需要大數據產品提供另外一個重要的功能--數據安全。

大數據產品在解決數據安全的方式上,都比較接近,簡單來說,就是讓一份數據通過非同步或者同步的方式保存在多台機器上,從而保障數據的安全。

分散式存儲在解決數據安全的技術難點後,又引入了一個新的技術問題,就是如何保障多個副本中的數據一致性。目前SequoiaDB是使用Raft演算法來保證數據在多個副本中一致性。

2.Raft演算法

2.1Raft演算法背景

在分散式環境下,最著名的一致性演算法應該是Paxos演算法,但是由於它實在過於晦澀難懂,並且實現起來極度困難,所以在2013年,Diego Ongaro、John Ousterhout兩個人以易懂(Understandability)為目標設計了一套一致性演算法Raft。Raft演算法最大的特點在於簡單易懂,並且實現起來簡單

2.2Raft演算法概述

與Paxos不同,Raft強調的是易懂,Raft和Paxos一樣只要保證n/2+1節點正常就能夠提供服務。

眾所周知當問題較為複雜時可以把問題分解為幾個小問題來處理,Raft也使用了分而治之的思想。Raft演算法重點解決三個子問題:選舉(Leader election)、日誌複製(Log replication)、安全性(Safety)。

Raft演算法強化了Leader節點的功能,Follower節點的數據只能夠從Leader中獲取,所以Follower節點的實現就變得簡單,只要負責和Leader保持通信,並且接受Leader推送的數據即可。

2.3Raft演算法原理

2.3.1 節點角色

Raft演算法中,對節點的狀態分為3種角色,分別是Leader(領導者)、Follower(追隨者)和Candidate(候選者)。

Leader,負責處理來自客戶端的請求,負責將日誌同步到Follower中,並且保證與Follower之間的heartBeat聯繫;

Follower,當集群剛剛啟動時,所有節點均為Follower狀態,它的工作主要為響應Leader的日誌同步請求,響應Candidate的請求,以及把請求到Follower的事務請求轉發給Leader;

Candidate,選舉Leader時負責投票,選舉出來Leader後,節點將從Candidate狀態變為Leader狀態。

2.3.2 Terms

在分散式環境下,「時間同步」一直都是老大難的技術難題。Raft為了解決這個問題,將時間劃分為一個一個的Term(可以理解為「邏輯時間」)來處理在不同時間段里的數據一致性。

Terms有以下原則

1 每個Term中,至多存在一個Leader

2 某些Term中,有可能存在由於選舉失敗,沒有Leader的情況

3 每個節點自己維護本地的currentTerm

4 每個Term都是一個連續遞增的編號

5 如果Follower的Term編號比別的Follower Term編號小時,該Follower Term編號將更新Term編號,以保持與其他Follower Term編號一致

2.3.3 選舉

Raft的選舉由定時器觸發,每個節點的觸發時間都不相同。

所有的節點在開始時狀態都為Follower,當定時器觸發選舉後Term編號遞增,該節點的狀態由Follower轉為Candidate,並且向其他節點發起RequestVote RPC請求,這時選舉有3種情況可能發生:

1 發起RequestVote的節點收到n/2+1(過半數)個節點的投票,該節點將從Candidate狀態變為Leader狀態,開始向其他節點發送HeartBeat以保持Leader的正常狀態

2 如果收到投票請求後,該節點發現發起投票的節點Term大於自己,則該節點狀態從Candidate轉為Follower,否則保持Candidate狀態,並且拒絕該投票請求

3 選舉期間發生了超時,則Term編號遞增,重新發起選舉

2.3.4 日誌複製

日誌複製主要的作用就是用來保證節點的數據一致性與高可用性。

當Leader被選舉出來後,所有的事務操作都必須要經過Leader處理。這些事務操作成功後,將會被按順序寫入到LOG中,每個LOG都包含一個index編號。

Leader在LOG發生變化後,通過HeartBeat將新的LOG同步到Follower上,Follower在接收到LOG後,再向Leader發送ACK信息,當Leader接到大多數(2/n+1)Follower的ACK信息後,將該LOG設置為已提交,並且Leader將LOG追加到本地磁碟中。

同時Leader將在下一個HeartBeat中,通知所有的Follower將該LOG存儲在各自的本地磁碟中。

2.3.5 安全性

安全性是用於確保每個節點都是按照相同的日誌序列進行執行的安全機制。

如果當某個Follower在同步Leader的日誌時失敗,但是未來該Follower又可能被選舉為Leader時,就有可能導致前一個Leader已經commit的日誌發生覆蓋,這樣就導致了節點執行不同序列的日誌。

Raft的安全性就是用於保證選舉出來的Leader一定包含先前已經commit LOG 的機制,主要遵循的原則如下:

1 每個Term 只能選舉一個Leader;

2 Leader的日誌完整性,則當Candidate重新選舉Leader時,新的Leader必須要包含先前已經commit的LOG;

3 Candidate在選舉新的Leader時,使用Term來保證LOG的完整性;

3.分散式資料庫數據一致性技術實現

以國產原廠的分散式資料庫SequoiaDB為例,SequoiaDB在多副本的部署中,採用Raft演算法保證數據在多副本環境中保持一致。

SequoiaDB集群中,總共包含3中角色節點,分別是協調節點、編目節點和數據節點。由於協調節點本身不存任何數據,所以只有編目節點和數據節點存在事務操作,換言之,編目分區組和數據分區組的副本同步採用Raft演算法保證數據一致性。

3.1編目節點和數據節點的事務日誌介紹

編目節點和數據節點由於都是需要存儲數據的,並且在集群部署中該,為了確保數據的安全,都是建議採用分散式的方式進行部署,所以在數據同步中,需要採用Raft演算法的基本原理進行數據同步。

編目節點和數據節點在存儲數據時,共包含兩大部分,一個真實的數據文件,另一個是事務日誌文件。

SequoiaDB的節點事務日誌,默認情況下由20個64MB(總大小為1.25GB)的文件構成。節點的事務日誌主要包含一個index編號和數據操作內容,index編號保持永遠遞增狀態。

另外,SequoiaDB節點的事務日誌不會永久保存,而是當所有的事務日誌寫滿後,再重新從第一個文件開始進行覆蓋寫入。

3.2編目分區組的數據一致性

由於編目分區組是保存SequoiaDB集群的元信息,數據同步要求高,所以編目分區組的數據一致性要求為強一致性,即每次向編目分區組執行事務操作時,必須要確保所有的編目節點操作成功,才計算該操作執行成功,否則該事務操作將在整個編目分區組中回退事務日誌,以保證分區組內的數據一致性。

另外,編目分區組還有一個比較重要的特性,即編目分區組必須要存在主節點才能夠正常工作,如果老的主節點宕機了,編目分區組暫時沒有主節點,則該編目分區組不能夠對外提供任何事務操作和數據查詢操作。

3.3數據分區組的數據一致性

數據分區組的數據一致性默認情況下為最終一致性性,即只要求主節點執行事務操作成功即視為操作成功,主節點將在未來非同步同步ReplicaLOG到從節點上。

3.4主從節點的事務日誌同步

SequoiaDB的主從節點是通過事務日誌同步來保證數據一致性的,並且主從節點的事務日誌同步是單線程完成。

如果當主節點和從節點的LSN差距為一條記錄,則主節點會主動將最新的事務日誌推送給從節點。

如果主節點和從節點的LSN差距超過一條記錄,則從節點會主動向主節點請求同步事務日誌,主節點收到同步請求後,會將從節點的LSN號到主節點最新的LSN號對應的事務日誌打包一次性發送給從節點。

3.5從節點日誌重放

當從節點獲取到主節點推送過來的事務日誌後,就會自動解析事務日誌和重放。從節點在重放事務日誌時,默認情況下會以10並發來重放事務日誌。

從節點在執行並發重放日誌時有條件限制,即在集合的唯一索引個數<=1的情況下,INSERT、DELETE、UPDATE、LOB WRITE、LOB UPDATE、LOB REMOVE操作可以支持並發重放事務日誌。從節點在做並發重放時,是通過記錄的OID進行打散並發執行,這樣就可以保證對相同記錄的操作不會由於並發重放導致數據不一致。

但是用戶需要注意,從節點在重放事務日誌時, DROP CL操作不能夠支持並發重放。

4.SequoiaDB數據一致性應用

目前SequoiaDB數據分區組的數據一致性是基於集合級別進行配置的。用戶在使用SequoiaDB過程中,可以隨時調整數據一致性的強度。

4.1 創建集合時指定

在一個多副本的SequoiaDB集群中,集合默認的數據一致性行級別為「最終一致性」。用戶可以在創建集合時顯式指定該集合的「數據一致性強度」,例如可以在SequoiaDB Shell中執行以下命令

db.CSNAME.createCL("CLNAME",{ReplSize:3})

ReplSize參數填寫範圍

-1 到 7

參數說明

-1 ,代表彈性強一致性;

例如副本數為3,當所有的副本節點都正常運行時,資料庫將確保數據同時成功寫入3個副本中才提交該事務日誌;

如果其中一個節點宕機,但是該數據分區組中仍然存在主節點,則資料庫需要確保數據同時成功寫入2個副本中才提交事務日誌。

0 ,代表強一致性;

例如副本數為3,當所有的副本節點都正常運行時,資料庫將確保數據同時成功寫入3個副本中才提交該事務日誌;

如果其中一個節點宕機,但是該數據分區組中仍然存在主節點,則資料庫仍然需要確保數據同時成功寫入3個副本中才提交事務日誌,所以當分區組中存在宕機節點,則該數據分區組無法寫入新的記錄。

1-7 數值代表分區組中寫入記錄時,應該確保寫入到多少個節點中,才可以提交該事務日誌,否則認為該事務操作失敗,另外,如果填寫的數值大於數據分區組所有的節點數目,則以數據分區組的最大節點數目為生效RepliSize值,但是在資料庫SDB_SNAP_CATALOG快照中依然顯式用戶填寫的ReplSize數據。

4.2 修改已經存在的集合

如果集合在創建時沒有設置「數據一致性」ReplSize參數,用戶也可以對已經存在的集合進行修改,在SequoiaDB Shell修改命令如下

db.CSNAME.CLNAME.alter({ReplSize:3})

ReplSize的取值範圍和創建集合時一致。

4.3 如何查看集合的ReplSize參數

如果用戶希望檢查當前集合的RepliSize參數值,可以通過資料庫快照進行查看,在SequoiaDB Shell查看命令如下

db.snapshot(SDB_SNAP_CATALOG,{}, {"Name":null, "IsMainCL":null,"MainCLName":null, "ReplSize":null})

列印信息如下

{

"MainCLName":"test.main2",

"Name": "foo.bar2",

"IsMainCL": null,

"ReplSize": null

}

{

"IsMainCL": true,

"Name": "test.main2",

"MainCLName": null,

"ReplSize": null

}

{

"Name": "foo.tt",

"ReplSize": 3,

"IsMainCL": null,

"MainCLName": null

}

5. 總結

分散式的資料庫,通過Raft演算法來確保在分散式情況上數據的一致性,並且編目分區組和數據分區組對數據一致性要求又有所不同,編目分區組始終要求的是數據在多副本請情況下數據強一致性,而數據分區組則可以由用戶在創建集合時來執行數據一致性的強度,強度越高,數據安全性越好,但是執行的效率就會相對較差,反之依然。

目前SequoiaDB在數據一致性場景上,用戶的調整空間較大,可以根據不同的業務要求來調整數據一致性的強度,以滿足業務或追求性能最優,或者數據最安全的技術要求。

詳細請點擊查看

https://blog.csdn.net/u014439239/article/details/79977573?

blog.csdn.net


推薦閱讀:

基於量子糾纏的低延遲雙活存儲系統
分散式系統的雪崩效應
單機存儲引擎的基礎方法
論文筆記:[OSDI14] F4: Facebooks Warm BLOB Storage System
分散式存儲系統演進

TAG:大數據 | 分散式系統 | 分散式存儲 |