雲端計算下的資料庫 分析 以及部分網際網路公司目前採用的新型資料庫總結

HIT_微笑前進發表於2015-07-21

雲端計算下的新型資料庫技術 

 

摘要:在這個資訊化的時代,我們的一舉一動都離不開與資料打交道,特別是雲端計算和大資料時代的到來,使得傳統資料庫的效能已無法滿足海量資料的實時交易查詢需求,在效能和成本的雙重壓力之下,雲端計算下的資料庫需要尋找突破之路。

 

 1.簡介:

雲端計算通過整合,管理和調配分佈在網際網路中的所有計算資源,以統一的介面同時向使用者提供服務。網際網路提供的各種計算形式的應用以及提供這些服務的資料中心和軟硬體基礎設施、提供的服務成為軟體即服務(SaaS),資料中心的軟硬體基礎設施即為雲,這種虛擬化資源提供計算的方式使得服務通過網際網路傳播,而使用者不需要知道雲端計算服務的提供者和提供方式。因此,雲端計算具有規模大,可靠性高,使用者透明,可擴充套件性強,提供按需服務和廉價等特點。而實現以上需求的前提條件就是雲端計算系統應該具備足夠大的規模和處理能力,以滿足大量的資料訪問,資料儲存和來自不同網路等額請求。

傳統的關係型資料庫雖然在資料儲存方面佔據著不可動搖的地位,但由於其天生的限制,越來越不能滿足雲端計算下的資料擴充套件、讀寫速度、支撐容量以及建設和運營成本的要求。鑑於此,國內外知名的一些網際網路企業GoogleFacebookTwitter、阿里、騰訊、百度等紛紛展開探索,自主研發新型資料庫,這些企業有擁有眾多的優秀人才,以及豐富的產品經驗,所以對於新型資料庫的探索成果在一定程度上也代表了當下雲端計算下資料庫的最新的進展,所以本文主要先對與傳統型資料庫的優劣進行一些分析,接著介紹了現如今新型資料庫的研究進展,對各型別資料庫進行一些對比分析,最後在對於還存在的不足進行總結並對資料庫的發展提出自己一些的看法。

2.背景:

2.1 雲端計算和大資料:

大資料是一種大規模資料的管理和利用的商業模式和技術平臺的泛指,它不同於傳統的海量資料,除了資料規模呈現幾何級數增長的特徵以外,還包括所有資料型別的採集、分類、處理、分析和展現等多個方面,從而最終實現從大資料中挖掘潛在巨大價值的目的。因此,大資料具有這4方面的特徵:規模性(Volume)、多樣性(Variety)、高速性(Velocity)和真實性(Veracity)。

雲端計算是一種基於網際網路的計算方式,通過這種方式,共享的軟硬體資源和資訊可以按需提供給計算機和其他裝置。能夠像煤氣、水電一樣提供給資訊時代的社會化服務,使用方便,費用低廉。雲端計算具有以下的特點:

(1) 超大規模。“雲”具有超大的規模,Google雲端計算擁有100多萬臺伺服器,AmazonIBM、微軟等的雲均擁有幾十萬臺伺服器,正是這樣擁有超大規模的“雲”能夠賦予使用者前所未有的計算能力。

(2) 虛擬化。雲端計算支援使用者在任意位置,使用各種終端獲取應用服務。所請求的資源來自“雲”,而不是固定的有形的實體。應用在“雲”中某處執行,但實際使用者無需瞭解、也不用擔心應用執行的具體位置。只需要一臺筆記本或者一部手機,就可以通過網路服務來實現我們需要的一切,甚至包括超級計算的任務。

(3) 高可靠性。“雲”使用了資料多副本容錯、計算節點同構可互換等措施來保障服務的高可靠性,使用雲端計算比使用本地計算可靠。

(4) 通用性。雲端計算不針對特定的應用,在雲的支撐下可以構造出千變萬化的應用,同一個雲可以同時支撐不同的應用執行

(5) 高可擴充套件性。雲的規模可以動態伸縮,滿足應用和使用者規模增長的需要。

(6) 按需服務。雲是一個龐大的資源池,可按需購買,象自來水,電,煤氣一樣計費使用。

(7) 極其廉價。用於“雲”的特殊容錯措施可以採用極其廉價的節點來構成雲,“雲”的自動化集中式管理使得大量企業無需負擔日益高昂的資料中心管理成本,“雲”的通用性使資源的利用率較之傳統系統大幅提升,因此使用者可以充分享受“雲”的低成本優勢。

 

 

大資料著眼於“資料”,關注實際業務,提供資料採集分析挖掘,看重資訊積澱即資料儲存能力。雲端計算著眼於“計算”,關注IT解決方案,提供IT基礎架構,看重計算能力,即資料處理能力,資料是兩者之間最重要的聯絡,也是兩者存在的意義,所以對於雲端計算和大資料時代,資料庫技術的重要性也就不言而喻了。

2.2 雲端計算下的傳統型資料庫

隨著web2.0的發展,傳統的關係型資料庫在應對超大規模和高併發的資料量和訪問量時存在難以克服的問題:

(1)高併發讀寫速度慢

在資料量達到一定規模時,由於關係型資料庫的系統邏輯非常複雜,使得其容易發生死鎖等併發問題,導致其讀寫速度下降非常嚴重。

(2)支撐容量有限

對於資料量巨大的一些網站例如社交網站,每天海量的使用者動態,累計下每月就能產生幾億條資料記錄,對於關係型資料庫,在這樣一個具有數億條記錄的表中進行SQL查詢,效率會是極其低下乃至不可忍受的。

(3)可擴充套件性差

在基於web的架構中,資料庫是最難進行橫向擴充套件的,當一個應用系統的使用者量和訪問量與日俱增的時候,傳統的關係型資料庫卻不能像web service 那樣簡單的通過新增更多的硬體和服務節點來擴充套件效能和負載能力。對於很多需要提供不間斷服務的網站來說,對資料庫系統進行升級和擴充套件是非常痛苦的事情,往往需要停機維護和資料遷移,因此迫切需要關聯式資料庫也能夠通過不斷新增伺服器節點來實現擴充套件。

(4)建設和運維成本高

企業級資料庫的價格很高,並且隨著系統的規模增大而不斷上升。高昂的建設和運維成本無法滿足雲端計算應用對資料庫的需求。

(5)對於分散式系統的制約

為了支撐更大的訪問量和資料量,我們必然需要分散式資料庫系統,然而由於傳統關係型資料庫的強一致性,就會使得分散式系統的延遲提高,因為網路通訊本身比單機內通訊代價高很多,這種通訊的代價就會直接增加系統單次提交的延遲。延遲提高會導致資料庫所持有時間變長,使得高衝突條件下分散式事物的效能不升反降,甚至效能距離單機資料庫都還有明顯的差距。面對這個難題,傳統的關聯式資料庫選擇了放棄分散式的方案,因為在20世紀70-80年代,資料庫主要被用來處理企業內的各類資料,面對的使用者不過幾千人,而資料量最多也就是TB級別。用單臺機器處理事務,用個磁碟陣列處理一下磁碟容量不夠的問題,基本就能解決一切問題。

然而,在大資料時代,雲端計算的資料量已然從TB級別變為了PB級別甚至更多,存在單點的單擊系統無論如何努力,都會面對系統處理能力的天花板,原來的這條路就不能再接著走下去了。

2.3 幾種雲端計算下的新型資料庫及其實現原理

 

(1)NoSQL非關係型資料庫

面對傳統資料庫出現的種種挑戰,NoSQL是在新形勢下出現的一種給關係型資料庫的總稱,它用全新的儲存方式,減少了資料互動,減少了編寫、除錯的程式碼,對海量資料實現高效儲存和高效訪問,同時它的開源免費也降低了企業的運營成本。

NoSQL的主要特徵為:

1)不需要預定義模式:不需要預定義資料模式,預定義表結構。資料中的每條記錄可能有不同的屬性和格式。當插入資料時,並不需要預先定義它們的模式。 

2無共享架構:相對於將所有資料儲存的儲存區域網路中的全共享架構。NoSQL往往將資料劃分後儲存在各個本地伺服器上。因為從本地磁碟讀取資料的效能往往好於通過網路傳輸讀取資料的效能,從而提高了系統的效能。

3彈性可擴充套件:可以在系統執行的時候,動態增加或者刪除結點。不需要停機維護,資料可以自動遷移。

4分割槽:相對於將資料存放於同一個節點,NoSQL資料庫需要將資料進行分割槽,將記錄分散在多個節點上面。並且通常分割槽的同時還要做複製。這樣既提高了並行效能,又能保證沒有單點失效的問題。

5非同步複製:RAID儲存系統不同的是,NoSQL中的複製,往往是基於日誌的非同步複製。這樣,資料就可以儘快地寫入一個節點,而不會被網路傳輸引起遲延。缺點是並不總是能保證一致性,這樣的方式在出現故障的時候,可能會丟失少量的資料。

6BASE相對於事務嚴格的ACID特性,NoSQL資料庫保證的是BASE特性。BASE是最終一致性和軟事務。

NoSQL資料庫並沒有一個統一的架構,兩種NoSQL資料庫之間的不同,甚至遠遠超過兩種關係型資料庫的不同。可以說,NoSQL各有所長,成功的NoSQL必然特別適用於某些場合或者某些應用,在這些場合中會遠遠勝過關係型資料庫和其他的NoSQL

具體優勢表現有:

1)資料庫的開發效率高,在設計上NoSQL資料庫和傳統的資料庫有很大的不同,傳統應用程式的開發中,需要在記憶體資料結構和福安息資料庫的對映上花費大量的精力和時間。NoSQL資料庫更符合應用程式的需求,部分NoSQL資料庫可以在硬碟上直接操作,簡化了資料的互動,減少了編寫、除錯程式的工作量。

2)資料庫的擴充套件能力強。現在企業通常使用更小,更便宜的計算機組成叢集來構建資料庫,NoSQL資料庫的設計正是針對伺服器叢集,所以更適合大規模資料的處理。

3)資料庫的開發成本低廉。因為NoSQL資料庫主要都是開源軟體,所以沒有昂貴的開發成本。在專案開發中很多企業為了節省開發成本而選擇NoSQL資料庫。

4)資料模型靈活。在關聯式資料庫中,資料有固定結構,通過各種操作互相關聯,對大型的表格增刪欄位非常麻煩。NoSQL的儲存只有一對鍵值或者陣列,無需事先建立欄位,任何時候都可以儲存自定義的資料格式。

NoSQL資料庫的分類

鍵值(Key-Value)儲存資料庫

這一類資料庫主要會使用到一個雜湊表,這個表中有一個特定的鍵和一個指標指向特定的資料。Key/value模型對於IT系統來說的優勢在於簡單、易部署。但是如果DBA只對部分值進行查詢或更新的時候,Key/value就顯得效率低下了。[3] 舉例如:Tokyo Cabinet/Tyrant, Redis, Voldemort, Oracle BDB.

列儲存資料庫。

這部分資料庫通常是用來應對分散式儲存的海量資料。鍵仍然存在,但是它們的特點是指向了多個列。這些列是由列家族來安排的。如:Cassandra, HBase, Riak.

文件型資料庫

文件型資料庫的靈感是來自於Lotus Notes辦公軟體的,而且它同第一種鍵值儲存相類似。該型別的資料模型是版本化的文件,半結構化的文件以特定的格式儲存,比如JSON。文件型資料庫可 以看作是鍵值資料庫的升級版,允許之間巢狀鍵值。而且文件型資料庫比鍵值資料庫的查詢效率更高。如:CouchDB, MongoDb. 國內也有文件型資料庫SequoiaDB,已經開源。

圖形(Graph)資料庫

圖形結構的資料庫同其他行列以及剛性結構的SQL資料庫不同,它是使用靈活的圖形模型,並且能夠擴充套件到多個伺服器上。NoSQL資料庫沒有標準的查詢語言(SQL),因此進行資料庫查詢需要制定資料模型。許多NoSQL資料庫都有REST式的資料介面或者查詢API如:Neo4J, InfoGrid, Infinite Grap

(2)NewSQL

NewSQL是對各種新的可擴充套件/高效能資料庫的總稱,這類資料庫不僅具有NoSQL對海量資料的儲存管理能力,還有傳統資料庫支援ACID和SQL等特性。

NewSQL系統雖然在的內部結構變化很大,但是它們有兩個顯著的共同特點:

(1)它們都支援關係資料模型

(2) 它們都使用SQL作為其主要的介面。已知的第一個NewSQL系統叫做H-Store,它是一個分散式並行記憶體資料庫系統。

目前NewSQL系統大致分三類: 

新架構

第一型別的NewSQL系統是全新的資料庫平臺,它們均採取了不同的設計方法。它們大概分兩類:

(1) 這類資料庫工作在一個分散式叢集的節點上,其中每個節點擁有一個資料子集。 SQL查詢被分成查詢片段傳送給自己所在的資料的節點上執行。這些資料庫可以通過新增額外的節點來線性擴充套件。現有的這類資料庫有: Google SpannerVoltDB, Clustrix, NuoDB.

(2) 這些資料庫系統通常有一個單一的主節點的資料來源。它們有一組節點用來做事務處理,這些節點接到特定的SQL查詢後,會把它所需的所有資料從主節點上取回來後執行SQL查詢,再返回結果。

SQL引擎

第二類是高度優化的SQL儲存引擎。這些系統提供了MySQL相同的程式設計介面,但擴充套件性比內建的引擎InnoDB更好。這類資料庫系統有:TokuDB, MemSQL

透明分片

這類系統提供了分片的中介軟體層,資料庫自動分割在多個節點執行。這類資料庫包擴:ScaleBase,dbShards, Scalearc。 

2.4 當今幾家主流網際網路公司的資料庫技術

(1)阿里分散式資料庫服務DRDS

DRDS也是一個NewSQL的系統,它與ScaleBase、VoltDB等系統類似,都希望能夠找到一條既能保持系統的高擴充套件性和高效能,又能儘可能保持傳統資料庫的ACID事務和SQL特性的分散式資料庫系統。

 

三層架構,Matrix對應資料庫切分場景,對SQL有一定限制,Group對應讀寫分離和高可用場景,對SQL幾乎沒有限制。

 

DRDS主要功能介紹

分散式SQL執行引擎
分散式SQL引擎主要的目的,就是實現與單機資料庫SQL引擎的完全相容。目前我們的SQL引擎能夠做到與MySQL的SQL引擎全相容,包括各類join和各類複雜函式等。他主要包含SQL解析、優化、執行和合並四個流程,如圖3中綠色部分。

 

雖然SQL是相容的,但是分散式SQL執行演算法與單機SQL的執行演算法卻完全不同,原因也很簡單,網路通訊的延遲比單機內通訊的延遲大得多。舉個 例子說明一下,我們有份檔案要從一張紙A上謄寫到另外一張紙B上,單機系統就好比兩張紙都在同一個辦公室裡,而分散式資料庫則就像是一張紙在北京,一張紙 在杭州。
自然地,如果兩張紙在同一個辦公室,因為傳輸距離近,逐行謄寫的效率是可以接受的。而如果距離是北京到杭州,用逐行謄寫的方式,就立刻顯得代價太 高了,我們總不能看一行,就打個“飛的”去杭州寫下來吧。在這種情況下,還是把紙A上的資訊拍個照片,【一整批的】帶到杭州去處理,明顯更簡單一些。這就 是分散式資料庫特別強調吞吐調優的原因,只要是涉及到跨機的所有查詢,都必須儘可能的積攢一批後一起傳送,以減少系統延遲提高帶來的不良影響。

按需資料庫叢集平滑擴縮

DRDS允許應用按需將新的單機儲存加入或移出叢集,DRDS則能夠保證應用在遷移流程中實現不停機擴容縮容。

 

在內部的資料庫使用實踐中,這個功能的一個最重要應用場景就是雙11了。在雙11之前,會將大批的機器加入到我們的資料庫叢集中,抗過了雙11,這批機器就會下線。 

因為完全無法預測在什麼時間點系統會有爆發性的增長,而如果在這時候系統因為技術原因不能使用,就會給整個業務帶來毀滅性的影響,風口一旦錯過,就追悔莫及了。我想這就是雲端計算特別強調可擴充套件能力的原因吧。

小表廣播
小表廣播也是我們在分散式資料庫領域內最常用的工具之一,他的核心目的其實都是一個——儘可能讓查詢只發生在單機。

讓我們用一個例子來說明,小表廣播的一般使用場景。

 

圖中,如果我想知道買家id等於0的使用者在商城裡面買了哪些商品,我們一般會先將這兩個表join起來,然後再用where平臺名=”商城” and buyerID = 0找到符合要求的資料。然而這種join的方式,會導致大量的針對左表的網路I/O。如果要取出的資料量比較大,系統延遲會明顯上升。

這時候,為了提升效能,我們就必須要減少跨機join的網路代價。我們比較推薦應用做如下處理,將左表複製到右表的每一個庫上。這樣,join操作就由分散式join一下變回到本地join,系統的效能就有很大的提升了,如圖所示。

 

分散式事務套件

在阿里巴巴的業務體系中存在非常多需要事務類的場景,下單減庫存,賬務,都是事務場景最集中的部分。
而我們處理事務的方法卻和傳統應用處理事務的方案不大一樣,我們非常強調事務的最終一致性和非同步化。利用這種方式,能夠極大地降低分散式系統中鎖持有的時間,從而極大地提升系統效能。

 

這種處理機制,是我們分散式事務能夠以極低成本大量執行的最核心法門。在DRDS平臺內,我們將這些方案產品化,為了DRDS的分散式事務解決套件。

利用他們,能夠讓你以比較低的成本,實現低延遲,高吞吐的分散式事務場景。

 

(2)MongoDB

MongoDB[1] 是一個基於分散式檔案儲存的資料庫。由C++語言編寫。旨在為WEB應用提供可擴充套件的高效能資料儲存解決方案。

MongoDB[2] 是一個介於關聯式資料庫和非關聯式資料庫之間的產品,是非關聯式資料庫當中功能最豐富,最像關聯式資料庫的。他支援的資料結構非常鬆散,是類似jsonbson格式,因此可以儲存比較複雜的資料型別。Mongo最大的特點是他支援的查詢語言非常強大,其語法有點類似於物件導向的查詢語言,幾乎可以實現類似關聯式資料庫單表查詢的絕大部分功能,而且還支援對資料建立索引

它的特點是高效能、易部署、易使用,儲存資料非常方便。主要功能特性有:

*面向集合儲存,易儲存物件型別的資料。

*模式自由。

*支援動態查詢

*支援完全索引,包含內部物件。

*支援查詢。

*支援複製和故障恢復。

*使用高效的二進位制資料儲存,包括大型物件(如視訊等)。

*自動處理碎片,以支援雲端計算層次的擴充套件性。

*支援RUBYPYTHONJAVAC++PHPC#等多種語言。

*檔案儲存格式為BSON(一種JSON的擴充套件)。

*可通過網路訪問。

使用原理

所謂面向集合Collection-Oriented),意思是資料被分組儲存在資料集中,被稱為一個集合(Collection)。每個集合在資料庫中都有一個唯一的標識名,並且可以包含無限數目的文件。集合的概念類似關係型資料庫RDBMS)裡的表(table),不同的是它不需要定義任何模式(schema)Nytro MegaRAID技術中的快閃記憶體快取記憶體演算法,能夠快速識別資料庫內大資料集中的熱資料,提供一致的效能改進。

模式自由(schema-free),意味著對於儲存在mongodb資料庫中的檔案,我們不需要知道它的任何結構定義。如果需要的話,你完全可以把不同結構的檔案儲存在同一個資料庫裡。

儲存在集合中的文件,被儲存為鍵-值對的形式。鍵用於唯一標識一個文件,為字串型別,而值則可以是各種復雜的文件型別。我們稱這種儲存形式為BSONBinary Serialized Document Format)。[3] 

[4] MongoDB已經在多個站點部署,其主要場景如下:

1)網站實時資料處理。它非常適合實時的插入、更新與查詢,並具備網站實時資料儲存所需的複製及高度伸縮性。

2)快取。由於效能很高,它適合作為資訊基礎設施的快取層。在系統重啟之後,由它搭建的持久化快取層可以避免下層的資料來源過載。

3)高伸縮性的場景。非常適合由數十或數百臺伺服器組成的資料庫,它的路線圖中已經包含對MapReduce引擎的內建支援。

不適用的場景如下:1)要求高度事務性的系統。

2)傳統的商業智慧應用。

3)複雜的跨文件(表)級聯查詢。

設計特徵

MongoDB 的設計目標是高效能、可擴充套件、易部署、易使用,儲存資料非常方便。其主要功能特性如下。

1)面向集合儲存,容易儲存物件型別的資料。在MongoDB 中資料被分組儲存在集合中,集合類似RDBMS 中的表,一個集合中可以儲存無限多的文件。

2)模式自由,採用無模式結構儲存。在MongoDB 中集合中儲存的資料是無模式的文件,採用無模式儲存資料是集合區別於RDBMS 中的表的一個重要特徵。

3)支援完全索引,可以在任意屬性上建立索引,包含內部物件。MongoDB的索引和RDBMS 的索引基本一樣,可以在指定屬性、內部物件上建立索引以提高查詢的速度。除此之外,MongoDB 還提供建立基於地理空間的索引的能力。

4)支援查詢。MongoDB 支援豐富的查詢操作,MongoDB 幾乎支援SQL中的大部分查詢。

5)強大的聚合工具。MongoDB 除了提供豐富的查詢功能外,還提供強大的聚合工具,如countgroup 等,支援使用MapReduce 完成複雜的聚合任務。

6)支援複製和資料恢復。MongoDB 支援主從複製機制,可以實現資料備份、故障恢復、讀擴充套件等功能。而基於副本集的複製機制提供了自動故障恢復的功能,確保了叢集資料不會丟失。

7)使用高效的二進位制資料儲存,包括大型物件(如視訊)。使用二進位制格式儲存,可以儲存任何型別的資料物件。

8)自動處理分片,以支援雲端計算層次的擴充套件。MongoDB 支援叢集自動切分資料,對資料進行分片可以使叢集儲存更多的資料,實現更大的負載,也能保證儲存的負載均衡。

9)支援PerlPHPJavaC#JavaScriptRubyC++語言的驅動程式,MongoDB 提供了當前所有主流開發語言的資料庫驅動包,開發人員使用任何一種主流開發語言都可以輕鬆程式設計,實現訪問MongoDB 資料庫。

10)檔案儲存格式為BSONJSON 的一種擴充套件)。BSON 是對二進位制格式的JSON 的簡稱,BSON 支援文件和陣列的巢狀。

11)可以通過網路訪問。可以通過網路遠端訪問MongoDB 資料庫。

(3)亞馬遜自主研發的資料庫:DynamoDB

DynamoDB是亞馬遜自主研發的NoSQL型資料庫,Amazon DynamoDB 是一項快速靈活的 NoSQL 資料庫服務,適合所有需要一致性且延遲低於 10 毫秒的任意規模的應用程式。它是完全託管的雲資料庫,支援文件和鍵值儲存模型。其靈活的資料模型和可靠的效能令其成為移動、Web、遊戲、廣告技術、物聯網和眾多其他應用的不二之選。

 

Amazon DynamoDB 優勢

 

快速穩定的效能

Amazon DynamoDB 旨在為所有應用程式提供快速穩定、規模彈性的效能。服務端平均延遲通常不超過十毫秒。隨著您的資料卷增多,應用程式效能要求增加,Amazon DynamoDB 使用自動分割槽和 SSD 技術來滿足您的吞吐量需求,以任意規模提供低延遲。

高度可擴充套件

建立表時,只需指定所需的請求容量即可。如果您的應用吞吐量需求發生變化,只需使用 AWS 管理控制檯或 Amazon DynamoDB API 呼叫更新表的請求容量即可。儘管 Amazon DynamoDB 在後臺管理所有的擴充套件工作,您仍然可以在擴充套件進行過程中達成您的優先吞吐量等級。

 

 

靈活

Amazon DynamoDB 支援文件和鍵值資料結構,您可以靈活地設計最適合您的應用程式的最佳架構。 

 

精細訪問控制

Amazon DynamoDB 與 AWS Identity and Access Management (IAM) 整合,對組織內的使用者實現精細的訪問控制。您可以為每名使用者分配唯一的安全證照,控制每名使用者對服務和資源的訪問。 

完全託管

Amazon DynamoDB 是完全託管的雲 NoSQL 資料庫服務,您只需建立資料庫表並設定吞吐量,其餘事情都交由該服務來代勞。您無需再擔心資料庫管理任務,例如硬體或軟體配置、建立設定和配置、軟體更新、操作可靠的分散式資料庫叢集,或者隨著擴充套件需要在多個例項間對資料進行分割槽等問題,您只需盡享 Amazon DynamoDB 服務之大成。

(4)FaceBook圖形資料庫TAO

Facebook上,人們已經形成了一個複雜的社會關係網路,如何去儲存、擴充套件和展示這個網路是Facebook工程師的一大難題。早在幾年前,Facebook的工程師就意識到:關係型資料庫的老方法,正在逐步降低基礎設施和程式碼的效率。2009年,他們開始設計一種新的資料庫體系結構,也就是分散式資料庫TAOThe Associations and Objects)。625日,Facebook在官方部落格上公佈了支援其基礎設施細節。

Facebook的軟體工程師Mark Marchukov在部落格中表示他們之所以建立TAO的原因之一在於同時使用MySQLMemcached讀取資料太複雜了。產品工程師要工作在兩種完全不同的資料模型之間:大規模的MySQL伺服器用關係表儲存持久資料,類似數量的快取資料伺服器用來儲存SQL查詢到的鍵值對。即便是封裝在資料訪問庫中最常見的操作,也需要產品工程師對系統內部有充分的瞭解,才能高效地使用memcache-MySQL組合。

TAO的圖型架構在資訊組織方面類似於Facebook圖搜尋工具,它將世界看作由節點(物件,即人、地點和事物)和邊(關聯,即他們之間的關係)組成的圖。隨著資料量的增大,保持資料的關係模式變得不再重要,TAO及其對應的API應運而生。

Marchukov認為TAO最大的突破在於實現了圖解模型,Facebook的主要工作負載在於讀取資料,TAO證明了圖資料模型很適合這類查詢操作較多的網站。實際上,類似Neo4j的圖形資料庫一直備受關注,因為它能有效表示人際關係。 

Marchukov 在部落格中提到,TAO不僅大規模實現了圖資料結構,也使用MySQL實現硬碟上的持久儲存,同時要保證資料在各個資料中心的最終一致性,使用者才能獲取新鮮事

TAO服務執行在大量的伺服器叢集上,這些分佈在不同地理位置的叢集構成一個樹形網路。有另外的叢集用來持久儲存物件和物件關聯,RAM和快閃記憶體實現快取。這種分層結構在單獨進行不同型別的叢集擴充套件時更方便,也能有效利用伺服器硬體。

(5)Google Spanner簡介

Spanner 是Google的全球級的分散式資料庫 (Globally-Distributed Database) 。Spanner的擴充套件性達到了令人咋舌的全球級,可以擴充套件到數百萬的機器,數已百計的資料中心,上萬億的行。更給力的是,除了誇張的擴充套件性之外,他還能 同時通過同步複製和多版本來滿足外部一致性,可用性也是很好的。衝破CAP的枷鎖,在三者之間完美平衡。

Spanner是個可擴充套件,多版本,全球分散式還支援同步複製的資料庫。他是Google的第一個可以全球擴充套件並且支援外部一致的事務。Spanner能 做到這些,離不開一個用GPS和原子鐘實現的時間API。這個API能將資料中心之間的時間同步精確到10ms以內。因此有幾個給力的功能:無鎖讀事務, 原子schema修改,讀歷史資料無block 

下面主要是Spanner的背景,設計和併發控制。

Spanner背景

要搞清楚Spanner原理,先得了解SpannerGoogle的定位。

從上圖可以看到。Spanner位於F1GFS之間,承上啟下。所以先提一提F1GFS

F1

和眾多網際網路公司一樣,在早期Google大量使用了MysqlMysql是單機的,可以用Master-Slave來容錯,分割槽來擴充套件。但是需 要大量的手工運維工作,有很多的限制。因此Google開發了一個可容錯可擴充套件的RDBMS——F1。和一般的分散式資料庫不同,F1對應RDMS應有的 功能,毫不妥協。起初F1是基於Mysql的,不過會逐漸遷移到Spanner

F1有如下特點:

·        7×24高可用。哪怕某一個資料中心停止運轉,仍然可用。

·        可以同時提供強一致性和弱一致。

·        可擴充套件

·        支援SQL

·        事務提交延遲50-100ms,讀延遲5-10ms,高吞吐

眾所周知Google BigTable是重要的NoSql產品,提供很好的擴充套件性,開源世界有HBase與之對應。為什麼Google還需要F1,而不是都使用 BigTable呢?因為BigTable提供的最終一致性,一些需要事務級別的應用無法使用。同時BigTable還是NoSql,而大量的應用場景需 要有關係模型。就像現在大量的網際網路企業都使用Mysql而不願意使用HBase,因此Google才有這個可擴充套件資料庫的F1。而Spanner就是 F1的至關重要的底層儲存技術。

ColossusGFS II

Colossus也是一個不得不提起的技術。他是第二代GFS,對應開源世界的新HDFSGFS是著名的分散式檔案系統。

初代GFS是為批處理設計的。對於大檔案很友好,吞吐量很大,但是延遲較高。所以使用他的系統不得不對GFS做各種優化,才能獲得良好的效能。那為什麼 Google沒有考慮到這些問題,設計出更完美的GFS ?因為那個時候是2001年,Hadoop出生是在2007年。如果Hadoop是世界領先水平的話,GFS比世界領先水平還領先了6年。同樣的 Spanner出生大概是2009年,現在我們看到了論文,估計SpannerGoogle已經很完善,同時Google內部已經有更先進的替代技術在 醞釀了。筆者預測,最早在2015年才會出現SpannerF1的山寨開源產品。

Colossus是第二代GFSColossusGoogle重要的基礎設施,因為他可以滿足主流應用對FS的要求。Colossus的重要改進有:

·      優雅Master容錯處理 (不再有2s的停止服務時間)

·        Chunk大小隻有1MB (對小檔案很友好)

·        Master可以儲存更多的Metadata(Chunk64MB變為1MB後,Metadata會擴大64倍,但是Google也解決了)

Colossus可以自動分割槽Metadata。使用Reed-Solomon演算法來複制,可以將原先的3份減小到1.5份,提高寫的效能,降低延遲。客戶端來複制資料。具體細節筆者也猜不出。

 

BigTable, Megastore對比

Spanner主要致力於跨資料中心的資料複製上,同時也能提供資料庫功能。在Google類似的系統有BigTableMegastore。和這兩者相比,Spanner又有什麼優勢呢。

BigTableGoogle得到了廣泛的使用,但是他不能提供較為複雜的Schema,還有在跨資料中心環境下的強一致性。Megastore 有類RDBMS的資料模型,同時也支援同步複製,但是他的吞吐量太差,不能適應應用要求。Spanner不再是類似BigTable的版本化 key-value儲存,而是一個“臨時多版本”的資料庫。何為“臨時多版本”,資料是儲存在一個版本化的關係表裡面,儲存的時間資料會根據其提交的時間 打上時間戳,應用可以訪問到較老的版本,另外老的版本也會被垃圾回收掉。

Google官方認為 Spanner是下一代BigTable,也是Megastore的繼任者。

 

Google Spanner設計

功能

從高層看Spanner是通過Paxos狀態機將分割槽好的資料分佈在全球的。資料複製全球化的,使用者可以指定資料複製的份數和儲存的地點。 Spanner可以在叢集或者資料發生變化的時候將資料遷移到合適的地點,做負載均衡。使用者可以指定將資料分佈在多個資料中心,不過更多的資料中心將造成 更多的延遲。使用者需要在可靠性和延遲之間做權衡,一般來說複製12個資料中心足以保證可靠性。

作為一個全球化分散式系統,Spanner提供一些有趣的特性。

·        應用可以細粒度的指定資料分佈的位置。精確的指定資料離使用者有多遠,可以有效的控制讀延遲(讀延遲取決於最近的拷貝)。指定資料拷貝之間有多遠,可以控制 寫的延遲(寫延遲取決於最遠的拷貝)。還要資料的複製份數,可以控制資料的可靠性和讀效能。(多寫幾份,可以抵禦更大的事故)

·        Spanner還有兩個一般分散式資料庫不具備的特性:讀寫的外部一致性,基於時間戳的全域性的讀一致。這兩個特性可以讓Spanner支援一致的備份,一致的MapReduce,還有原子的Schema修改。

這寫特性都得益有Spanner有一個全球時間同步機制,可以在資料提交的時候給出一個時間戳。因為時間是系列化的,所以才有外部一致性。這個很容易理解,如果有兩個提交,一個在T1,一個在T2。那有更晚的時間戳那個提交是正確的。

這個全球時間同步機制是用一個具有GPS和原子鐘的TrueTime API提供了。這個TrueTime API能夠將不同資料中心的時間偏差縮短在10ms內。這個API可以提供一個精確的時間,同時給出誤差範圍。Google已經有了一個TrueTime API的實現。筆者覺得這個TrueTimeAPI 非常有意義,如果能單獨開源這部分的話,很多資料庫如MongoDB都可以從中受益。

體系結構

Spanner由於是全球化的,所以有兩個其他分散式資料庫沒有的概念。

·        Universe。一個Spanner部署例項稱之為一個Universe。目前全世界有3個。一個開發,一個測試,一個線上。因為一個Universe就能覆蓋全球,不需要多個。

·        Zones. 每個Zone相當於一個資料中心,一個Zone內部物理上必須在一起。而一個資料中心可能有多個Zone。可以在執行時新增移除Zone。一個Zone可以理解為一個BigTable部署例項。

 

如圖所示。一個Spanner有上面一些元件。實際的元件肯定不止這些,比如TrueTime API Server。如果僅僅知道這些知識,來構建Spanner是遠遠不夠的。但Google都略去了。那筆者就簡要介紹一下。

·        Universemaster: 監控這個universezone級別的狀態資訊

·        Placement driver:提供跨區資料遷移時管理功能

·        Zonemaster:相當於BigTableMaster。管理Spanserver上的資料。

·        Location proxy:儲存資料的Location資訊。客戶端要先訪問他才知道資料在那個Spanserver上。

·        Spanserver:相當於BigTableThunkServer。用於儲存資料。

可以看出來這裡每個元件都很有料,但是Google的論文裡只具體介紹了Spanserver的設計,筆者也只能介紹到這裡。下面詳細闡述Spanserver的設計。

 

Spanserver

本章詳細介紹Spanserver的設計實現。Spanserver的設計和BigTable非常的相似。參照下圖

從下往上看。每個資料中心會執行一套Colossus (GFS II) 。每個機器有100-1000tabletTablet概念上將相當於資料庫一張表裡的一些行,物理上是資料檔案。打個比方,一張1000行的表,有 10tablet,第1-100行是一個tablet,第101-200是一個tablet。但和BigTable不同的是BigTable裡面的 tablet儲存的是Key-Value都是stringSpanner儲存的Key多了一個時間戳:

(Key: string, timestamp: int64) ->string

因此spanner天生就支援多版本,tablet在檔案系統中是一個B-tree-like的檔案和一個write-ahead日誌。

每個Tablet上會有一個Paxos狀態機。Paxos是一個分散式一致性協議。Table的後設資料和log都儲存在上面。Paxos會選出一個 replicaleader,這個leader的壽命預設是10s,10s後重選。Leader就相當於複製資料的master,其他replica的 資料都是從他那裡複製的。讀請求可以走任意的replica,但是寫請求只有去leader。這些replica統稱為一個paxos group

每個leader replicaspanserver上會實現一個lock table還管理併發。Lock table記錄了兩階段提交需要的鎖資訊。但是不論是在Spanner還是在BigTable上,但遇到衝突的時候長時間事務會將效能很差。所以有一些操 作,如事務讀可以走lock table,其他的操作可以繞開lock table

每個leader replicaspanserver上還有一個transaction manager。如果事務在一個paxos group裡面,可以繞過transaction manager。但是一旦事務跨多個paxos group,就需要transaction manager來協調。其中一個Transactionmanager被選為leader,其他的是slave聽他指揮。這樣可以保證事務。

 

Directories and Placement

之所以SpannerBigTable有更強的擴充套件性,在於Spanner還有一層抽象的概念directory, directory是一些key-value的集合,一個directory裡面的key有一樣的字首。更妥當的叫法是bucketing。 Directory是應用控制資料位置的最小單元,可以通過謹慎的選擇Key的字首來控制。據此筆者可以猜出,在設計初期,Spanner是作為F1的存 儲系統而設立,甚至還設計有類似directory的層次結構,這樣的層次有很多好處,但是實現太複雜被摒棄了。

Directory作為資料放置的最小單元,可以在paxos group裡面移來移去。Spanner移動一個directory一般出於如下幾個原因:

·        一個paxos group的負載太大,需要切分

·        將資料移動到access更近的地方

·        將經常同時訪問的directory放到一個paxos group裡面

Directory可以在不影響client的前提下,在後臺移動。移動一個50MBdirectory大概需要的幾秒鐘。

那麼directorytablet又是什麼關係呢。可以理解為Directory是一個抽象的概念,管理資料的單元;而tablet是物理的東 西,資料檔案。由於一個Paxos group可能會有多個directory,所以spannertablet實現和BigTabletablet實現有些不同。BigTable的 tablet是單個順序檔案。Google有個專案,名為Level DB,是BigTable的底層,可以看到其實現細節。而Spannertablet可以理解是一些基於行的分割槽的容器。這樣就可以將一些經常同時訪問 的directory放在一個tablet裡面,而不用太在意順序關係。

paxos group之間移動directory是後臺任務。這個操作還被用來移動replicas。移動操作設計的時候不是事務的,因為這樣會造成大量的讀寫 block。操作的時候是先將實際資料移動到指定位置,然後再用一個原子的操作更新後設資料,完成整個移動過程。

Directory還是記錄地理位置的最小單元。資料的地理位置是由應用決定的,配置的時候需要指定複製數目和型別,還有地理的位置。比如(上海, 複製2份;南京複製1。這樣應用就可以根據使用者指定終端使用者實際情況決定的資料儲存位置。比如中國隊的資料在亞洲有3份拷貝日本隊的資料全球都有拷貝。

前面對directory還是被簡化過的,還有很多無法詳述。

 

資料模型

Spanner的資料模型來自於Google內部的實踐。在設計之初,Spanner就決心有以下的特性:

·        支援類似關聯式資料庫的schema

·        Query語句

·        支援廣義上的事務

為何會這樣決定呢?在Google內部還有一個Megastore,儘管要忍受效能不夠的折磨,但是在Google300多個應用在用它,因為 Megastore支援一個類似關聯式資料庫的schema,而且支援同步複製 (BigTable只支援最終一致的複製。使用Megastore的應用有大名鼎鼎的Gmail, Picasa, Calendar, Android MarketAppEngine。 而必須對Query語句的支援,來自於廣受歡迎的Dremel,筆者不久前寫了篇文章來介紹他。 最後對事務的支援是比不可少了,BigTableGoogle內部被抱怨的最多的就是其只能支援行事務,再大粒度的事務就無能為力了。Spanner的 開發者認為,過度使用事務造成的效能下降的惡果,應該由應用的開發者承擔。應用開發者在使用事務的時候,必須考慮到效能問題。而資料庫必須提供事務機制, 而不是因為效能問題,就乾脆不提供事務支援。

資料模型是建立在directorykey-value模型的抽象之上的。一個應用可以在一個universe中建立一個或多個 database,在每個database中建立任意的tableTable看起來就像關係型資料庫的表。有行,有列,還有版本。Query語句看起來 是多了一些擴充套件的SQL語句。

Spanner的資料模型也不是純正的關係模型,每一行都必須有一列或多列元件。看起來還是Key-value。主鍵組成Key,其他的列是Value。但這樣的設計對應用也是很有裨益的,應用可以通過主鍵來定位到某一行。

上圖是一個例子。對於一個典型的相簿應用,需要儲存其使用者和相簿。可以用上面的兩個SQL來建立表。Spanner的表是層次化的,最頂層的表是 directory table。其他的表建立的時候,可以用interleave in parent來什麼層次關係。這樣的結構,在實現的時候,Spanner可以將巢狀的資料放在一起,這樣在分割槽的時候效能會提升很多。否則Spanner 無法獲知最重要的表之間的關係。

 

TrueTime

TrueTime API 是一個非常有創意的東西,可以同步全球的時間。上表就是TrueTime APITT.now()可以獲得一個絕對時間TTinterval,這個值和UnixTime是相同的,同時還能夠得到一個誤差e。 TT.after(t)TT.before(t)是基於TT.now()實現的。

那這個TrueTime API實現靠的是GFS和原子鐘。之所以要用兩種技術來處理,是因為導致這兩個技術的失敗的原因是不同的。GPS會有一個天線,電波干擾會導致其失靈。原子鐘很穩定。當GPS失靈的時候,原子鐘仍然能保證在相當長的時間內,不會出現偏差。

實際部署的時候。每個資料中心需要部署一些Master機器,其他機器上需要有一個slave程式來從Master同步。有的Master用 GPS,有的Master用原子鐘。這些Master物理上分佈的比較遠,怕出現物理上的干擾。比如如果放在一個機架上,機架被人碰倒了,就全宕了。另外 原子鐘不是並很貴。Master自己還會不斷比對,新的時間資訊還會和Master自身時鐘的比對,會排除掉偏差比較大的,並獲得一個保守的結果。最終 GPS master提供時間精確度很高,誤差接近於0

每個Slave後臺程式會每個30秒從若干個Master更新自己的時鐘。為了降低誤差,使用Marzullo演算法。每個slave還會計算出自己的誤差。這裡的誤差包括的通訊的延遲,機器的負載。如果不能訪問Master,誤差就會越走越大,知道重新可以訪問。

 

Google Spanner併發控制

Spanner使用TrueTime來控制併發,實現外部一致性。支援以下幾種事務。

·        讀寫事務

·        只讀事務

·        快照讀,客戶端提供時間戳

·        快照讀,客戶端提供時間範圍

例如一個讀寫事務發生在時間t,那麼在全世界任何一個地方,指定t快照讀都可以讀到寫入的值。

上表是Spanner現在支援的事務。單獨的寫操作都被實現為讀寫事務 ; 單獨的非快照被實現為只讀事務。事務總有失敗的時候,如果失敗,對於這兩種操作會自己重試,無需應用自己實現重試迴圈。

時間戳的設計大大提高了只讀事務的效能。事務開始的時候,要宣告這個事務裡沒有寫操作,只讀事務可不是一個簡單的沒有寫操作的讀寫事務。它會用一個 系統時間戳去讀,所以對於同時的其他的寫操作是沒有Block的。而且只讀事務可以在任意一臺已經更新過的replica上面讀。

對於快照讀操作,可以讀取以前的資料,需要客戶端指定一個時間戳或者一個時間範圍。Spanner會找到一個已經充分更新好的replica上讀取。

還有一個有趣的特性的是,對於只讀事務,如果執行到一半,該replica出現了錯誤。客戶端沒有必要在本地快取剛剛讀過的時間,因為是根據時間戳讀取的。只要再用剛剛的時間戳讀取,就可以獲得一樣的結果。

 

讀寫事務

正如BigTable一樣,Spanner的事務是會將所有的寫操作先快取起來,在Commit的時候一次提交。這樣的話,就讀不出在同一個事務中寫的資料了。不過這沒有關係,因為Spanner的資料都是有版本的。

在讀寫事務中使用wound-wait演算法來避免死鎖。當客戶端發起一個讀寫事務的時候,首先是讀操作,他先找到相關資料的leader replica,然後加上讀鎖,讀取最近的資料。在客戶端事務存活的時候會不斷的向leader發心跳,防止超時。當客戶端完成了所有的讀操作,並且快取 了所有的寫操作,就開始了兩階段提交。客戶端閒置一個coordinator group,並給每一個leader傳送coordinatorid和快取的寫資料。

leader首先會上一個寫鎖,他要找一個比現有事務晚的時間戳。通過Paxos記錄。每一個相關的都要給coordinator傳送他自己準備的那個時間戳。

Coordinatorleader一開始也會上個寫鎖,當大家傳送時間戳給他之後,他就選擇一個提交時間戳。這個提交的時間戳,必須比剛剛的所有時間戳晚,而且還要比TT.now()+誤差時間 還有晚。這個Coordinator將這個資訊記錄到Paxos

在讓replica寫入資料生效之前,coordinator還有再等一會。需要等兩倍時間誤差。這段時間也剛好讓Paxos來同步。因為等待之 後,在任意機器上發起的下一個事務的開始時間,都比如不會比這個事務的結束時間早了。然後coordinator將提交時間戳傳送給客戶端還有其他的 replica。他們記錄日誌,寫入生效,釋放鎖。

 

只讀事務

對於只讀事務,Spanner首先要指定一個讀事務時間戳。還需要了解在這個讀操作中,需要訪問的所有的讀的KeySpanner可以自動確定Key的範圍。

如果Key的範圍在一個Paxos group內。客戶端可以發起一個只讀請求給group leaderleader選一個時間戳,這個時間戳要比上一個事務的結束時間要大。然後讀取相應的資料。這個事務可以滿足外部一致性,讀出的結果是最後 一次寫的結果,並且不會有不一致的資料。

如果Key的範圍在多個Paxos group內,就相對複雜一些。其中一個比較複雜的例子是,可以遍歷所有的group leaders,尋找最近的事務發生的時間,並讀取。客戶端只要時間戳在TT.now().latest之後就可以滿足要求了。 

 

參考文獻:

1、《挑戰傳統關係型資料庫:FaceBook圖形資料庫TAO揭祕》 Jordan Novet

2、《雲時代的分散式資料庫:阿里分散式資料庫服務DRDS》 沈詢

3、《大資料與雲端計算》李永紅

4、《基於雲端計算的資料庫分析》 謝紅 

5、《全球級的分散式資料庫Google Spanner原理》

相關文章