圖資料庫 - 維基百科:在電腦科學中,圖資料庫(英語:graph database,GDB)是一個使用圖結構進行語義查詢的資料庫,它使用節點、邊和屬性來表示和儲存資料。該系統的關鍵概念是圖,它直接將儲存中的資料項,與資料節點和節點間表示關係的邊的集合相關聯。這些關係允許直接將儲存區中的資料連結在一起,並且在許多情況下,可以通過一個操作進行檢索。圖資料庫將資料之間的關係作為優先順序。查詢圖資料庫中的關係很快,因為它們永久儲存在資料庫本身中。可以使用圖資料庫直觀地顯示關係,使其對於高度互連的資料非常有用。
圖資料庫是一種非關係型資料庫,以解決現有關聯式資料庫的侷限性。圖模型明確地列出了資料節點之間的依賴關係,而關係模型和其他 NoSQL 資料庫模型則通過隱式連線來連結資料。圖資料庫從設計上,就是可以簡單快速地檢索難以在關係系統中建模的複雜層次結構的。圖資料庫與 20 世紀 70 年代的網路模型資料庫相似,它們都表示一般的圖,但是網路模型資料庫在較低的抽象層次上執行,並且不能輕鬆遍歷一系列邊。
圖資料庫的底層儲存機制可能各有不同。有些依賴於關係引擎並將圖資料“儲存”到表中(雖然表是一個邏輯元素,但是這種方法在圖資料庫、圖資料庫管理系統和實際儲存資料的物理裝置之間施加了另一層抽象)。另一些則使用鍵值儲存或面向文件的資料庫進行儲存,使它們具有固有的 NoSQL 結構。大多數基於非關係儲存引擎的圖資料庫還新增了標記或屬性的概念,這些標記或屬性本質上是具有指向另一個文件的指標的關係。這樣就可以對資料元素進行分類,以便於集中檢索。
從圖資料庫中檢索資料需要SQL 之外的查詢語言,SQL是為了處理關係系統中的資料而設計的,因此無法“優雅地”處理遍歷圖。截至 2017 年,沒有一個像 SQL 那樣通用的圖查詢語言,通常都是僅限與一個產品的。不過,已經有一些標準化的工作,使得 Gremlin、SPARQL 和 Cypher 成為了多供應商查詢語言。除了具有查詢語言介面外,還可以通過應用程式介面(API)訪問一些圖資料庫。
圖資料庫與圖計算引擎不同。圖資料庫是轉換關係OLTP 資料庫的技術。而圖計算引擎在 OLAP 中用於批量分析。由於主要技術公司在使用專有圖資料庫方面的成功以及開源圖資料庫的引入,圖資料庫在 2000 年代引起了相當大的關注。
上面部分引用了維基百科對圖資料庫的詞條來講解何為圖資料庫,而本文整理於圖資料庫 Nebula Graph 交流群中對圖資料庫的零碎知識,作為對圖資料庫知識的補充。本文分為小知識及 Q&A 兩部分。
本文主目錄
- 小知識
- 圖資料庫興起的契機
- 圖資料庫儲存方式 —— 基於記憶體儲存 vs 基於分散式 kv 儲存
- 一種圖資料庫儲存層的設計探討
- 圖結構的視覺化與 GIS 資料的視覺化
- Q&A 提問回答
- 圖資料庫計算儲存分離設計及該設計模式的考量原因
- 怎麼理解圖資料庫頂點和標籤
- Nebula 如何處理 ID 衝突問題
- Nebula Graph 和 Tiger Graph 的區別
- 圖資料庫 0 標籤的意義
- 大家怎麼看「圖資料庫要有索引」這個問題?
- 在知識圖譜場景下計算、儲存及副本一致性問題
小知識
學習圖資料庫的起手式——瞭解圖資料庫興起的契機。
圖資料庫興起的契機 --@阿穠
2010 年前後,對於社交媒體網路研究的興起帶動了圖計算的大規模應用。
2000 年前後熱門的是 資訊檢索
和 分析
,主要是 Google 的帶動,以及 Amazon 的 e-commerce 所用的協同過濾推薦,當時 collaborative filtering也被認為是 information retrieval 的一個細分領域,包括 Google 的 PageRank 也是在資訊檢索領域研究較多。後來才是 Twitter,Facebook 的崛起帶動了網路科學 Network science的研究。
圖理論和圖演算法不是新科學,很早就有,只是最近 20 年大資料,網路零售和社交網路的發展, big data
、social networks
、e-commerce
、Web 2.0
讓圖計算有了新的用武之地,而且硬體計算力的提高和分散式計算日益成熟的支援也使圖計算在高效處理海量資料成為可能。
學習完圖資料庫發展的契機,我們來學習下圖資料庫儲存方式和一種圖資料庫儲存層的設計探討。
圖資料庫儲存方式 —— 基於記憶體儲存 vs 基於分散式 kv 儲存 --@Bruceleexiaokan
Bruceleexiaokan:基於記憶體的圖資料庫有其優勢,特別對於 大規模深度遍歷
以及基於之上的 graph model 計算
,這在大規模並行處理( MPP )是有較強優勢,其訪問語言更像是程式語言而並非圖遍歷。
Sherman:各種儲存各有優缺點,各有擅長的應用場景,所以離開了場景和需求,很難對比不同的解決方案。
Bruceleexiaokan:基於分散式 kv 之上的圖資料庫,對於大規模深度遍歷和計算,對於graph model 的支援,有其缺陷。圖資料庫需要有分類,我們需要明白討論的是哪一種。
- 實時線上圖資料庫,
- 線下圖資料庫,
- 大規模數學分析用圖資料庫。
如果講到第 3 種,圖結構基於記憶體的方案有優勢。第 1 和 2 種大規模圖資料庫主要也就是基於 kv+ 索引
一種圖資料庫儲存層的設計探討 --@Bruceleexiaokan
無中心化的儲存叢集,一般單個叢集還是有一定的大小限制,不宜過大。儲存層的抽象在於,資料集(圖的話就是不同的點和邊)到儲存叢集的邏輯對映對使用者透明,使用者可用性要求高的場景需要考慮雙叢集互為災備。單叢集的資料平衡是叢集內部的事,叢集和叢集間的資料平衡是需要設計的,其中線下到線上的資料傳輸通道尤其重要。
設計原則:
- 不要使得單叢集過大;
- 本地互為備份叢集支援讀 active-active;
- 利用線下到線上資料傳輸通道做好資料叢集間遷移、backfill、recovery,batch update 等等工作:
- 資料訪問有抽象,使得叢集的運維對於使用者訪問透明;
- 做好叢集間的跨資料中心資料複製;
- 到達即使逐步投資也能線性擴充套件的設計;
學習完儲存和設計的小知識,來對比下圖資料庫圖結構的視覺化和 GIS 資料的視覺化。
圖結構的視覺化與 GIS 資料的視覺化 --@Space
關於圖結構視覺化與 GIS 資料的視覺化本質上有比較大的差異:
GIS 是 Hierarchical + 瓦片式
貼片展示的,而圖結構本身是 flat 的,只能一次性將所有 touch 到的資料全部展示出來。但是 GIS 的做法可以給我們啟示,結合具體的業務場景,能否也做一個 層級抽樣
,但是圖抽樣的問題是:如何在抽樣的同時,儘量 保留子圖的連通性
(否則可能 high level 的層顯示的都是孤立的點,只有最後最細粒度的層才會顯示所有資料)。
一些粗淺的想法:可以結合圖計算的技術,先算連通子圖,然後在連通子圖內部算 PageRank,按照 PageRank 大小劃分成不同的區間,相當於按照 PageRank 值做 Hierarchical 分層,在層次切換時,為了保證圖的連通性,除了顯示下一個層次的頂點(PageRank 值在下一個區間)之外,還需要顯示這 2 個層次抽樣出來的頂點的邊(這相當於一個子圖內部的連通路徑的檢索,如果能做 aggreate 更好,如果這些邊很多,是否可以按照 EdgeType aggregate,先顯示統計值,如果使用者有興趣再展開——即圖資料庫返回 aggregation 值,前端生成”虛擬”的邊,隨著進一步展開,這些”虛擬的邊”會被實際明細邊取代)。
上述 trick 只是為了解決圖資料像 GIS 一樣平滑展示的問題,缺點也比較明顯,Hierarchical 抽樣代價高。
另外,圖資料的展示問題,不是一個獨立的前端技術問題,還涉及到後端圖資料庫如下 feature 的支援:
- degree 統計
- 按照 EdgeType 進行 aggregation
- query 時遇到超級頂點做截斷,並返回截斷資訊給 client
內建一些 AP 性演算法,如 PageRank、lpa、環探測等。
圖資料視覺化,還需要考慮:
前端資料承載量是有限的,CS 型別的視覺化工具還好點,BS 型別的視覺化工具,瀏覽器承載的量就更少。如何在業務上將 touch 到的資料量限制在一定範圍內是應用是要考慮的。
此外,由於頂點和邊的 name 和其他 tag 資訊,一般在視覺化的時候不會一次性都顯示在圖上,首次繪製可僅向圖資料庫請求 name,後續 tag 的 properties 在使用者感興趣的時候(點選/hover)時再次請求。
佈局問題:目前常見的無非是力導引、圓形、樹形、網格型,這些都是無任何業務語義的佈局,如樹形佈局,哪些應該作為頂層節點,哪些是下一級節點,如果僅僅通過邊的有向性,單個 EdgeType 顯示還好,多個 EdgeType 混合在一棵樹上顯示的時候會破壞掉單個 EdgeType 樹的結構,必須引入業務規則來限制不同佈局下的問題
Q&A 提問回答
由於 Q&A 整理於 Nebula Graph 交流群,有多人蔘與討論,所以以下問題回覆中會有群友暱稱出現,不做 Nebula Graph 官方成員和群友身份區分,僅交流圖資料庫技術~如果你對下列問題有不同的看法歡迎本文評論區交流(≧▽≦),加入圖資料庫交流群請加 WeChat:NebulaGraphbot
圖資料庫計算儲存分離設計及該設計模式的考量原因
提問:計算儲存分離的話,資料遷移,請問下大佬們,網路頻寬會是瓶頸嗎?Nebula 怎麼解決的呀?
恆子:現在都萬兆網路卡了,一般機房內很難把頻寬打滿的,通常 IO 會先是瓶頸。
波娃子:如果是地理分散式的圖資料庫,頻寬是要考慮的效能限制因素。
Sherman:是的,現在比較流行的做法是兩地三中心或者三地五中心。分散式圖資料庫,既有圖的部分,也必然會涉及到分佈系統的部分
Bruceleexiaokan:由於大規模線上圖資料庫都設計成計算和儲存分離,資料儲存的設計是尤為重要。就金融 Risk 而言,邏輯上其實就是一張大圖,有上百 TB 的資料量,可線性擴充套件的儲存層設計是圖資料庫的關鍵
提問:為什麼都設計成計算儲存分離的模式,有什麼重要的考量嗎
Bruceleexiaokan:對於 Risk 而言,線上是 inference 為主,大部分場景是為了 feature 計算,基本在 2-3 跳以內的圖遍歷,都很簡單,但是對於效能和可用性的要求很高,所以線上圖資料庫儲存分離很合理。但針對資料分析的圖資料庫,其設計會不一樣,更需要的是圖的深度遍歷能力,因此儲存分離應該是個問題,但如何支援大規模的圖,如何 scale up 應該是關鍵,而不是 scale out。
天師:儲存計算分離大多是適應雲端計算架構:儲存層買空間,計算層買彈性虛機。
吳敏:長期看,計算、儲存和網路幾個硬體模組發展的速度是不太一樣的,並不都是摩爾定理的速度,分離能更合適長期硬體演進
Sherman:我覺得儲存計算分離的一個很大的好處是儲存叢集和計算叢集可以獨立擴縮容,可以通過對不同叢集容量的調整,最終達到能夠滿足業務需求的最佳搭配。
怎麼理解圖資料庫頂點和標籤
提問:怎麼理解 Vertex 和 Tag 之間的關係,Schema 裡面有沒有 Vertex 的概念?一個頂點 ID 可以對應多個 Tag 是這個意思嗎?
Sherman:解釋一下 Vertex,Tag,Edge 以及他們之間的關係:
Vertex 是一個頂點,用一個 64 位的 ID 來標識,一個 Vertex 可以被打上多個 Tag(標籤),每個 Tag 定義了一組屬性。
舉個例子,我們可以有 Person 和 Developer 這兩個 Tag,Person 這個 Tag 裡定義了姓名、電話、住址等等資訊,Developer 這個 Tag 裡可能定義了熟悉的程式語言、工作年限、GitHub 賬號等等資訊。一個 Vertex 可以被打上 Person 這個 Tag,這就表示這個 Vertex 代表了一個 Person,同時也包含了 Person 裡的屬性。另一個 Vertex 可能被同時打上了 Person 和 Developer 這兩個 Tag,那就表示這個 Vertex 不僅是一個 Person,還是一個 Developer。
Sherman:Vertex 和 Vertex 之間可以用 Edge 相連,每一條 Edge 都會有型別,比如是好友關係。每個 Edge Type 也可以定義一組屬性。Edge 一般用來表示一種關係,或者一個動作。比如,Peraon A 給 Person B 轉了一筆錢,那 A 和 B 之間就會有一條 transfer 型別的邊,transfer 這個邊型別(Edge Type)可以定義一組屬性,比如轉賬金額,轉賬時間等等。
Sherman:任何兩個 Vertex 之間可以有多種型別的邊,也可以有多條同種型別的邊,比如轉賬,兩個 Person 之間可以有多筆轉賬,那麼每筆轉賬就是一條邊。
提問:對於例子有一個小小疑問,這裡的 Tag 可以理解為本體 ontology 嗎?
Sherman:按我的理解,ontology 應該是整張知識圖譜,也就是說包含 Vertex 和 Edge。在 Nebula 裡,Vertex 本身不含內容(也就是說沒有屬性),內容是存放在 Tag 裡的,這裡“內容”指的是 ontology 裡的concept,“邊”就是 ontology 裡的 relationship。
提問:追加個問題: 多個標籤是否支援層級關係,比如組織架構什麼的?謝謝?
在 Nebula 裡,可以定義標籤之間的依賴關係,比如上面的例子裡,Developer 依賴 Person。
Nebula 如何處理 ID 衝突問題
提問:如果要構建一個網路,使用者,商家,公眾號,文章,這些 ID 會重複衝突的。根據現在 vertex id就可以唯一指代點的原則,原有的 ID 不能直接使用,有什麼辦法構建出這個網路嗎?還是把 ID 作為Tag屬性,然後建索引。
吳敏:型別和原始 ID 拼在一起 hash,作為 VID,然後把原始 ID 作為一個 property。
Sherman:由於業務千變萬化,所以當初我們決定把如何產生 VID 交個業務來決定。VID 是一個 64 位整數,在你的 case 裡,如果 ID 不足 64 位,那就可以用 2-4 bit 來表示不同的型別,這樣就把原來可能衝突的 ID 分到了不同的空間。如果原來的 ID 已經是 64 bit 的了,那可以像@吳敏 說的那樣做 hash,把真實 ID 儲存在屬性裡
Nebula Graph 和 Tiger Graph 的區別
提問:大佬們,我們想了解下 Nebula Graph 和 Tiger Graph有關係,二者有什麼區別麼
Sherman:簡單的講,Tiger Graph 不是真正意義上的對等分散式,它是有中心節點的分散式,它分佈儲存的是點和邊上的屬性,但是整張圖的關係必須儲存在一臺機器上。同時在執行的時候,整張圖必須載入到記憶體裡,這就限制了它能處理的圖的規模。而一個產品的架構一旦建立之後,要改動不是一件容易的事情,基本相當於重做。
J.GUARDIAN:簡單理解的話,Tiger Graph 為了效能犧牲了圖規模的處理能力,而 Nebula 解決的圖規模的能力,但是相對會稍微犧牲一些效能。
Sherman:也不完全是,當然這是我之前對 Tiger Graph 的瞭解。
✏️ 圖資料庫 0 標籤的意義
提問: 我看我們的文件裡寫著“一個頂點必須至少有一個型別的標籤”,但是我注意到 Neo4j 是支援 0 個標籤的,請問沒有標籤的節點在查詢時跟普通標籤用法一樣麼,為什麼要支援 0 個標籤呢?這樣做有什麼意義呢?
Sherman:多數的圖計算效能評測的資料集(如 Graph500、Twitter)都是 0 標籤,也就是無屬性過濾條件。這樣能看出一個圖引擎的最核心的效能。通過標籤過濾在大多數情況下對圖進行動態剪枝,時耗進而兒會縮短。
大家怎麼看「圖資料庫要有索引」這個問題?
提問:大家怎麼看「圖資料庫要有索引」這個問題?
Bruceleexiaokan:最終這是一個設計上的trade off
問題,不同資料分佈和不同訪問需求對於不同的設計方案,效能肯定是不同的。最好的方案是設計儲存訪問抽象,保留設計和實現靈活性,針對不同場景可以有不同優化。
相鄰邊的索引和節點 inline 儲存本是一種優化,可以減少物理磁碟 block read 數量,和節點一塊讀和寫。但到了一些特殊場景:
-
如果更新非常頻繁,會造成寫放大問題
-
單節點邊出入度異常高,但訪問只遍歷前幾個。其效能反而會變差,屬性索引是另一個問題
Sherman:@Bruceleexiaokan 完全同意,索引的使用要看場景,過度使用索引會得不償失。
提問:Nebula 是對臨接點有索引的 對吧
Sherman:對屬性有索引
在知識圖譜場景下計算、儲存及副本一致性問題
提問:我們知識圖譜業務場景,查節點間的路徑,請問下實時計算結果的效率怎麼樣呀?還是說比較推薦離線計算?Nebula 是儲存計算分離的是吧?
Sherman:說一下個人理解,我覺得知識圖譜的場景一般是需要線上查詢的,因為不知道會有怎麼樣的查詢問題。嗯,是的,Nebula 是儲存計算分離的,最好的好處是部署方式靈活,計算節點和儲存節點可以根據不同的需求獨立擴縮容。
提問:各副本之間是最終一致嗎?還是強一致呀?
吳敏:各副本之間是基於 Raft 協議的強一致。
圖資料庫眾測
圖資料庫 Nebula Graph Beta 版本上線,版本 捉蟲活動 正在進行歡迎來找 Bug ?