|
簡(jiǎn)介
在眾多不同的數(shù)據(jù)模型里,關(guān)系數(shù)據(jù)模型自80年代就處于統(tǒng)治地位,而且有不少實(shí)現(xiàn),如Oracle、MySQL和MSSQL,它們也被稱為關(guān)系數(shù)據(jù)庫管理系統(tǒng)(RDBMS)。然而,最近隨著關(guān)系數(shù)據(jù)庫使用案例的不斷增加,一些問題也暴露了出來,這主要是因?yàn)閮蓚€(gè)原因:數(shù)據(jù)建模中的一些缺陷和問題,以及在大數(shù)據(jù)量和多服務(wù)器之上進(jìn)行水平伸縮的限制。兩個(gè)趨勢(shì)讓這些問題引起了全球軟件社區(qū)的重視:
- 用戶、系統(tǒng)和傳感器產(chǎn)生的數(shù)據(jù)量呈指數(shù)增長(zhǎng),其增長(zhǎng)速度因大部分?jǐn)?shù)據(jù)量集中在象Amazon、Google和其他云服務(wù)這樣的分布式系統(tǒng)上而進(jìn)一步加快。
- 數(shù)據(jù)內(nèi)部依賴和復(fù)雜度的增加,這一問題因互聯(lián)網(wǎng)、Web2.0、社交網(wǎng)絡(luò),以及對(duì)大量不同系統(tǒng)的數(shù)據(jù)源開放和標(biāo)準(zhǔn)化的訪問而加劇。
在應(yīng)對(duì)這些趨勢(shì)時(shí),關(guān)系數(shù)據(jù)庫產(chǎn)生了更多的問題。這導(dǎo)致大量解決這些問題某些特定方面的不同技術(shù)的出現(xiàn),它們可以與現(xiàn)有RDBMS相互配合或代替它們-亦被稱為混合持久化(Polyglot Persistence)。數(shù)據(jù)庫替代品并不是新鮮事物,它們已經(jīng)以對(duì)象數(shù)據(jù)庫(OODBMS)、層次數(shù)據(jù)庫(如LDAP)等形式存在很長(zhǎng)時(shí)間了。但是,過去幾年間,出現(xiàn)了大量新項(xiàng)目,它們被統(tǒng)稱為NOSQL數(shù)據(jù)庫(NOSQL-databases)
本文旨在介紹圖形數(shù)據(jù)庫(Graph Database)在NOSQL運(yùn)動(dòng)里的地位,第二部分則是對(duì)Neo4j(一種基于Java的圖形數(shù)據(jù)庫)的簡(jiǎn)介。
NOSQL環(huán)境
NOSQL(Not Only SQL,不限于SQL)是一類范圍非常廣泛的持久化解決方案,它們不遵循關(guān)系數(shù)據(jù)庫模型,也不使用SQL作為查詢語言。
簡(jiǎn)單地講,NOSQL數(shù)據(jù)庫可以按照它們的數(shù)據(jù)模型分成4類:
- 鍵-值存儲(chǔ)庫(Key-Value-stores)
- BigTable實(shí)現(xiàn)(BigTable-implementations)
- 文檔庫(Document-stores)
- 圖形數(shù)據(jù)庫(Graph Database)
就Voldemort或Tokyo CabiNET這類鍵/值系統(tǒng)而言,最小的建模單元是鍵-值對(duì)。對(duì)BigTable的克隆品來講,最小建模單元?jiǎng)t是包含不同個(gè)數(shù)屬性的元組,至于象CouchDB和MongoDB這樣的文檔庫,最小單元是文檔。圖形數(shù)據(jù)庫則干脆把整個(gè)數(shù)據(jù)集建模成一個(gè)大型稠密的網(wǎng)絡(luò)結(jié)構(gòu)。
在此,讓我們深入檢閱NOSQL數(shù)據(jù)庫的兩個(gè)有意思的方面:伸縮性和復(fù)雜度。
1.伸縮性
CAP: ACID vs. BASE
為了保證數(shù)據(jù)完整性,大多數(shù)經(jīng)典數(shù)據(jù)庫系統(tǒng)都是以事務(wù)為基礎(chǔ)的。這全方位保證了數(shù)據(jù)管理中數(shù)據(jù)的一致性。這些事務(wù)特性也被稱為ACID(A代表原子性、C表示一致性、I是隔離性、D則為持久性)。然而,ACID兼容系統(tǒng)的向外擴(kuò)展已經(jīng)表現(xiàn)為一個(gè)問題。在分布式系統(tǒng)中,高可用性不同方面之間產(chǎn)生的沖突沒有完全得到解決-亦稱CAP法則:
- 強(qiáng)一致性(C):所有客戶端看到的數(shù)據(jù)是同一個(gè)版本,即使是數(shù)據(jù)集發(fā)生了更新-如利用兩階段提交協(xié)議(XA事務(wù)),和ACID,
- 高可用性(A):所有客戶端總能找到所請(qǐng)求數(shù)據(jù)的至少一個(gè)版本,即使集群中某些機(jī)器已經(jīng)宕機(jī),
- 分區(qū)容忍性(P):整個(gè)系統(tǒng)保持自己的特征,即使是被部署到不同服務(wù)器上的時(shí)候,這對(duì)客戶端來講是透明的。
CAP法則假定向外擴(kuò)展的3個(gè)不同方面中只有兩個(gè)可以同時(shí)完全實(shí)現(xiàn)。
為了能處理大型分布式系統(tǒng),讓我們深入了解所采用的不同CAP特征。
很多NOSQL數(shù)據(jù)庫首先已經(jīng)放寬了對(duì)于一致性(C)的要求,以期得到更好的可用性(A)和分區(qū)容忍性(P)。這產(chǎn)生了被稱為BASE(基本(B)可用性(A)、軟狀態(tài)(S)、最終一致性(E))的系統(tǒng)。它們沒有經(jīng)典意義上的事務(wù),并且在數(shù)據(jù)模型上引入了約束,以支持更好的分區(qū)模式(如Dynamo系統(tǒng)等)。關(guān)于CAP、ACID和BASE的更深入討論可以在這篇介紹里找到。
2.復(fù)雜度
蛋白質(zhì)同源網(wǎng)絡(luò)(Protein Homology NETwork),感謝Alex Adai:細(xì)胞和分子生物學(xué)院-德州大學(xué)
數(shù)據(jù)和系統(tǒng)的互聯(lián)性增加產(chǎn)生了一種無法用簡(jiǎn)單明了或領(lǐng)域無關(guān)(domain-independent)方式進(jìn)行伸縮和自動(dòng)分區(qū)的稠密數(shù)據(jù)集,甚至連Todd Hoff也提到了這一問題。關(guān)于大型復(fù)雜數(shù)據(jù)集的可視化內(nèi)容可以訪問可視化復(fù)雜度(Visual Complexity)。
關(guān)系模型
在把關(guān)系數(shù)據(jù)模型扔進(jìn)故紙堆之前,我們不應(yīng)該忘記關(guān)系數(shù)據(jù)庫系統(tǒng)成功的一個(gè)原因是遵照E.F. Codd的想法,關(guān)系數(shù)據(jù)模型通過規(guī)范化的手段原則上能夠建模任何數(shù)據(jù)結(jié)構(gòu)且沒有信息冗余和丟失。建模完成之后,就可以使用SQL以一種非常強(qiáng)大的方式插入、修改和查詢數(shù)據(jù)。甚至有些數(shù)據(jù)庫,為了插入速度或針對(duì)不同使用情況(如OLTP、OLAP、Web應(yīng)用或報(bào)表)的多維查詢(星形模式),對(duì)模式實(shí)現(xiàn)了優(yōu)化。
這只是理論。然而在實(shí)踐中,RDBM遇到了前面提到的CAP問題的限制,以及由高性能查詢實(shí)現(xiàn)而產(chǎn)生的問題:聯(lián)結(jié)大量表、深度嵌套的SQL查詢。其他問題包括伸縮性、隨時(shí)間的模式演變,樹形結(jié)構(gòu)的建模,半結(jié)構(gòu)化數(shù)據(jù),層級(jí)和網(wǎng)絡(luò)等。
關(guān)系模型也很難適應(yīng)當(dāng)前軟件開發(fā)的方法,如面向?qū)ο蠛蛣?dòng)態(tài)語言,這被稱為對(duì)象-關(guān)系阻抗失配。由此,象Java的Hibernate這樣的ORM層被開發(fā)了出來,而且被應(yīng)用到這種混合環(huán)境里。它們固然簡(jiǎn)化了把對(duì)象模型映射到關(guān)系數(shù)據(jù)模型的任務(wù),但是沒有優(yōu)化查詢的性能。尤其是半結(jié)構(gòu)化數(shù)據(jù)往往被建模成具有許多列的大型表,其中很多行的許多列是空的(稀疏表),這導(dǎo)致了拙劣的性能。甚至作為替代方法,把這些結(jié)構(gòu)建模成大量的聯(lián)結(jié)表,也有問題。因?yàn)镽DBMS中的聯(lián)結(jié)是一種非常昂貴的集合操作。
圖形是關(guān)系規(guī)范化的一種替代技術(shù)
看看領(lǐng)域模型在數(shù)據(jù)結(jié)構(gòu)上的方案,有兩個(gè)主流學(xué)派- RDBMS采用的關(guān)系方法和圖-即網(wǎng)絡(luò)結(jié)構(gòu),如語義網(wǎng)用到的。
盡管圖結(jié)構(gòu)在理論上甚至可以用RDBMS規(guī)范化,但由于關(guān)系數(shù)據(jù)庫的實(shí)現(xiàn)特點(diǎn),對(duì)于象文件樹這樣的遞歸結(jié)構(gòu)和象社交圖這樣的網(wǎng)絡(luò)結(jié)構(gòu)有嚴(yán)重的查詢性能影響。網(wǎng)絡(luò)關(guān)系上的每次操作都會(huì)導(dǎo)致RDBMS上的一次"聯(lián)結(jié)"操作,以兩個(gè)表的主鍵集合間的集合操作來實(shí)現(xiàn),這種操作不僅緩慢并且無法隨著這些表中元組數(shù)量的增加而伸縮。
屬性圖形(Property Graph)的基本術(shù)語
在圖的領(lǐng)域,并沒有一套被廣泛接受的術(shù)語,存在著很多不同類型的圖模型。但是,有人致力于創(chuàng)建一種屬性圖形模型(Property Graph Model),以期統(tǒng)一大多數(shù)不同的圖實(shí)現(xiàn)。按照該模型,屬性圖里信息的建模使用3種構(gòu)造單元:
- 節(jié)點(diǎn)(即頂點(diǎn))
- 關(guān)系(即邊)-具有方向和類型(標(biāo)記和標(biāo)向)
- 節(jié)點(diǎn)和關(guān)系上面的屬性(即特性)
更特殊的是,這個(gè)模型是一個(gè)被標(biāo)記和標(biāo)向的屬性多重圖(multigraph)。被標(biāo)記的圖每條邊都有一個(gè)標(biāo)簽,它被用來作為那條邊的類型。有向圖允許邊有一個(gè)固定的方向,從末或源節(jié)點(diǎn)到首或目標(biāo)節(jié)點(diǎn)。屬性圖允許每個(gè)節(jié)點(diǎn)和邊有一組可變的屬性列表,其中的屬性是關(guān)聯(lián)某個(gè)名字的值,簡(jiǎn)化了圖形結(jié)構(gòu)。多重圖允許兩個(gè)節(jié)點(diǎn)之間存在多條邊。這意味著兩個(gè)節(jié)點(diǎn)可以由不同邊連接多次,即使兩條邊有相同的尾、頭和標(biāo)記。
下圖顯示了一個(gè)被標(biāo)記的小型屬性圖。
TinkerPop有關(guān)的小型人員圖
圖論的巨大用途被得到了認(rèn)可,它跟不同領(lǐng)域的很多問題都有關(guān)聯(lián)。最常用的圖論算法包括各種類型的最短路徑計(jì)算、測(cè)地線(Geodesic Path)、集中度測(cè)量(如PageRank、特征向量集中度、親密度、關(guān)系度、HITS等)。然而,在很多情況下,這些算法的應(yīng)用僅限制于研究,因?yàn)閷?shí)際中沒有任何可用于產(chǎn)品環(huán)境下的高性能圖形數(shù)據(jù)庫實(shí)現(xiàn)。幸運(yùn)的是,近些年情況有所改觀。有幾個(gè)項(xiàng)目已經(jīng)被開發(fā)出來,而且目標(biāo)直指24/7的產(chǎn)品環(huán)境:
- Neo4j -開源的Java屬性圖形模型
- AllegroGraph,閉源,RDF-QuadStore
- Sones -閉源,關(guān)注于.NET
- Virtuoso -閉源,關(guān)注于RDF
- HyergraphDB -開源的Java超圖模型
- Others like InfoGrid、Filament、FlockDB等。
下圖展示了在復(fù)雜度和伸縮性方面背景下的主要NOSQL分類的位置。
關(guān)于“規(guī)模擴(kuò)展和復(fù)雜度擴(kuò)展的比較”的更多內(nèi)容,請(qǐng)閱讀Emil Eifrem的博文。
Neo4j -基于Java的圖形數(shù)據(jù)庫
Neo4j是一個(gè)用Java實(shí)現(xiàn)、完全兼容ACID的圖形數(shù)據(jù)庫。數(shù)據(jù)以一種針對(duì)圖形網(wǎng)絡(luò)進(jìn)行過優(yōu)化的格式保存在磁盤上。Neo4j的內(nèi)核是一種極快的圖形引擎,具有數(shù)據(jù)庫產(chǎn)品期望的所有特性,如恢復(fù)、兩階段提交、符合XA等。自2003年起,Neo4j就已經(jīng)被作為24/7的產(chǎn)品使用。該項(xiàng)目剛剛發(fā)布了1.0版 -關(guān)于伸縮性和社區(qū)測(cè)試的一個(gè)主要里程碑。通過聯(lián)機(jī)備份實(shí)現(xiàn)的高可用性和主從復(fù)制目前處于測(cè)試階段,預(yù)計(jì)在下一版本中發(fā)布。Neo4j既可作為無需任何管理開銷的內(nèi)嵌數(shù)據(jù)庫使用;也可以作為單獨(dú)的服務(wù)器使用,在這種使用場(chǎng)景下,它提供了廣泛使用的REST接口,能夠方便地集成到基于php、.NET和JavaScript的環(huán)境里。但本文的重點(diǎn)主要在于討論Neo4j的直接使用。
開發(fā)者可以通過Java-API直接與圖形模型交互,這個(gè)API暴露了非常靈活的數(shù)據(jù)結(jié)構(gòu)。至于象JRuby/Ruby、Scala、Python、Clojure等其他語言,社區(qū)也貢獻(xiàn)了優(yōu)秀的綁定庫。Neo4j的典型數(shù)據(jù)特征:
- 數(shù)據(jù)結(jié)構(gòu)不是必須的,甚至可以完全沒有,這可以簡(jiǎn)化模式變更和延遲數(shù)據(jù)遷移。
- 可以方便建模常見的復(fù)雜領(lǐng)域數(shù)據(jù)集,如CMS里的訪問控制可被建模成細(xì)粒度的訪問控制表,類對(duì)象數(shù)據(jù)庫的用例、TripleStores以及其他例子。
- 典型使用的領(lǐng)域如語義網(wǎng)和RDF、LinkedData、GIS、基因分析、社交網(wǎng)絡(luò)數(shù)據(jù)建模、深度推薦算法以及其他領(lǐng)域。
甚至“傳統(tǒng)”RDBMS應(yīng)用往往也會(huì)包含一些具有挑戰(zhàn)性、非常適合用圖來處理的數(shù)據(jù)集,如文件夾結(jié)構(gòu)、產(chǎn)品配置、產(chǎn)品組裝和分類、媒體元數(shù)據(jù)、金融領(lǐng)域的語義交易和欺詐檢測(cè)等。
圍繞內(nèi)核,Neo4j提供了一組可選的組件。其中有支持通過元模型構(gòu)造圖形結(jié)構(gòu)、SAIL -一種SparQL兼容的RDF TripleStore實(shí)現(xiàn)或一組公共圖形算法的實(shí)現(xiàn)。
要是你想將Neo4j作為單獨(dú)的服務(wù)器運(yùn)行,還可以找到REST包裝器。這非常適合使用LAMP軟件搭建的架構(gòu)。通過memcached、e-tag和基于Apache的緩存和Web層,REST甚至簡(jiǎn)化了大規(guī)模讀負(fù)荷的伸縮。
高性能?
要給出確切的性能基準(zhǔn)數(shù)據(jù)很難,因?yàn)樗鼈兏讓拥挠布⑹褂玫臄?shù)據(jù)集和其他因素關(guān)聯(lián)很大。自適應(yīng)規(guī)模的Neo4j無需任何額外的工作便可以處理包含數(shù)十億節(jié)點(diǎn)、關(guān)系和屬性的圖。它的讀性能可以很輕松地實(shí)現(xiàn)每毫秒(大約每秒1-2百萬遍歷步驟)遍歷2000關(guān)系,這完全是事務(wù)性的,每個(gè)線程都有熱緩存。使用最短路徑計(jì)算,Neo4j在處理包含數(shù)千個(gè)節(jié)點(diǎn)的小型圖時(shí),甚至比MySQL快1000倍,隨著圖規(guī)模的增加,差距也越來越大。
這其中的原因在于,在Neo4j里,圖遍歷執(zhí)行的速度是常數(shù),跟圖的規(guī)模大小無關(guān)。不象在RDBMS里常見的聯(lián)結(jié)操作那樣,這里不涉及降低性能的集合操作。Neo4j以一種延遲風(fēng)格遍歷圖-節(jié)點(diǎn)和關(guān)系只有在結(jié)果迭代器需要訪問它們的時(shí)候才會(huì)被遍歷并返回,對(duì)于大規(guī)模深度遍歷而言,這極大地提高了性能。
寫速度跟文件系統(tǒng)的查找時(shí)間和硬件有很大關(guān)系。Ext3文件系統(tǒng)和SSD磁盤是不錯(cuò)的組合,這會(huì)導(dǎo)致每秒大約100,000寫事務(wù)操作。
示例-黑客帝國(guó)
前面已經(jīng)說過,社交網(wǎng)絡(luò)只是代表了圖形數(shù)據(jù)庫應(yīng)用的冰山一角,但用它們來作為例子可以讓人很容易理解。為了闡述Neo4j的基本功能,下面這個(gè)小型圖來自黑客帝國(guó)這部電影。該圖是用Neo4j的Neoclipse產(chǎn)生的,該插件基于Eclipse RCP:
這個(gè)圖鏈接到一個(gè)已知的引用節(jié)點(diǎn)(id=0),這是為了方便的從一個(gè)已知起點(diǎn)找到條路進(jìn)入這個(gè)網(wǎng)絡(luò)。這個(gè)節(jié)點(diǎn)不是必須的,但實(shí)踐證明它非常有用。
Java的實(shí)現(xiàn)看上去大概是這個(gè)樣子:
在“target/neo”目錄創(chuàng)建一個(gè)新的圖形數(shù)據(jù)庫
EmbeddedGraphDatabase graphdb = new EmbeddedGraphDatabase("target/neo");
it知識(shí)庫:圖形數(shù)據(jù)庫、NOSQL和Neo4j,轉(zhuǎn)載需保留來源!
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。