聊聊圖數據庫和圖數據庫的小知識

圖數據庫 - 維基百科:在計算機科學中,圖數據庫(英語:graph database,GDB)是一個使用圖結構進行語義查詢數據庫,它使用節點和屬性來表示和存儲數據。該系統的關鍵概念是,它直接將存儲中的數據項,與數據節點和節點間表示關係的的集合相關聯。這些關係允許直接將存儲區中的數據鏈接在一起,並且在許多情況下,可以通過一個操作進行檢索。圖數據庫將數據之間的關係作爲優先級。查詢圖數據庫中的關係很快,因爲它們永久存儲在數據庫本身中。可以使用圖數據庫直觀地顯示關係,使其對於高度互連的數據非常有用。
圖數據庫是一種非關係型數據庫,以解決現有關係數據庫的侷限性。圖模型明確地列出了數據節點之間的依賴關係,而關係模型和其他 NoSQL 數據庫模型則通過隱式連接來鏈接數據。圖數據庫從設計上,就是可以簡單快速地檢索難以在關係系統中建模的複雜層次結構的。圖數據庫與 20 世紀 70 年代的網絡模型數據庫相似,它們都表示一般的圖,但是網絡模型數據庫在較低的抽象層次上運行,並且不能輕鬆遍歷一系列邊。
圖數據庫的底層存儲機制可能各有不同。有些依賴於關係引擎並將圖數據“存儲”到表中(雖然表是一個邏輯元素,但是這種方法在圖數據庫、圖數據庫管理系統和實際存儲數據的物理設備之間施加了另一層抽象)。另一些則使用鍵值存儲面向文檔的數據庫進行存儲,使它們具有固有的 NoSQL 結構。大多數基於非關係存儲引擎的圖數據庫還添加了標記屬性的概念,這些標記或屬性本質上是具有指向另一個文檔的指針的關係。這樣就可以對數據元素進行分類,以便於集中檢索。
從圖數據庫中檢索數據需要 SQL 之外的查詢語言,SQL是爲了處理關係系統中的數據而設計的,因此無法“優雅地”處理遍歷圖。截至 2017 年,沒有一個像 SQL 那樣通用的圖查詢語言,通常都是僅限與一個產品的。不過,已經有一些標準化的工作,使得 GremlinSPARQL 和 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 datasocial networkse-commerce 、Web 2.0讓圖計算有了新的用武之地,而且硬件計算力的提高和分佈式計算日益成熟的支持也使圖計算在高效處理海量數據成爲可能。

學習完圖數據庫發展的契機,我們來學習下圖數據庫存儲方式和一種圖數據庫存儲層的設計探討。

🆚 圖數據庫存儲方式 —— 基於內存存儲 vs 基於分佈式 kv 存儲    --@Bruceleexiaokan

Bruceleexiaokan:基於內存的圖數據庫有其優勢,特別對於 大規模深度遍歷以及基於之上的 graph model 計算,這在大規模並行處理( MPP )是有較強優勢,其訪問語言更像是編程語言而並非圖遍歷。

Sherman:各種存儲各有優缺點,各有擅長的應用場景,所以離開了場景和需求,很難對比不同的解決方案。

Bruceleexiaokan:基於分佈式 kv 之上的圖數據庫,對於大規模深度遍歷和計算,對於graph model 的支持,有其缺陷。圖數據庫需要有分類,我們需要明白討論的是哪一種。

  1. 實時在線圖數據庫,
  2. 線下圖數據庫,
  3. 大規模數學分析用圖數據庫。

如果講到第 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 的支持:

  1. degree 統計
  2. 按照 EdgeType 進行 aggregation
  3. 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 數量,和節點一塊讀和寫。但到了一些特殊場景:

  1. 如果更新非常頻繁,會造成寫放大問題
  2. 單節點邊出入度異常高,但訪問只遍歷前幾個。其性能反而會變差,屬性索引是另一個問題

Sherman:@Bruceleexiaokan 完全同意,索引的使用要看場景,過度使用索引會得不償失。

提問:Nebula 是對臨接點有索引的 對吧 

Sherman:對屬性有索引

📚 在知識圖譜場景下計算、存儲及副本一致性問題

提問:我們知識圖譜業務場景,查節點間的路徑,請問下實時計算結果的效率怎麼樣呀?還是說比較推薦離線計算?Nebula 是存儲計算分離的是吧?

Sherman:說一下個人理解,我覺得知識圖譜的場景一般是需要在線查詢的,因爲不知道會有怎麼樣的查詢問題。嗯,是的,Nebula 是存儲計算分離的,最好的好處是部署方式靈活,計算節點和存儲節點可以根據不同的需求獨立擴縮容。

提問:各副本之間是最終一致嗎?還是強一致呀?

吳敏:各副本之間是基於 Raft 協議的強一致。

圖數據庫衆測

圖數據庫 Nebula Graph Beta 版本上線,版本 捉蟲活動 正在進行歡迎來找 Bug 😁

參考資料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章