?譯者 | 陳峻
審校 | 孫淑娟
在過去的十年間,分布式系統(tǒng)已遍布全球。它們跨區(qū)域地使用編排技術(shù),實(shí)現(xiàn)了橫跨多個(gè)云服務(wù)提供商及本地基礎(chǔ)設(shè)施的混合云式部署,負(fù)載平衡,以及高可用性。在此基礎(chǔ)上,數(shù)據(jù)庫(kù)領(lǐng)域也在不斷迭代與發(fā)展。近年來,業(yè)界大量涌現(xiàn)了專為分布式數(shù)據(jù)庫(kù)部署而設(shè)計(jì)的新型數(shù)據(jù)庫(kù)系統(tǒng)。當(dāng)然,也有部分?jǐn)?shù)據(jù)庫(kù)已在原有的設(shè)計(jì)中,添加了分布式架構(gòu)組件。
DB-Engines.com評(píng)出的百?gòu)?qiáng)數(shù)據(jù)庫(kù)
知名網(wǎng)站DB-engines.com使用加權(quán)算法,跟蹤了各種數(shù)據(jù)庫(kù)在各個(gè)平臺(tái)上的提及次數(shù)、Google的搜索趨勢(shì)、Stack Overflow上的討論頻率、推文發(fā)布的職業(yè)技能次數(shù)、以及LinkedIn個(gè)人資料出現(xiàn)的數(shù)量。下圖展示了截至2022年5月,在上榜的394種數(shù)據(jù)庫(kù)中,市場(chǎng)占比前100的數(shù)據(jù)庫(kù)分布情況。
截至2022年5月,DB-Engines.com上排名前100的數(shù)據(jù)庫(kù)
其中,作為傳統(tǒng)的SQL系統(tǒng),關(guān)系數(shù)據(jù)庫(kù)管理系統(tǒng)(RDBMS)仍占比最大,高達(dá)47%。而占比25%是NoSQL系統(tǒng),涵蓋了豐富的類型,包括:MongoDB之類的文檔數(shù)據(jù)庫(kù)、Redis之類的鍵值系統(tǒng)、ScyllaDB之類的寬列(wide column)數(shù)據(jù)庫(kù)、以及Neo4j之類的圖形數(shù)據(jù)庫(kù)。而占比11%的“多模型”數(shù)據(jù)庫(kù)包含了在同一系統(tǒng)中,同時(shí)支持SQL和NoSQL的混合體(如:Microsoft的Cosmos DB和ArangoDB),或支持多種NoSQL數(shù)據(jù)模型的數(shù)據(jù)庫(kù)(如:DynamoDB,它將自己列為NoSQL鍵值系統(tǒng)和一個(gè)文件存儲(chǔ)的集合)。
什么是分布式數(shù)據(jù)庫(kù)?
人們對(duì)于如何構(gòu)建符合SQL(源自ANSI/ISO/IEC9075:2016的正式標(biāo)準(zhǔn)化)的分布式RDBMS系統(tǒng)有著不同的理解。目前ANSI、ISO、IETF或W3C尚未對(duì)“NoSQL數(shù)據(jù)庫(kù)”進(jìn)行明確的定義。在我看來,分布式數(shù)據(jù)庫(kù)的基本特征是:首先定義了一個(gè)集群,并在其中分布了不同的數(shù)據(jù);接著,集群中定義了各個(gè)節(jié)點(diǎn)角色。每個(gè)節(jié)點(diǎn)或是對(duì)等節(jié)點(diǎn),或是有某些節(jié)點(diǎn)處于領(lǐng)導(dǎo)位置,而其他節(jié)點(diǎn)扮演跟隨者的角色。然后,這些角色能夠?qū)崿F(xiàn)彼此的故障轉(zhuǎn)移。最后,它們能夠盡可能地均勻復(fù)制和分片數(shù)據(jù)。
在此基礎(chǔ)上,我們可以從上述名列前100名的數(shù)據(jù)庫(kù)中,挑選出5種典型的,并將它們分為如下兩類:
SQL+NewSQL | NoSQL |
PostgreSQL | MongoDB |
CockroachDB | Redis |
| ScyllaDB(Cassandra) |
在上表的左側(cè),Postgres和CockroachDB代表了分布式SQL。其中,CockroachDB號(hào)稱“NewSQL”,是專為分布式數(shù)據(jù)庫(kù)而設(shè)計(jì)的。在上表的右側(cè),MongoDB、Redis和ScyllaDB都屬于分布式NoSQL。總地說來,如果您需要表聯(lián)合(JOIN)操作的話,可以沿用SQL和RDBMS。如果您需要對(duì)數(shù)據(jù)進(jìn)行非規(guī)范化,那么便可以選擇NoSQL。
多數(shù)據(jù)中心集群
前面提到了集群的概念。早在多數(shù)據(jù)中心的設(shè)計(jì)架構(gòu)被提出之前,PostgreSQL、MongoDB和Redis都被設(shè)計(jì)為單數(shù)據(jù)中心的本地集群。
- 如上表所示,首發(fā)于1986年的Postgres,完全早于云計(jì)算的概念。但隨著時(shí)間的推移,它在設(shè)計(jì)和功能上發(fā)生了不少的改進(jìn)。
- 作為NewSQL的代表,CockroachDB在設(shè)計(jì)之初就考慮到了全局性分布。
- MongoDB在公有云誕生之初發(fā)布,其最初的設(shè)計(jì)只考慮到了單個(gè)數(shù)據(jù)中心集群,現(xiàn)在也增加了對(duì)于各種不同拓?fù)涞闹С?。使用MongoDB Atlas,您可以非常輕松地將其部署到多個(gè)區(qū)域中。
- 根據(jù)低延遲的設(shè)計(jì)理念,Redis通常被部署在單個(gè)數(shù)據(jù)中心中。同時(shí),它也提供了允許部署多數(shù)據(jù)中心的企業(yè)功能。
- ScyllaDB和Cassandra一樣,從一開始就在設(shè)計(jì)中考慮了多數(shù)據(jù)中心的部署。
集群
在分布式數(shù)據(jù)庫(kù)的概念中,我們提到了復(fù)制和分片。這完全取決于數(shù)據(jù)庫(kù)架構(gòu)的分層或同構(gòu)程度。例如,MongoDB只有一個(gè)主節(jié)點(diǎn),其余都是該主節(jié)點(diǎn)的副本(被稱為副本集)。您只能在主節(jié)點(diǎn)上寫入數(shù)據(jù)庫(kù)。而由于副本為只讀,因此您無法直接更新它們,而必須由主節(jié)點(diǎn)去更新其他副本。顯然,這些節(jié)點(diǎn)是異構(gòu)的,而不是同構(gòu)的。
這類主備(Primary-Replica)架構(gòu)有助于在重讀?。╮ead-heavy)的工作負(fù)載中分配流量。而在混合或重寫入(write-heavy)的工作負(fù)載中,主節(jié)點(diǎn)會(huì)成為瓶頸。也就是說,在主節(jié)點(diǎn)出現(xiàn)故障時(shí),由于集群需要臨時(shí)選出一個(gè)新的主節(jié)點(diǎn),因此數(shù)據(jù)庫(kù)會(huì)不得不臨時(shí)暫停寫入操作。這就是所謂的單點(diǎn)故障。
相反,ScyllaDB和Cassandra屬于“無領(lǐng)導(dǎo)”的P2P多活(Active-Active)系統(tǒng)。由于客戶端可以讀取或?qū)懭肴魏瓮瑯?gòu)的節(jié)點(diǎn),因此避免了單點(diǎn)故障。也就是說,每個(gè)節(jié)點(diǎn)都可以更新集群中任何其他副本的數(shù)據(jù)。
可見,雖然多活會(huì)帶來更多的計(jì)算量,但是它解決了服務(wù)器保持彼此同步的問題。用戶最終會(huì)得到一個(gè)適合重寫入的負(fù)載平衡的系統(tǒng),畢竟每個(gè)節(jié)點(diǎn)都可以提供讀取與寫入服務(wù)。
下面,我們看看上述5種數(shù)據(jù)庫(kù)在主副本和P2P多活方面的表現(xiàn):
- CockroachDB和ScyllaDB(以及Cassandra)是按照多活模式設(shè)計(jì)的。
- Postgres需要一些外部方法來實(shí)現(xiàn)多活,而并非內(nèi)置。
- MongoDB并不支持多活。
- 在Redis企業(yè)版中,我們可以使用無沖突的復(fù)制數(shù)據(jù)類型(conflict-free replicated data types,CRDT)來實(shí)現(xiàn)多活模式。
注意,Postgres、MongoDB和Redis都默認(rèn)會(huì)使用主副本的數(shù)據(jù)分布模式。
復(fù)制
分布式系統(tǒng)設(shè)計(jì)也會(huì)影響到已部署的不同機(jī)架、或數(shù)據(jù)中心之間分配數(shù)據(jù)的方式。例如,在一套給定主副本系統(tǒng)中,只有擁有主節(jié)點(diǎn)的數(shù)據(jù)中心,才能服務(wù)于任何寫入的負(fù)載。而其他數(shù)據(jù)中心只能作為只讀副本。
而在支持多數(shù)據(jù)中心集群的對(duì)等系統(tǒng)中,整個(gè)集群中的每個(gè)節(jié)點(diǎn)都可以接受讀取或?qū)懭胴?fù)載。顯然,這會(huì)更方便將工作負(fù)載分布到多個(gè)地理位置。
例如,通過使用ScyllaDB,您可以判定每個(gè)站點(diǎn)具有相同甚至不同的復(fù)制因子。在上圖的右側(cè),我們展示了在一個(gè)數(shù)據(jù)中心擁有三個(gè)數(shù)據(jù)副本,而在另一個(gè)數(shù)據(jù)中心擁有兩個(gè)副本的情況。
不同級(jí)別的操作會(huì)具有一致性。您可能在具有三節(jié)點(diǎn)的數(shù)據(jù)中心進(jìn)行本地的“仲裁”式讀取或?qū)懭耄矗盒枰ㄟ^本地仲裁來更新三個(gè)節(jié)點(diǎn)中的哪兩個(gè))。當(dāng)然,您也可能有一個(gè)集群范圍內(nèi)的仲裁,判定需要更新一個(gè)或兩個(gè)數(shù)據(jù)中心里的任意三個(gè)節(jié)點(diǎn)。
拓?fù)涓兄?/h4>
我們已經(jīng)了解了分布式數(shù)據(jù)庫(kù)的本地集群方式,它可以有效地讓多個(gè)系統(tǒng)分擔(dān)負(fù)載。您也可以跨多個(gè)地域節(jié)點(diǎn)對(duì)數(shù)據(jù)庫(kù)進(jìn)行分片,或是通過確保相同數(shù)據(jù)在多個(gè)節(jié)點(diǎn)上的高可用性,來保證數(shù)據(jù)的復(fù)制。
下面,讓我們假設(shè)一個(gè)場(chǎng)景:如果您的所有節(jié)點(diǎn)都安裝在同一個(gè)機(jī)架中,而整個(gè)機(jī)架出現(xiàn)了故障,那該怎么辦呢?此時(shí),我們需要用到同一數(shù)據(jù)中心內(nèi)的機(jī)架拓?fù)涓兄源_保將數(shù)據(jù)分布到該數(shù)據(jù)中心的多個(gè)機(jī)架中,從而最大限度地減少因電源或網(wǎng)絡(luò)中斷,而導(dǎo)致的整個(gè)機(jī)架與另一個(gè)機(jī)架失去連接。
在分布式數(shù)據(jù)庫(kù)中,我們需要數(shù)據(jù)庫(kù)的多個(gè)副本,運(yùn)行在不同的數(shù)據(jù)中心上,以實(shí)現(xiàn)跨集群的更新機(jī)制。每個(gè)單一數(shù)據(jù)庫(kù)都能夠自主運(yùn)行,而且它們的同步機(jī)制既可以是單向的(由一個(gè)數(shù)據(jù)中心去更新下游副本),也可以是雙向或多向的。這種地理分布可以通過允許就近用戶的連接,來最小化延遲,進(jìn)而確保在出現(xiàn)單個(gè)數(shù)據(jù)中心的災(zāi)難時(shí),用戶不會(huì)丟失部分甚至全部數(shù)據(jù)。
下面,我們來看看上述5種數(shù)據(jù)庫(kù)在拓?fù)涓兄矫娴谋憩F(xiàn):
- CockroachDB和ScyllaDB均有內(nèi)置的拓?fù)涓兄匦浴?/li>
- MongoDB從2015年后開始引入拓?fù)涓兄匦浴?/li>
- Postgres和Redis最初被設(shè)計(jì)為單數(shù)據(jù)中心方案。雖然不是開箱即用的,但是您可以像添加多活功能那樣,去手動(dòng)添加拓?fù)涓兄?wù)。
下面,我們根據(jù)上述各項(xiàng)分布式特點(diǎn),對(duì)5種數(shù)據(jù)庫(kù)進(jìn)行屬性上的總結(jié)和對(duì)比。
PostgreSQL
Postgres是如今最流行的SQL實(shí)現(xiàn)之一。它提供了開箱即用的本地集群。不過,由于Postgres仍在致力于完善其多數(shù)據(jù)中心的集群,因此您需要通過額外的配置和開發(fā),方可實(shí)現(xiàn)。
由于SQL建立在高度一致的事務(wù)性模式上,因此它不適合廣泛地跨越地理區(qū)域的集群。每個(gè)查詢都會(huì)被所有相關(guān)數(shù)據(jù)中心之間的長(zhǎng)時(shí)間延遲而放大。
同時(shí),Postgres依賴于主副本模型。集群中存在著主節(jié)點(diǎn)和副本節(jié)點(diǎn)的關(guān)系。您也可以額外地添加負(fù)載均衡器,或者多活附加組件。此外,Postgres雖然在自動(dòng)化分片方面取得了一些進(jìn)展,但是目前仍需要用戶進(jìn)行手動(dòng)數(shù)據(jù)分片。
CockroachDB
作為“NewSQL”的CockroachDB不但使用了Postgres的傳輸協(xié)議(wire protocol),而且大量借鑒了許多由Postgres開創(chuàng)的概念。當(dāng)然,它并沒有局限于Postgres架構(gòu)。例如:多數(shù)據(jù)中心集群和對(duì)等無領(lǐng)導(dǎo)拓?fù)?,都被?nèi)置了進(jìn)去。
此外,CockroachDB不但具有自動(dòng)分片和數(shù)據(jù)復(fù)制功能,而且也內(nèi)置了數(shù)據(jù)中心的感知能力,您可以按需添加機(jī)架的感知功能。
值得注意的是,由于CockroachDB需要所有的事務(wù)具有高度一致性,因此用戶喪失了最終一致性或可調(diào)一致性(Tunable Consistency)的靈活度。這不但會(huì)降低吞吐量,而且會(huì)在任何跨數(shù)據(jù)中心的部署中,產(chǎn)生高基線的延遲(high baseline latencies)。
MongoDB
作為NoSQL典型代表的MongoDB,已被開發(fā)出了許多分布式數(shù)據(jù)庫(kù)功能。例如,它已經(jīng)能夠?qū)崿F(xiàn)多數(shù)據(jù)中心的集群了。雖然MongoDB在大多數(shù)情況下,仍然需要遵循主副本模式,但有用戶可以通過第三方工具使其實(shí)現(xiàn)P2P的多活模式。
Redis
作為“鍵值對(duì)”存儲(chǔ)的典型數(shù)據(jù)庫(kù),Redis旨在實(shí)現(xiàn)內(nèi)存緩存或數(shù)據(jù)存儲(chǔ)。雖然它可以持久化數(shù)據(jù),但是如果數(shù)據(jù)集不適合內(nèi)存的話,就會(huì)讓性能大打折扣。
Redis在設(shè)計(jì)上默認(rèn)考慮了本地集群。這會(huì)導(dǎo)致例如:一旦您無法在5毫秒內(nèi)從SSD獲取數(shù)據(jù),就無法在145毫秒內(nèi)完成從舊金山到倫敦的網(wǎng)絡(luò)傳輸往返時(shí)間。當(dāng)然,對(duì)于那些確實(shí)需要多地域分布存儲(chǔ)的企業(yè)而言,它們?nèi)匀粫?huì)在多數(shù)據(jù)中心里構(gòu)建Redis集群。
同時(shí),由于Redis往往是作為主副本模式運(yùn)行的,因此它更適用于重讀取的緩存服務(wù)器。也就是說,它需要數(shù)據(jù)被先寫入,然后再分散到副本處,以平衡它們的緩存負(fù)載。
Redis的企業(yè)功能可以實(shí)現(xiàn)P2P的多活集群。同時(shí),Redis能夠自動(dòng)分片和復(fù)制數(shù)據(jù)。不過,其拓?fù)涓兄δ軆H限于帶有企業(yè)特性的機(jī)架感知。
ScyllaDB
ScyllaDB是按照Apache Cassandra的分布式數(shù)據(jù)庫(kù)模型設(shè)計(jì)的。默認(rèn)情況下,它帶有多數(shù)據(jù)中心集群,而且采取的是無領(lǐng)導(dǎo)的多活拓?fù)洹?/p>
ScyllaDB會(huì)自動(dòng)分片,并為每個(gè)操作提供了可調(diào)的一致性。如果您想獲得更強(qiáng)的一致性,它也能夠支持輕量級(jí)事務(wù),并提供寫入的線性化。
就拓?fù)涓兄?,ScyllaDB支持機(jī)架感知和數(shù)據(jù)中心感知。它甚至支持令牌感知和分片感知,ScyllaDB不僅可以知曉該在哪個(gè)節(jié)點(diǎn)存儲(chǔ)數(shù)據(jù),而且可以獲悉與該數(shù)據(jù)關(guān)聯(lián)的CPU信息。
小結(jié)
在上文中,我們分析了五種知名的分布式數(shù)據(jù)庫(kù)系統(tǒng)。其中,CockroachDB為SQL數(shù)據(jù)庫(kù)提供了開箱即用的特性與屬性的全面組合,而ScyllaDB為NoSQL系統(tǒng)提供了全面的功能。目前,分布式數(shù)據(jù)庫(kù)仍在不斷迭代與改進(jìn)。它們正變得更加靈活、更具可擴(kuò)展性、以及具有更高的性能。
譯者介紹
陳峻 (Julian Chen),51CTO社區(qū)編輯,具有十多年的IT項(xiàng)目實(shí)施經(jīng)驗(yàn),善于對(duì)內(nèi)外部資源與風(fēng)險(xiǎn)實(shí)施管控,專注傳播網(wǎng)絡(luò)與信息安全知識(shí)與經(jīng)驗(yàn);持續(xù)以博文、專題和譯文等形式,分享前沿技術(shù)與新知;經(jīng)常以線上、線下等方式,開展信息安全類培訓(xùn)與授課。
原文標(biāo)題:??Comparing Distributed Databases???,作者:Peter Corless?