|
文 / 丁藝明
傳統(tǒng)互聯(lián)網(wǎng)正在邁向一個全新的時代——社交服務(wù)網(wǎng)(Social NETworking Service)時代,從“人與機(jī)器”的時代邁向“人與人”的時代。互聯(lián)網(wǎng)社交服務(wù)網(wǎng)站的發(fā)展驗證了“六度分隔理論”(Six Degrees of Separation),即“人際關(guān)系脈絡(luò)方面你必然可以通過不超出六位中間人間接與世上任意先生女士相識”。個體的社交圈會不斷地擴(kuò)大和重疊并最終形成大的社交網(wǎng)絡(luò)。無論是國外的Facebook、MySpace、Twitter,還是國內(nèi)的開心網(wǎng)、人人網(wǎng)等都一頭扎進(jìn)社交網(wǎng),因為他們認(rèn)定社交網(wǎng)必然掀起新一輪的互聯(lián)網(wǎng)革命。
社交網(wǎng)的一個顯著特點是支持巨大用戶數(shù),例如Facebook支持超過3億的用戶,其數(shù)據(jù)中心運行著超過萬臺的服務(wù)器,為遍布全球的用戶提供信息通訊服務(wù)。另外,任何兩個社交網(wǎng)用戶都可能交互,也就是必須支持任何兩個數(shù)據(jù)庫用戶的數(shù)據(jù)關(guān)聯(lián)操作。這對于服務(wù)端的數(shù)據(jù)庫管理提出了極大的挑戰(zhàn)。
關(guān)系數(shù)據(jù)庫與 NoSQL 數(shù)據(jù)庫
關(guān)系數(shù)據(jù)庫使用者遵循一些數(shù)據(jù)庫范式,這些范式是數(shù)據(jù)庫設(shè)計中的一系列原理和技術(shù),目的是為了減少數(shù)據(jù)庫中數(shù)據(jù)冗余和增進(jìn)數(shù)據(jù)的一致性。結(jié)構(gòu)化查詢語言SQL大量使用多表連接操作,SQL的通用性可以為使用者帶來很多方便。
隨著越來越多大規(guī)模工作負(fù)荷應(yīng)用的發(fā)行,對可伸縮性的需求,可能會變得非常迅速和無比龐大。
關(guān)系數(shù)據(jù)庫的確能伸縮自如,但通常只能在單臺服務(wù)器節(jié)點上進(jìn)行。例如采用表分區(qū)技術(shù),一個表格可以由多個物理文件組成,雖然表格的容量增大了,但該表格仍然只能由一數(shù)據(jù)庫引擎管理;另外增加一物理文件時,表格Schema得做改動,也就是還不能支持動態(tài)擴(kuò)容。
一旦單節(jié)點的能力抵達(dá)上限,就得通過多服務(wù)器節(jié)點來擴(kuò)展來分發(fā)負(fù)載。這時關(guān)系數(shù)據(jù)庫的復(fù)雜性就開始影響其潛在的擴(kuò)展規(guī)模了。RDBMS支持分區(qū)視圖(Partition View) 技術(shù),也就是支持聯(lián)合數(shù)據(jù)庫(Federated Database)(如圖1)。一個分區(qū)視圖可以由多個分布在不同數(shù)據(jù)庫節(jié)點服務(wù)器上的表格組合而成,數(shù)據(jù)庫用戶看到的只是該視圖,不必關(guān)心物理表格。通過數(shù)據(jù)水平分割技術(shù),分區(qū)視圖把負(fù)載分擔(dān)到多個數(shù)據(jù)庫節(jié)點服務(wù)器上。擴(kuò)容時,該方法除了需改動視圖定義外,分區(qū)視圖成為分布式數(shù)據(jù)庫系統(tǒng)的中心,存在單點故障問題。另外,跨數(shù)據(jù)庫節(jié)點之間多表格間連接操作的支持出現(xiàn)極大困難。
圖1 IBM聯(lián)邦數(shù)據(jù)庫的體系結(jié)構(gòu)
當(dāng)試圖擴(kuò)展數(shù)據(jù)庫系統(tǒng)到成百上千個節(jié)點時,將導(dǎo)致不堪復(fù)雜性之重負(fù),這一特點使得RDBMS在大型分布式系統(tǒng)平臺市場里的生存能力被大幅削減。
為了能向客戶提供一個伸縮自如的空間存放應(yīng)用數(shù)據(jù),供應(yīng)商實際上只有一種真正的選擇——實現(xiàn)一種新型的專注于可擴(kuò)展性的數(shù)據(jù)庫系統(tǒng),而犧牲掉關(guān)系數(shù)據(jù)庫所帶來的其他好處。NoSQL是非關(guān)系型數(shù)據(jù)存儲的廣義定義,它打破了長久以來關(guān)系型數(shù)據(jù)庫與ACID理論大一統(tǒng)的局面。NoSQL數(shù)據(jù)存儲不需要固定的表結(jié)構(gòu),通常也不存在連接操作,在超大型數(shù)據(jù)存取上具備關(guān)系型數(shù)據(jù)庫無法比擬的性能優(yōu)勢。該術(shù)語在2009 年初得到了廣泛認(rèn)同,其中Key-Value數(shù)據(jù)模型是解決大型數(shù)據(jù)庫系統(tǒng)擴(kuò)充問題的一種可行的解決方案。
Berkeley DB Key-Value數(shù)據(jù)模型
Berkeley DB是一種支持Key-Value數(shù)據(jù)模型的嵌入式數(shù)據(jù)庫存儲引擎。它不支持Client/Server網(wǎng)絡(luò)訪問方式,程序通過進(jìn)程內(nèi)的API訪問數(shù)據(jù)庫,不支持SQL或者其他數(shù)據(jù)庫查詢語言,不支持表結(jié)構(gòu)和數(shù)據(jù)列。訪問數(shù)據(jù)庫的程序自主決定數(shù)據(jù)如何儲存在記錄里,一條記錄由一個稱為鍵(Key)的數(shù)據(jù)塊和一個稱為值(Value)的數(shù)據(jù)塊組成。Berkeley DB不對記錄里的數(shù)據(jù)進(jìn)行任何包裝。應(yīng)用程序可通過回調(diào)函數(shù)來定義不同鍵之間的大小關(guān)系,記錄和它的鍵都可以達(dá)到4GB的長度。盡管架構(gòu)簡單,Berkeley DB卻支持很多高級的數(shù)據(jù)庫特性,比如ACID 數(shù)據(jù)庫事務(wù)處理、細(xì)粒度鎖、 XA接口、熱備份以及同步復(fù)制。Berkley DB為不同用戶提供多種功能集(Feature Set):支持單個寫線程的數(shù)據(jù)存儲(Data Store);支持多并發(fā)寫線程的并發(fā)數(shù)據(jù)存儲(Concurrent Data Store);支持ACID和災(zāi)難恢復(fù)的事務(wù)數(shù)據(jù)存儲(Transactional Data Store);通過復(fù)制支持容錯的高可靠數(shù)據(jù)存儲(High Availability)。
關(guān)系數(shù)據(jù)庫系統(tǒng)由存儲引擎和關(guān)系引擎兩個獨立部分組成。存儲引擎負(fù)責(zé)記錄存儲、索引和事務(wù)處理,關(guān)系引擎負(fù)責(zé)基于存儲引擎提供的服務(wù),分析SQL、制定查詢執(zhí)行計劃等。Berkeley DB是一種存儲引擎。例如MySQL數(shù)據(jù)庫可采用MyISAM、InnoDB、Berkeley DB等存儲引擎,如圖2所示。
圖2 MySQL使用的不同的存儲引擎
Berkeley DB支持平衡樹(BTree)、哈希(Hash)、隊列(Queue)和記錄(Record)等數(shù)據(jù)集存儲和索引方式,還支持根據(jù)Key-Value中的Key創(chuàng)建集群索引(Clustered Index)。這樣記錄集的物理次序就根據(jù)Key值大小來排列。如果要查詢結(jié)果記錄集的鍵值為給定的一個范圍,該特性對于支持這種類型的快速查詢起了很大作用。Berkeley DB的一個Key-Value記錄集稱為一個數(shù)據(jù)庫,會存儲在一個單獨文件中。Berkeley DB通過創(chuàng)建輔助數(shù)據(jù)庫(Secondary Database),允許對記錄集建立非集群索引(Non-Clustered Index)。非集群索引適用于快速查詢結(jié)果為一條記錄,該記錄的鍵值為給定的一個值。例如社交網(wǎng)用戶數(shù)據(jù)集:
User <UID, First_Name, Last_Name, Icon, E-mail>
如果以UID作為主數(shù)據(jù)庫的鍵,其他字段作為主數(shù)據(jù)庫的值,可再創(chuàng)建一個輔助數(shù)據(jù)庫,以E-mail作為輔助數(shù)據(jù)庫的鍵,輔助數(shù)據(jù)庫的值為E-mail所對應(yīng)的UID,也就是指向主數(shù)據(jù)庫記錄的指針。若在一個Key-Value數(shù)據(jù)庫查詢,一般可根據(jù)查詢條件創(chuàng)建成一個鍵值,引擎返回一個游標(biāo)(Cursor),該游標(biāo)指向等于或大于該鍵值的結(jié)果數(shù)據(jù)集。
不難看出Berkeley DB使用的索引技術(shù)與SQL Server、Oracle等高端數(shù)據(jù)庫系統(tǒng)是一樣的。RDBMS中經(jīng)常使用的表格連接操作,在Berkeley DB中不再支持,需要應(yīng)用程序去實現(xiàn)兩個數(shù)據(jù)集的連接操作。這是Key-Value數(shù)據(jù)模型與關(guān)系數(shù)據(jù)模型典型的區(qū)別。
Berkeley DB除了作為MySQL的存儲引擎之外,還應(yīng)用在OpenLDAP、MemCached等知名軟件。
與Berkeley DB類似的數(shù)據(jù)庫引擎還有Tokyo CabiNET/ Tyrant等。
社交網(wǎng)數(shù)據(jù)庫系統(tǒng)Cassandra
以Facebook用戶數(shù)據(jù)集為例,不可能把3億條數(shù)據(jù)集存放在同一個表格、文件或由同一臺計算機(jī)處理,這要求系統(tǒng)能支持?jǐn)?shù)據(jù)分區(qū),把數(shù)據(jù)集分割在多臺節(jié)點計算機(jī)中,每臺計算機(jī)分擔(dān)一部分負(fù)載,當(dāng)用戶增加到一定程度時,系統(tǒng)能允許加入新的節(jié)點計算機(jī),并且盡可能地減少數(shù)據(jù)遷移。
2007年10月30日,Amazon的CTO Werner Vogels發(fā)表了一篇文章,討論了一種基于Key-Value數(shù)據(jù)模型的存儲系統(tǒng)Dynamo。該系統(tǒng)支撐了不少Amazon的面向電子商務(wù)等關(guān)鍵性應(yīng)用,它采用的存儲引擎是 Berkeley DB 事務(wù)數(shù)據(jù)存儲(Transactional Data Store)。Dynamo系統(tǒng)主要為存儲1M左右甚至更小的內(nèi)容,如購物車、推薦列表等。Dynamo設(shè)計上有下面一些特點。
- 通過數(shù)據(jù)分區(qū)復(fù)制來支持高可靠性與高可伸縮性。
- 始終可寫。
- 一致性與寫入速度的折中,不要求同步寫入所有副本。
- 對稱,完全去中心化,人工管理工作很小。
Cassandra DB最初由Facebook開發(fā),后來轉(zhuǎn)變成為開源項目。它是一個為網(wǎng)絡(luò)社交云計算設(shè)計的數(shù)據(jù)庫,主要特點是它不再是一個數(shù)據(jù)庫,而是由一堆數(shù)據(jù)庫節(jié)點共同構(gòu)成的一個分布式網(wǎng)絡(luò)服務(wù),對Cassandra的一個寫操作會被復(fù)制到其他節(jié)點上去,對Cassandra的讀操作也會被路由到某個節(jié)點上面去讀取。對于Cassandra群集來說,擴(kuò)展性能是比較簡單的事情,只管在群集里面添加節(jié)點就可以了。
Cassandra的用戶包括Facebook、Twitter和Digg等。Digg工程副總裁John Quinn說:“Cassandra采用完全分散的模式,每個節(jié)點都一樣,不會出現(xiàn)單點故障。它的容錯率也非常高,數(shù)據(jù)可以被復(fù)制到數(shù)據(jù)中心的多個節(jié)點中。它還非常具有彈性,隨著新設(shè)備的加入,其讀寫吞吐量將呈線性增加。”
Cassandra以Amazon專有的完全分布式的Dynamo為基礎(chǔ),結(jié)合了Google BigTable基于列族(Column Family)的數(shù)據(jù)模型。P2P去中心化的存儲。很多方面都可以稱之為Dynamo 2.0。
圖3為Cassandra、Dynamo、Key-Value之間的關(guān)系及在社交網(wǎng)上的應(yīng)用。箭頭表示依賴關(guān)系。
圖3 Cassandra、Dynamo、Key-Value關(guān)系圖
分布式存儲系統(tǒng)Dynamo
Dynamo采用Consistent Hashing算法來實現(xiàn)數(shù)據(jù)分區(qū)。
Consistent Hashing基本原理是:首先求出服務(wù)器節(jié)點的哈希值,并將其配置到0~2^32的圓上。然后用同樣的方法求出存儲數(shù)據(jù)的鍵的哈希值,并映射到圓上。再從數(shù)據(jù)映射到的位置開始順時針查找,將數(shù)據(jù)保存到找到的第一個服務(wù)器上。如果超過2^32仍然找不到服務(wù)器,就會保存到第一臺服務(wù)器上。如圖4所示。
圖4 數(shù)據(jù)分割到4個節(jié)點數(shù)據(jù)庫
如果添加一臺服務(wù)器。只有在圓上,增加服務(wù)器的地點逆時針方向的第一臺服務(wù)器上的部分?jǐn)?shù)據(jù)需要遷移到新的節(jié)點數(shù)據(jù)庫。如圖5所示。
圖5 添加Node5后需要遷移的數(shù)據(jù)
數(shù)據(jù)分區(qū)后,數(shù)據(jù)塊被復(fù)制到N個節(jié)點上。復(fù)制時因為更新產(chǎn)生的一致性問題的維護(hù)采取類似拜占庭容錯Quorum協(xié)議(Byzantine Fault-tolerance Quorum)的機(jī)制以及去中心化的復(fù)制同步協(xié)議。當(dāng)一個存儲節(jié)點被認(rèn)為是拜占庭節(jié)點時,它的行為可能任意偏移,表現(xiàn)在:拒絕響應(yīng)請求、發(fā)送錯誤消息、存儲錯誤信息。Quorum協(xié)議中除了N之外還有兩個關(guān)鍵參數(shù):R與W。R代表一次成功的讀取操作中最小參與節(jié)點數(shù)量,W代表一次成功的寫操作中最小參與節(jié)點數(shù)量。R和W直接影響性能、一致性。R 和 W 值過小則影響一致性,過大則影響效率,這兩個值要平衡。如果W設(shè)置為1,則一個實例中只要有一個節(jié)點可寫就寫成功,不會影響寫效率;如果R設(shè)置為1,只要有一個節(jié)點可讀,就讀成功,不會影響讀效率。
Facebook數(shù)據(jù)庫查詢語言:FQL
Facebook為開發(fā)者提供一套和SQL風(fēng)格一致的數(shù)據(jù)庫查詢語言,稱為Facebook Query Language (FQL)。FQL是一種基于列的數(shù)據(jù)查詢語言。提供豐富的條件查詢,甚至包括子查詢。
例如,以下FQL查詢已安裝Facebook應(yīng)用程序的用戶$app_user的好友ID集合:
SELECT uid FROM user WHERE is_app_user = 1 AND
uid IN (SELECT uid2 FROM friend WHERE uid1 = $app_user)
it知識庫:社交網(wǎng)站數(shù)據(jù)庫技術(shù)分析,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。