分布式數(shù)據(jù)庫數(shù)據(jù)一致性原理說明與實(shí)現(xiàn)

大數(shù)據(jù)

前言

分布式數(shù)據(jù)庫的數(shù)據(jù)一致性管理是其最重要的內(nèi)核技術(shù)之一,也是保證分布式數(shù)據(jù)庫滿足數(shù)據(jù)庫最基本的ACID特性中的 “一致性”(Consistency)的保障。在分布式技術(shù)發(fā)展下,數(shù)據(jù)一致性的解決方法和技術(shù)也在不斷的演進(jìn),本文就以作者實(shí)際研發(fā)的分布式數(shù)據(jù)庫作為案例,介紹分布式數(shù)據(jù)庫數(shù)據(jù)一致性的原理以及實(shí)際實(shí)現(xiàn)。

1.數(shù)據(jù)一致性

1.1數(shù)據(jù)一致性是什么

大部份使用傳統(tǒng)關(guān)系型數(shù)據(jù)庫的DBA在看到“數(shù)據(jù)一致性”時(shí),第一反應(yīng)可能都是數(shù)據(jù)在跨表事務(wù)中的數(shù)據(jù)一致性場(chǎng)景。但是本文介紹的“數(shù)據(jù)一致性”,指的是“數(shù)據(jù)在多份副本中存儲(chǔ)時(shí),如何保障數(shù)據(jù)的一致性”場(chǎng)景。

由于在大數(shù)據(jù)領(lǐng)域,數(shù)據(jù)的安全不再由硬件來保證,而是通過軟件手段,通過同時(shí)將數(shù)據(jù)寫入到多個(gè)副本中,來確保數(shù)據(jù)的安全。數(shù)據(jù)庫在同時(shí)向多個(gè)副本寫入記錄時(shí),如何確保每個(gè)副本數(shù)據(jù)一致,稱為“數(shù)據(jù)一致性”。

1.2關(guān)系型數(shù)據(jù)庫如何保障數(shù)據(jù)一致性

傳統(tǒng)的關(guān)系型數(shù)據(jù)庫對(duì)于運(yùn)行環(huán)境–硬件要求都比較高,例如Oracle會(huì)建議用戶使用小型機(jī)+共享存儲(chǔ)作為數(shù)據(jù)庫的運(yùn)行環(huán)境,DB2 DPF也同樣建議用戶采用更好的服務(wù)器+高端存儲(chǔ)來搭建數(shù)據(jù)庫的運(yùn)行環(huán)境。所以在數(shù)據(jù)存儲(chǔ)安全的技術(shù)要求下,傳統(tǒng)關(guān)系型數(shù)據(jù)庫更多是依賴硬件的技術(shù)來保障數(shù)據(jù)的安全性。

大數(shù)據(jù)

因?yàn)殛P(guān)系型數(shù)據(jù)庫的數(shù)據(jù)安全是基于硬件來保障,并且數(shù)據(jù)也不會(huì)通過同時(shí)存儲(chǔ)多份來保障數(shù)據(jù)的安全,所以關(guān)系型數(shù)據(jù)庫的用戶默認(rèn)認(rèn)為數(shù)據(jù)存儲(chǔ)是一致的。

1.3分布式存儲(chǔ)如何保障數(shù)據(jù)一致性

本文在討論分布式存儲(chǔ)時(shí),主要指的是大數(shù)據(jù)產(chǎn)品中的分布式文件系統(tǒng)和分布式數(shù)據(jù)庫,例如:SequoiaDB和HDFS。

用戶在搞明白分布式存儲(chǔ)的數(shù)據(jù)一致性原理時(shí),必須要先明白為什么他們就需要數(shù)據(jù)一致性,和分布式存儲(chǔ)的數(shù)據(jù)存儲(chǔ)與關(guān)系型數(shù)據(jù)庫的數(shù)據(jù)存儲(chǔ)又有什么區(qū)別。

大數(shù)據(jù)技術(shù)的誕生,確確實(shí)實(shí)讓系統(tǒng)的性能有新的突破,并且支持硬件以水平擴(kuò)展的方式來獲得線性增長(zhǎng)的性能和存儲(chǔ)。這些都是過去傳統(tǒng)關(guān)系型數(shù)據(jù)庫所無法提供的。另外,大數(shù)據(jù)技術(shù)也拋棄了運(yùn)行環(huán)境必須足夠好的硬性要求,而是允許用戶通過批量廉價(jià)X86服務(wù)器+本地磁盤的方式搭建規(guī)模集群,從而獲得比過去依賴硬件垂直擴(kuò)展所提供的更強(qiáng)的計(jì)算能力和更多的存儲(chǔ)空間。

大數(shù)據(jù)技術(shù)的核心思想就是分布式,將一個(gè)大的工作任務(wù)分解成多個(gè)小任務(wù),然后通過分布式并發(fā)操作的方式將其完成,從而提高整個(gè)系統(tǒng)的計(jì)算效率或者是存儲(chǔ)能力。而在分布式環(huán)境下,由于硬件的要求降低,必然需要大數(shù)據(jù)產(chǎn)品提供另外一個(gè)重要的功能–數(shù)據(jù)安全。

大數(shù)據(jù)

大數(shù)據(jù)產(chǎn)品在解決數(shù)據(jù)安全的方式上,都比較接近,簡(jiǎn)單來說,就是讓一份數(shù)據(jù)通過異步或者同步的方式保存在多臺(tái)機(jī)器上,從而保障數(shù)據(jù)的安全。

分布式存儲(chǔ)在解決數(shù)據(jù)安全的技術(shù)難點(diǎn)后,又引入了一個(gè)新的技術(shù)問題,就是如何保障多個(gè)副本中的數(shù)據(jù)一致性。目前SequoiaDB是使用Raft算法來保證數(shù)據(jù)在多個(gè)副本中一致性。

2.Raft算法

2.1Raft算法背景

在分布式環(huán)境下,最著名的一致性算法應(yīng)該是Paxos算法,但是由于它實(shí)在過于晦澀難懂,并且實(shí)現(xiàn)起來極度困難,所以在2013年,Diego Ongaro、John Ousterhout兩個(gè)人以易懂(Understandability)為目標(biāo)設(shè)計(jì)了一套一致性算法Raft。Raft算法最大的特點(diǎn)在于簡(jiǎn)單易懂,并且實(shí)現(xiàn)起來簡(jiǎn)單

2.2Raft算法概述

與Paxos不同,Raft強(qiáng)調(diào)的是易懂,Raft和Paxos一樣只要保證n/2+1節(jié)點(diǎn)正常就能夠提供服務(wù)。

眾所周知當(dāng)問題較為復(fù)雜時(shí)可以把問題分解為幾個(gè)小問題來處理,Raft也使用了分而治之的思想。Raft算法重點(diǎn)解決三個(gè)子問題:選舉(Leader election)、日志復(fù)制(Log replication)、安全性(Safety)。

Raft算法強(qiáng)化了Leader節(jié)點(diǎn)的功能,F(xiàn)ollower節(jié)點(diǎn)的數(shù)據(jù)只能夠從Leader中獲取,所以Follower節(jié)點(diǎn)的實(shí)現(xiàn)就變得簡(jiǎn)單,只要負(fù)責(zé)和Leader保持通信,并且接受Leader推送的數(shù)據(jù)即可。

2.3Raft算法原理

2.3.1??節(jié)點(diǎn)角色

Raft算法中,對(duì)節(jié)點(diǎn)的狀態(tài)分為3種角色,分別是Leader(領(lǐng)導(dǎo)者)、Follower(追隨者)和Candidate(候選者)。

Leader,負(fù)責(zé)處理來自客戶端的請(qǐng)求,負(fù)責(zé)將日志同步到Follower中,并且保證與Follower之間的heartBeat聯(lián)系;

Follower,當(dāng)集群剛剛啟動(dòng)時(shí),所有節(jié)點(diǎn)均為Follower狀態(tài),它的工作主要為響應(yīng)Leader的日志同步請(qǐng)求,響應(yīng)Candidate的請(qǐng)求,以及把請(qǐng)求到Follower的事務(wù)請(qǐng)求轉(zhuǎn)發(fā)給Leader;

Candidate,選舉Leader時(shí)負(fù)責(zé)投票,選舉出來Leader后,節(jié)點(diǎn)將從Candidate狀態(tài)變?yōu)長(zhǎng)eader狀態(tài)。

大數(shù)據(jù)

2.3.2 ?Terms

在分布式環(huán)境下,“時(shí)間同步”一直都是老大難的技術(shù)難題。Raft為了解決這個(gè)問題,將時(shí)間劃分為一個(gè)一個(gè)的Term(可以理解為“邏輯時(shí)間”)來處理在不同時(shí)間段里的數(shù)據(jù)一致性。

Terms有以下原則

每個(gè)Term中,至多存在一個(gè)Leader?某些Term中,有可能存在由于選舉失敗,沒有Leader的情況每個(gè)節(jié)點(diǎn)自己維護(hù)本地的currentTerm每個(gè)Term都是一個(gè)連續(xù)遞增的編號(hào)如果Follower的Term編號(hào)比別的Follower Term編號(hào)小時(shí),該Follower Term編號(hào)將更新Term編號(hào),以保持與其他Follower Term編號(hào)一致

2.3.3 ?選舉

Raft的選舉由定時(shí)器觸發(fā),每個(gè)節(jié)點(diǎn)的觸發(fā)時(shí)間都不相同。

所有的節(jié)點(diǎn)在開始時(shí)狀態(tài)都為Follower,當(dāng)定時(shí)器觸發(fā)選舉后Term編號(hào)遞增,該節(jié)點(diǎn)的狀態(tài)由Follower轉(zhuǎn)為Candidate,并且向其他節(jié)點(diǎn)發(fā)起RequestVote RPC請(qǐng)求,這時(shí)選舉有3種情況可能發(fā)生:

發(fā)起RequestVote的節(jié)點(diǎn)收到n/2+1(過半數(shù))個(gè)節(jié)點(diǎn)的投票,該節(jié)點(diǎn)將從Candidate狀態(tài)變?yōu)長(zhǎng)eader狀態(tài),開始向其他節(jié)點(diǎn)發(fā)送HeartBeat以保持Leader的正常狀態(tài)如果收到投票請(qǐng)求后,該節(jié)點(diǎn)發(fā)現(xiàn)發(fā)起投票的節(jié)點(diǎn)Term大于自己,則該節(jié)點(diǎn)狀態(tài)從Candidate轉(zhuǎn)為Follower,否則保持Candidate狀態(tài),并且拒絕該投票請(qǐng)求選舉期間發(fā)生了超時(shí),則Term編號(hào)遞增,重新發(fā)起選舉

大數(shù)據(jù)

2.3.4 ?日志復(fù)制

日志復(fù)制主要的作用就是用來保證節(jié)點(diǎn)的數(shù)據(jù)一致性與高可用性。

當(dāng)Leader被選舉出來后,所有的事務(wù)操作都必須要經(jīng)過Leader處理。這些事務(wù)操作成功后,將會(huì)被按順序?qū)懭氲絃OG中,每個(gè)LOG都包含一個(gè)index編號(hào)。

Leader在LOG發(fā)生變化后,通過HeartBeat將新的LOG同步到Follower上,F(xiàn)ollower在接收到LOG后,再向Leader發(fā)送ACK信息,當(dāng)Leader接到大多數(shù)(2/n+1)Follower的ACK信息后,將該LOG設(shè)置為已提交,并且Leader將LOG追加到本地磁盤中。

同時(shí)Leader將在下一個(gè)HeartBeat中,通知所有的Follower將該LOG存儲(chǔ)在各自的本地磁盤中。

2.3.5 ?安全性

安全性是用于確保每個(gè)節(jié)點(diǎn)都是按照相同的日志序列進(jìn)行執(zhí)行的安全機(jī)制。

如果當(dāng)某個(gè)Follower在同步Leader的日志時(shí)失敗,但是未來該Follower又可能被選舉為L(zhǎng)eader時(shí),就有可能導(dǎo)致前一個(gè)Leader已經(jīng)commit的日志發(fā)生覆蓋,這樣就導(dǎo)致了節(jié)點(diǎn)執(zhí)行不同序列的日志。

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

每個(gè)Term 只能選舉一個(gè)Leader;Leader的日志完整性,則當(dāng)Candidate重新選舉Leader時(shí),新的Leader必須要包含先前已經(jīng)commit的LOG;Candidate在選舉新的Leader時(shí),使用Term來保證LOG的完整性;

3.分布式數(shù)據(jù)庫數(shù)據(jù)一致性技術(shù)實(shí)現(xiàn)

以國產(chǎn)原廠的分布式數(shù)據(jù)庫SequoiaDB為例,SequoiaDB在多副本的部署中,采用Raft算法保證數(shù)據(jù)在多副本環(huán)境中保持一致。

SequoiaDB集群中,總共包含3中角色節(jié)點(diǎn),分別是協(xié)調(diào)節(jié)點(diǎn)、編目節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn)。由于協(xié)調(diào)節(jié)點(diǎn)本身不存任何數(shù)據(jù),所以只有編目節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn)存在事務(wù)操作,換言之,編目分區(qū)組和數(shù)據(jù)分區(qū)組的副本同步采用Raft算法保證數(shù)據(jù)一致性。

大數(shù)據(jù)

3.1編目節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn)的事務(wù)日志介紹

編目節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn)由于都是需要存儲(chǔ)數(shù)據(jù)的,并且在集群部署中該,為了確保數(shù)據(jù)的安全,都是建議采用分布式的方式進(jìn)行部署,所以在數(shù)據(jù)同步中,需要采用Raft算法的基本原理進(jìn)行數(shù)據(jù)同步。

編目節(jié)點(diǎn)和數(shù)據(jù)節(jié)點(diǎn)在存儲(chǔ)數(shù)據(jù)時(shí),共包含兩大部分,一個(gè)真實(shí)的數(shù)據(jù)文件,另一個(gè)是事務(wù)日志文件。

大數(shù)據(jù)

SequoiaDB的節(jié)點(diǎn)事務(wù)日志,默認(rèn)情況下由20個(gè)64MB(總大小為1.25GB)的文件構(gòu)成。節(jié)點(diǎn)的事務(wù)日志主要包含一個(gè)index編號(hào)和數(shù)據(jù)操作內(nèi)容,index編號(hào)保持永遠(yuǎn)遞增狀態(tài)。

另外,SequoiaDB節(jié)點(diǎn)的事務(wù)日志不會(huì)永久保存,而是當(dāng)所有的事務(wù)日志寫滿后,再重新從第一個(gè)文件開始進(jìn)行覆蓋寫入。

3.2編目分區(qū)組的數(shù)據(jù)一致性

由于編目分區(qū)組是保存SequoiaDB集群的元信息,數(shù)據(jù)同步要求高,所以編目分區(qū)組的數(shù)據(jù)一致性要求為強(qiáng)一致性,即每次向編目分區(qū)組執(zhí)行事務(wù)操作時(shí),必須要確保所有的編目節(jié)點(diǎn)操作成功,才計(jì)算該操作執(zhí)行成功,否則該事務(wù)操作將在整個(gè)編目分區(qū)組中回退事務(wù)日志,以保證分區(qū)組內(nèi)的數(shù)據(jù)一致性。

另外,編目分區(qū)組還有一個(gè)比較重要的特性,即編目分區(qū)組必須要存在主節(jié)點(diǎn)才能夠正常工作,如果老的主節(jié)點(diǎn)宕機(jī)了,編目分區(qū)組暫時(shí)沒有主節(jié)點(diǎn),則該編目分區(qū)組不能夠?qū)ν馓峁┤魏问聞?wù)操作和數(shù)據(jù)查詢操作。

3.3數(shù)據(jù)分區(qū)組的數(shù)據(jù)一致性

數(shù)據(jù)分區(qū)組的數(shù)據(jù)一致性默認(rèn)情況下為最終一致性性,即只要求主節(jié)點(diǎn)執(zhí)行事務(wù)操作成功即視為操作成功,主節(jié)點(diǎn)將在未來異步同步ReplicaLOG到從節(jié)點(diǎn)上。

3.4主從節(jié)點(diǎn)的事務(wù)日志同步

SequoiaDB的主從節(jié)點(diǎn)是通過事務(wù)日志同步來保證數(shù)據(jù)一致性的,并且主從節(jié)點(diǎn)的事務(wù)日志同步是單線程完成。

如果當(dāng)主節(jié)點(diǎn)和從節(jié)點(diǎn)的LSN差距為一條記錄,則主節(jié)點(diǎn)會(huì)主動(dòng)將最新的事務(wù)日志推送給從節(jié)點(diǎn)。

如果主節(jié)點(diǎn)和從節(jié)點(diǎn)的LSN差距超過一條記錄,則從節(jié)點(diǎn)會(huì)主動(dòng)向主節(jié)點(diǎn)請(qǐng)求同步事務(wù)日志,主節(jié)點(diǎn)收到同步請(qǐng)求后,會(huì)將從節(jié)點(diǎn)的LSN號(hào)到主節(jié)點(diǎn)最新的LSN號(hào)對(duì)應(yīng)的事務(wù)日志打包一次性發(fā)送給從節(jié)點(diǎn)。

3.5從節(jié)點(diǎn)日志重放

當(dāng)從節(jié)點(diǎn)獲取到主節(jié)點(diǎn)推送過來的事務(wù)日志后,就會(huì)自動(dòng)解析事務(wù)日志和重放。從節(jié)點(diǎn)在重放事務(wù)日志時(shí),默認(rèn)情況下會(huì)以10并發(fā)來重放事務(wù)日志。

從節(jié)點(diǎn)在執(zhí)行并發(fā)重放日志時(shí)有條件限制,即在集合的唯一索引個(gè)數(shù)<=1的情況下,INSERT、DELETE、UPDATE、LOB WRITE、LOBUPDATE、LOB REMOVE操作可以支持并發(fā)重放事務(wù)日志。從節(jié)點(diǎn)在做并發(fā)重放時(shí),是通過記錄的OID進(jìn)行打散并發(fā)執(zhí)行,這樣就可以保證對(duì)相同記錄的操作不會(huì)由于并發(fā)重放導(dǎo)致數(shù)據(jù)不一致。

但是用戶需要注意,從節(jié)點(diǎn)在重放事務(wù)日志時(shí), DROP CL操作不能夠支持并發(fā)重放。

4.SequoiaDB數(shù)據(jù)一致性應(yīng)用

目前SequoiaDB數(shù)據(jù)分區(qū)組的數(shù)據(jù)一致性是基于集合級(jí)別進(jìn)行配置的。用戶在使用SequoiaDB過程中,可以隨時(shí)調(diào)整數(shù)據(jù)一致性的強(qiáng)度。

4.1 創(chuàng)建集合時(shí)指定

在一個(gè)多副本的SequoiaDB集群中,集合默認(rèn)的數(shù)據(jù)一致性行級(jí)別為“最終一致性”。用戶可以在創(chuàng)建集合時(shí)顯式指定該集合的“數(shù)據(jù)一致性強(qiáng)度”,例如可以在SequoiaDB Shell中執(zhí)行以下命令

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

ReplSize參數(shù)填寫范圍

大數(shù)據(jù)

4.2 修改已經(jīng)存在的集合

如果集合在創(chuàng)建時(shí)沒有設(shè)置“數(shù)據(jù)一致性”ReplSize參數(shù),用戶也可以對(duì)已經(jīng)存在的集合進(jìn)行修改,在SequoiaDB Shell修改命令如下

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

ReplSize的取值范圍和創(chuàng)建集合時(shí)一致。

4.3 如何查看集合的ReplSize參數(shù)

如果用戶希望檢查當(dāng)前集合的RepliSize參數(shù)值,可以通過數(shù)據(jù)庫快照進(jìn)行查看,在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. 總結(jié)

分布式的數(shù)據(jù)庫,通過Raft算法來確保在分布式情況上數(shù)據(jù)的一致性,并且編目分區(qū)組和數(shù)據(jù)分區(qū)組對(duì)數(shù)據(jù)一致性要求又有所不同,編目分區(qū)組始終要求的是數(shù)據(jù)在多副本請(qǐng)情況下數(shù)據(jù)強(qiáng)一致性,而數(shù)據(jù)分區(qū)組則可以由用戶在創(chuàng)建集合時(shí)來執(zhí)行數(shù)據(jù)一致性的強(qiáng)度,強(qiáng)度越高,數(shù)據(jù)安全性越好,但是執(zhí)行的效率就會(huì)相對(duì)較差,反之依然。

目前SequoiaDB在數(shù)據(jù)一致性場(chǎng)景上,用戶的調(diào)整空間較大,可以根據(jù)不同的業(yè)務(wù)要求來調(diào)整數(shù)據(jù)一致性的強(qiáng)度,以滿足業(yè)務(wù)或追求性能最優(yōu),或者數(shù)據(jù)最安全的技術(shù)要求。

極客網(wǎng)企業(yè)會(huì)員

免責(zé)聲明:本網(wǎng)站內(nèi)容主要來自原創(chuàng)、合作伙伴供稿和第三方自媒體作者投稿,凡在本網(wǎng)站出現(xiàn)的信息,均僅供參考。本網(wǎng)站將盡力確保所提供信息的準(zhǔn)確性及可靠性,但不保證有關(guān)資料的準(zhǔn)確性及可靠性,讀者在使用前請(qǐng)進(jìn)一步核實(shí),并對(duì)任何自主決定的行為負(fù)責(zé)。本網(wǎng)站對(duì)有關(guān)資料所引致的錯(cuò)誤、不確或遺漏,概不負(fù)任何法律責(zé)任。任何單位或個(gè)人認(rèn)為本網(wǎng)站中的網(wǎng)頁或鏈接內(nèi)容可能涉嫌侵犯其知識(shí)產(chǎn)權(quán)或存在不實(shí)內(nèi)容時(shí),應(yīng)及時(shí)向本網(wǎng)站提出書面權(quán)利通知或不實(shí)情況說明,并提供身份證明、權(quán)屬證明及詳細(xì)侵權(quán)或不實(shí)情況證明。本網(wǎng)站在收到上述法律文件后,將會(huì)依法盡快聯(lián)系相關(guān)文章源頭核實(shí),溝通刪除相關(guān)內(nèi)容或斷開相關(guān)鏈接。

2017-10-19
分布式數(shù)據(jù)庫數(shù)據(jù)一致性原理說明與實(shí)現(xiàn)
前言 分布式數(shù)據(jù)庫的數(shù)據(jù)一致性管理是其最重要的內(nèi)核技術(shù)之一,也是保證分布式數(shù)據(jù)庫滿足數(shù)據(jù)庫最基本的ACID特性中的 “一致性”(Consistency)的保障。

長(zhǎng)按掃碼 閱讀全文