如何利用MongoDB實現(xiàn)高性能,高可用的雙活應(yīng)用架構(gòu)?
原創(chuàng)【51CTO.com原創(chuàng)稿件】投資界有一句至理名言——“不要把雞蛋放在同一個籃子里”。說的是投資需要分解風(fēng)險,以免孤注一擲失敗之后造成巨大的損失。
隨著企業(yè)服務(wù)窗口的不斷增加,業(yè)務(wù)中斷對很多企業(yè)意味著毀滅性的災(zāi)難,因此,跨多個數(shù)據(jù)中心的應(yīng)用部署成為了當(dāng)下最熱門的話題之一。
如今,在跨多個數(shù)據(jù)中心的應(yīng)用部署***實踐中,數(shù)據(jù)庫通常負(fù)責(zé)處理多個地理區(qū)域的讀取和寫入,對數(shù)據(jù)變更的復(fù)制,并提供盡可能高的可用性、一致性和持久性。
但是,并非所有的技術(shù)在選擇上都是平等的。例如,一種數(shù)據(jù)庫技術(shù)可以提供更高的可用性保證,卻同時只能提供比另一種技術(shù)更低的數(shù)據(jù)一致性和持久性保證。
本文先分析了在現(xiàn)代多數(shù)據(jù)中心中應(yīng)用對于數(shù)據(jù)庫架構(gòu)的需求。隨后探討了數(shù)據(jù)庫架構(gòu)的種類及優(yōu)缺點,***專門研究 MongoDB 如何適用于這些類別,并最終實現(xiàn)雙活的應(yīng)用架構(gòu)。
雙活的需求
當(dāng)組織考慮在多個跨數(shù)據(jù)中心(或區(qū)域云)部署應(yīng)用時,他們通常會希望使用“雙活”的架構(gòu),即所有數(shù)據(jù)中心的應(yīng)用服務(wù)器同時處理所有的請求。
圖 1:“雙活”應(yīng)用架構(gòu)
如圖 1 所示,該架構(gòu)可以實現(xiàn)如下目標(biāo):
- 通過提供本地處理(延遲會比較低),為來自全球的請求提供服務(wù)。
- 即使出現(xiàn)整個區(qū)域性的宕機(jī),也能始終保持高可用性。
- 通過對多個數(shù)據(jù)中心里服務(wù)器資源的并行使用,來處理各類應(yīng)用請求,并達(dá)到***的平臺資源利用率。
“雙活”架構(gòu)的替代方案是由一個主數(shù)據(jù)中心(區(qū)域)和多個災(zāi)備(DR)區(qū)域(如圖 2 所示)所組成的主-DR(也稱為主-被)架構(gòu)。
圖 2:主-DR 架構(gòu)
在正常運行條件下,主數(shù)據(jù)中心處理請求,而 DR 站點處于空閑狀態(tài)。如果主數(shù)據(jù)中心發(fā)生故障,DR 站點立即開始處理請求(同時變?yōu)榛顒訝顟B(tài))。
一般情況下,數(shù)據(jù)會從主數(shù)據(jù)中心復(fù)制到 DR 站點,以便在主數(shù)據(jù)中心出現(xiàn)故障時,能夠迅速實施接管。
如今,對于雙活架構(gòu)的定義尚未得到業(yè)界的普遍認(rèn)同,上述主-DR 的應(yīng)用架構(gòu)有時也被算作“雙活”。
區(qū)別在于從主站到 DR 站點的故障轉(zhuǎn)移速度是否夠快(通常為幾秒),并且是否能夠自動化(無需人為干預(yù))。在這樣的解釋中,雙活體系架構(gòu)意味著應(yīng)用停機(jī)時間接近于零。
有一種常見的誤解,認(rèn)為雙活的應(yīng)用架構(gòu)需要有多主數(shù)據(jù)庫。這樣理解是錯誤的,因為它曲解了多個主數(shù)據(jù)庫對于數(shù)據(jù)一致性和持久性的把握。
一致性確保了能讀取到先前寫入的結(jié)果,而數(shù)據(jù)持久性則確保了提交的寫入數(shù)據(jù)能夠被***保存,不會產(chǎn)生沖突寫入;或是由于節(jié)點故障所產(chǎn)生的數(shù)據(jù)丟失。
雙活應(yīng)用的數(shù)據(jù)庫需求
在設(shè)計雙活的應(yīng)用架構(gòu)時,數(shù)據(jù)庫層必須滿足如下四個方面的架構(gòu)需求(當(dāng)然,也要具備標(biāo)準(zhǔn)數(shù)據(jù)庫的功能,如具有:豐富的二級索引能力的查詢語言,低延遲地訪問數(shù)據(jù),本地驅(qū)動程序,全面的操作工具等):
- 性能,低延遲讀取和寫入操作。這意味著:能在本地數(shù)據(jù)中心應(yīng)用的節(jié)點上,處理讀取和寫入操作。
- 數(shù)據(jù)持久性,通過向多個節(jié)點的復(fù)制寫入來實現(xiàn),以便在發(fā)生系統(tǒng)故障時,數(shù)據(jù)能保持不變。
- 一致性,確保能讀取之前寫入的結(jié)果,而且在不同地區(qū)和不同節(jié)點所讀到的結(jié)果應(yīng)該相同。
- 可用性,當(dāng)某個節(jié)點、數(shù)據(jù)中心或網(wǎng)絡(luò)連接中斷時,數(shù)據(jù)庫必須能繼續(xù)運行。另外,從此類故障中恢復(fù)的時間應(yīng)盡可能短,一般要求是幾秒鐘。
分布式數(shù)據(jù)庫架構(gòu)
針對雙活的應(yīng)用架構(gòu),一般有三種類型的數(shù)據(jù)庫結(jié)構(gòu):
- 使用兩步式提交的分布式事務(wù)。
- 多主數(shù)據(jù)庫模式,有時也被稱為“無主庫模式”。
- 分割(分片)數(shù)據(jù)庫具有多個主分片,每個主分片負(fù)責(zé)數(shù)據(jù)的某個唯一片區(qū)。
下面讓我們來看看每一種結(jié)構(gòu)的優(yōu)缺點。
兩步式提交的分布式事務(wù)
分布式事務(wù)方法是在單次事務(wù)中更新所有包含某個記錄的節(jié)點,而不是寫完一個節(jié)點后,再(異步)復(fù)制到其他節(jié)點。
該事務(wù)保證了所有節(jié)點都會接收到更新,否則如果某個事務(wù)失敗,則所有節(jié)點都恢復(fù)到之前的狀態(tài)。
雖然兩步式提交協(xié)議可以確保持久性和多節(jié)點的一致性,但是它犧牲了性能。
兩步式提交協(xié)議要求在事務(wù)中所有參與的節(jié)點之間都要進(jìn)行兩步式的通信。即在操作的每個階段,都要發(fā)送請求和確認(rèn),以確保每個節(jié)點同時完成了相同的寫入。
當(dāng)數(shù)據(jù)庫節(jié)點分布在多個數(shù)據(jù)中心時,會將查詢的延遲從毫秒級別延長到數(shù)秒級別。
而在大多數(shù)應(yīng)用,尤其是那些客戶端是用戶設(shè)備(移動設(shè)備、Web 瀏覽器、客戶端應(yīng)用等)的應(yīng)用中,這種響應(yīng)級別是不可接受的。
多主數(shù)據(jù)庫
多主數(shù)據(jù)庫是一種分布式的數(shù)據(jù)庫,它允許某條記錄只在多個群集節(jié)點中一個之上被更新。而寫操作通常會復(fù)制該記錄到多個數(shù)據(jù)中心的多個節(jié)點上。
從表面上看,多主數(shù)據(jù)庫應(yīng)該是實現(xiàn)雙活架構(gòu)的理想方案。它使得每個應(yīng)用服務(wù)器都能不受限地讀取和寫入本地數(shù)據(jù)的副本。但是,它在數(shù)據(jù)一致性上卻有著嚴(yán)重的局限性。
由于同一記錄的兩個(或更多)副本可能在不同地點被不同的會話同時更新。這就會導(dǎo)致相同的記錄會出現(xiàn)兩個不同的版本,因此數(shù)據(jù)庫(有時是應(yīng)用本身)必須通過解決沖突來解決不一致的問題。
常用的沖突解決策略是:最近的更新“獲勝”,或是具有更多修改次數(shù)的記錄“獲勝”。因為如果使用其他更為復(fù)雜的解決策略,則性能上將受到顯著的影響。
這也意味著,從進(jìn)行寫入到完成沖突解決機(jī)制的這個時間段內(nèi),不同的數(shù)據(jù)中心會讀取到某個相同記錄的不同值和沖突值。
分區(qū)(分片)數(shù)據(jù)庫
分區(qū)數(shù)據(jù)庫將數(shù)據(jù)庫分成不同的分區(qū),或稱為分片。每個分片由一組服務(wù)器來實現(xiàn),而每個服務(wù)器都包含一份分區(qū)數(shù)據(jù)的完整副本。這里關(guān)鍵在于每個分片都保持著對數(shù)據(jù)分區(qū)的獨有控制權(quán)。
對于任何給定時間內(nèi)的每個分片來說,由一臺服務(wù)器充當(dāng)主服務(wù)器,而其他服務(wù)器則充當(dāng)其副本。數(shù)據(jù)的讀取和寫入被發(fā)布到主數(shù)據(jù)庫上。
如果主服務(wù)器出于任何原因的(例如硬件或網(wǎng)絡(luò)故障)失敗,則某一臺備用服務(wù)器會自動接任為主服務(wù)器的角色。
數(shù)據(jù)庫中的每條記錄都屬于某個特定的分區(qū),并由一個分片來進(jìn)行管理,以確保它只會被主分片進(jìn)行寫入。分片內(nèi)的記錄映射到每個分片的一個主分片,以確保一致性。
由于集群內(nèi)包含多個分片,因此會有多個主分片(多個主分區(qū)),因此這些主分片可以被分配到不同的數(shù)據(jù)中心,以確保都在每個數(shù)據(jù)中心的本地都能發(fā)生寫入操作,如圖 3 所示:
圖 3:分區(qū)數(shù)據(jù)庫
分片數(shù)據(jù)庫可用于實現(xiàn)雙活的應(yīng)用架構(gòu),其方法是:至少部署與數(shù)據(jù)中心一樣多的分片,并為分片分配主分片,以便每個數(shù)據(jù)中心至少有一個主分片,如圖 4 所示:
圖 4:具有分片數(shù)據(jù)庫的雙活架構(gòu)
另外,通過配置分片能保證每個分片在各種數(shù)據(jù)中心里至少有一個副本(數(shù)據(jù)的副本)。
例如,圖 4 中的圖表描繪了跨三個數(shù)據(jù)中心的分布式數(shù)據(jù)庫架構(gòu):
- 紐約(NYC)
- 倫敦(LON)
- 悉尼(SYD)
群集有三個分片,每個分片有三個副本:
- NYC 分片在紐約有一個主分片,在倫敦和悉尼有副本。
- LON 分片在倫敦有一個主分片,在紐約和悉尼有副本。
- SYD 分片在悉尼有一個主分片,在倫敦和紐約有副本。
通過這種方式,每個數(shù)據(jù)中心都有來自所有分片的副本,因此本地應(yīng)用服務(wù)器可以讀取整個數(shù)據(jù)集和一個分片的主分片,以便在其本地進(jìn)行寫入操作。
分片數(shù)據(jù)庫能滿足大多數(shù)使用場景的一致性和性能要求。由于讀取和寫入發(fā)生在本地服務(wù)器上,因此性能會非常好。
從主分片中讀取時,由于每條記錄只能分配給一個主分片,因此保證了一致性。
例如:我們在美國的新澤西州和俄勒岡州有兩個數(shù)據(jù)中心,那么我們可以根據(jù)地理區(qū)域(東部和西部)來分割數(shù)據(jù)集,并將東海岸用戶的流量路由到新澤西州的數(shù)據(jù)中心。
因為該數(shù)據(jù)中心包含的是主要用于東部的分片;并將西海岸用戶的流量路由到俄勒岡州數(shù)據(jù)中心,因為該數(shù)據(jù)中心包含的是主要用于西部的分片。
我們可以看到分片的數(shù)據(jù)庫為我們提供了多個主數(shù)據(jù)庫的所有好處,而且避免了數(shù)據(jù)不一致所導(dǎo)致的復(fù)雜性。
應(yīng)用服務(wù)器可以從本地主服務(wù)器上進(jìn)行讀取和寫入,由于每個主服務(wù)器擁有各自的記錄,因此不會出現(xiàn)任何的不一致。相反,多主數(shù)據(jù)庫的解決方案則可能會造成數(shù)據(jù)丟失和讀取的不一致。
數(shù)據(jù)庫架構(gòu)比較
圖 5:數(shù)據(jù)庫架構(gòu)比較
圖 5 提供了每一種數(shù)據(jù)庫架構(gòu)在滿足雙活應(yīng)用需求時所存在的優(yōu)缺點。在選擇多主數(shù)據(jù)庫和分區(qū)數(shù)據(jù)庫時,其決定因素在于應(yīng)用是否可以容忍可能出現(xiàn)的讀取不一致和數(shù)據(jù)的丟失問題。
如果答案是肯定的,那么多主數(shù)據(jù)庫可能會稍微容易部署些。而如果答案是否定的,那么分片數(shù)據(jù)庫則是***的選擇。
由于不一致性和數(shù)據(jù)丟失對于大多數(shù)應(yīng)用來說都是不可接受的,因此分片數(shù)據(jù)庫通常是***的選擇。
MongoDB 雙活應(yīng)用
MongoDB 是一個分片數(shù)據(jù)庫架構(gòu)的范例。在 MongoDB 中,主服務(wù)器和次服務(wù)器集的構(gòu)造被稱為副本集。副本集為每個分片提供了高可用性。
一種被稱為區(qū)域分片(Zone Sharding)的機(jī)制被配置為:由每個分片去管理的數(shù)據(jù)集。如前面所提到的,ZoneSharding 可以實現(xiàn)地域分區(qū)。
白皮書《MongoDB多數(shù)據(jù)中心部署》:
- https://www.mongodb.com/collateral/mongodb-multi-data-center-deployments?utm_medium=dzone-synd&utm_source=dzone&utm_content=active-application&jmp=dzone-ref
Zone Sharding 相關(guān)文檔:
- https://docs.mongodb.com/manual/tutorial/sharding-segmenting-data-by-location/的“分區(qū)(分片)數(shù)據(jù)庫”部分描述了 MongoDB 具體實現(xiàn)和運作的細(xì)節(jié)。
其實許多組織,包括:Ebay、YouGov、Ogilvyand Maher 都正在使用 MongoDB 來實現(xiàn)雙活的應(yīng)用架構(gòu)。
除了標(biāo)準(zhǔn)的分片數(shù)據(jù)庫功能之外,MongoDB 還提供對寫入耐久性和讀取一致性的細(xì)粒度控制,并使其成為多數(shù)據(jù)中心部署的理想選擇。對于寫入,我們可以指定寫入關(guān)注(write concern)來控制寫入的持久性。
Writeconcern 使得應(yīng)用在 MongoDB 確認(rèn)寫入之前,就能指定寫入的副本數(shù)量,從而在一個或多個遠(yuǎn)程數(shù)據(jù)中心內(nèi)的服務(wù)器上完成寫入操作。籍此,它保證了在節(jié)點或數(shù)據(jù)中心發(fā)生故障時,數(shù)據(jù)庫的變更不會被丟失。
另外,MongoDB 也補足了分片數(shù)據(jù)庫的一個潛在缺點:寫入可用性無法達(dá)到 100%。
由于每條記錄只有一個主節(jié)點,因此如果該主節(jié)點發(fā)生故障,則會有一段時間不能對該分區(qū)進(jìn)行寫入。
MongoDB 通過多次嘗試寫入,大幅縮短了故障切換的時間。通過多次嘗試的寫入操作,MongoDB 能夠自動應(yīng)對由于網(wǎng)絡(luò)故障等暫時性系統(tǒng)錯誤而導(dǎo)致的寫入失敗,因此也大幅簡化了應(yīng)用的代碼量。
MongoDB 的另一個適合于多數(shù)據(jù)中心部署的顯著特征是:MongoDB 自動故障切換的速度。
當(dāng)節(jié)點或數(shù)據(jù)中心出現(xiàn)故障或發(fā)生網(wǎng)絡(luò)中斷時,MongoDB 能夠在 2-5 秒內(nèi)(當(dāng)然也取決于對它的配置和網(wǎng)絡(luò)本身的可靠性)進(jìn)行故障切換。
發(fā)生故障后,剩余的副本集將根據(jù)配置去選擇一個新的主切片和 MongoDB 驅(qū)動程序,從而自動識別出新的主切片。一旦故障切換完成,其恢復(fù)進(jìn)程將自動履行后續(xù)的寫入操作。
對于讀取,MongoDB 提供了兩種功能來指定所需的一致性級別。
首先,從次數(shù)據(jù)進(jìn)行讀取時,應(yīng)用可以指定***時效值(maxStalenessSeconds)。
這可以確保次節(jié)點從主節(jié)點復(fù)制的滯后時間不能超過指定的時效值,從而次節(jié)點所返回的數(shù)據(jù)具有其時效性。
另外,讀取也可以與讀取關(guān)注(ReadConcern)相關(guān)聯(lián),來控制查詢到的返回數(shù)據(jù)的一致性。
例如,ReadConcern 能通過一些返回值來告知 MongoDB,那些被復(fù)制到副本集中的多數(shù)節(jié)點上的數(shù)據(jù)。
這樣可以確保查詢只讀取那些沒有因為節(jié)點或數(shù)據(jù)中心故障而丟失的數(shù)據(jù),并且還能為應(yīng)用提供一段時間內(nèi)數(shù)據(jù)的一致性視圖。
MongoDB 3.6 還引入了“因果一致性(causal consistency)”的概念,以保證客戶端會話中的每個讀取操作,都始終只“關(guān)注”之前的寫入操作是否已完成,而不管具體是哪個副本正在為請求提供服務(wù)。
通過在會話中對操作進(jìn)行嚴(yán)格的因果排序,這種因果一致性可以確保每次讀取都始終遵循邏輯上的一致,從而實現(xiàn)分布式系統(tǒng)的單調(diào)式讀?。╩onotonic read)。而這正是各種多節(jié)點數(shù)據(jù)庫所無法滿足的。
因果一致性不但使開發(fā)人員,能夠保留過去傳統(tǒng)的單節(jié)點式關(guān)系型數(shù)據(jù)庫,在實施過程中具備的數(shù)據(jù)嚴(yán)格一致性的優(yōu)勢;又能將時下流行架構(gòu)充分利用到可擴(kuò)展和具有高可用性的分布式數(shù)據(jù)平臺之上。
陳峻(Julian Chen) ,有著十多年的 IT 項目、企業(yè)運維和風(fēng)險管控的從業(yè)經(jīng)驗,日常工作深入系統(tǒng)安全各個環(huán)節(jié)。作為 CISSP 證書持有者,他在各專業(yè)雜志上發(fā)表了《IT運維的“六脈神劍”》、《律師事務(wù)所IT服務(wù)管理》 和《股票交易網(wǎng)絡(luò)系統(tǒng)中的安全設(shè)計》等論文。他還持續(xù)分享并更新《廉環(huán)話》系列博文和各種外文技術(shù)翻譯,曾被(ISC)2 評為第九屆亞太區(qū)信息安全***成就表彰計劃的“信息安全踐行者”和 Future-S 中國 IT 治理和管理的 2015 年度踐行人物。
【51CTO原創(chuàng)稿件,合作站點轉(zhuǎn)載請注明原文作者和出處為51CTO.com】