做者| 西湖數據智能研究院高級研發工程師 無極 node
大千世界紛繁複雜,萬物之間總會有千絲萬縷的關係。隨着現代商業社會的發展,事物的關聯關係愈加錯綜複雜,傳統的關係存儲已經不能知足咱們的業務需求。「圖」做爲關係探索將來發展的風向標,能夠更爲直觀地幫助人們認知事物,挖掘數據之間的奧祕,爲數據價值的體現開闢了新天地。程序員
做爲專業的數據智能上市公司,個推在圖應用分析方面也進行了豐富的實踐。本文將講述圖的常見業務場景、Neo4j在個推的落地應用案例和優化舉措,並在此基礎上創新性地提出了個推獨有的Neo4j社區版 HA(High Availability) 方案。數據庫
著名的柯尼斯堡七橋問題拉開了圖的新篇章。1736年, 萊昂哈德·歐拉針對該問題,進行了數學抽象,用二維矩陣予以表示,奠基了圖論的基礎。網絡
圖片來源於neo4j.com數據結構
什麼是圖?運維
圖的定義指出,圖G由兩個集合構成,記做G=<V,E> 。其中V是頂點的非空有限集合,E是邊的有限集合,邊是頂點的無序對或有序對集合。爲了更好地理解圖,咱們能夠看看下面的例子。佈局
圖片來源於neo4j.compost
圖中展現了3200個機場與60000條航線。對應圖的定義,每一個機場就是 V集合,航線則是E集合。性能
圖有哪些存儲方式?大數據
• 圖的鄰接矩陣
• 圖的鄰接表
• 有向圖的十字鏈表存儲表示
• 無向圖的鄰接多重表存儲表示
圖有哪些遍歷方式?
• 深度優先遍歷(DFS)
• 廣度優先遍歷(BFS)
圖數據庫
圖數據庫(GraphDatabase) 並不是指存儲圖片的數據庫,而是指支持以圖數據結構存儲和查詢數據的數據庫。圖數據庫是一種在線數據庫管理系統,具備處理圖數據模型的建立、讀取、更新和刪除(CRUD)操做。
圖片來源於amazon.com
圖存儲
一些圖數據庫使用原生圖存儲,這類存儲是通過優化的,而且是專門爲了存儲和管理圖而設計的。並非全部圖數據庫都使用原生圖存儲,也有一些圖數據庫將圖數據序列化,而後保存到關係型數據庫、面向對象數據庫,或其餘通用數據存儲中。
圖處理引擎
原生圖處理(也稱爲無索引鄰接)因爲其鏈接的節點在數據庫中能夠物理地指向彼此,所以被認爲是處理圖數據的最有效的方法。非原生圖處理使用其餘方法來處理CRUD操做。
圖常見業務場景
圖片來源於amazon.com
上圖中展現了圖在 社交網絡、推薦系統、知識圖譜、欺詐檢測、生命科學、網絡運維等業務場景中的應用。推薦系統是圖的一個典型應用,好比當咱們想要查詢好看的影片之時,售票軟件會根據咱們常常看的類型和風格幫咱們推薦相似的電影。
圖數據庫排名
根據 DB-Engines 統計, 2020 年圖數據庫受歡迎程度排行榜清晰地代表Neo4j 已經搶佔了圖數據庫的半壁江山。
Neo4j是一個高性能的NOSQL圖形數據庫,它將結構化數據存儲在網絡上而不是表中。它是一個嵌入式的、基於磁盤的、具有徹底的事務特性的Java持久化引擎,也能夠被看做是一個高性能的圖引擎,該引擎具備成熟數據庫的全部特性。
Neo4j讓程序員工做在一個面向對象的、靈活的網絡結構下而不是嚴格、靜態的表中——但他們能夠還能享受到具有徹底的事務特性、企業級的數據庫的全部好處。
圖片來源於neo4j.com
圖中展現了Neo4j圖數據庫從存儲到分析的平臺生態。
Neo4j 社區版(4.0.6)存儲分析
圖片來源於neo4j.com
Node 存儲(15 bytes)
節點存儲文件爲 neostore.nodestore.db ,定長記錄文件,每一個記錄表明一個節點。
• inUse(1 byte)
– [x x x x,_ _ ] 1-4 表示 nextPropId的高4位
– [ _ , x x x ] 5-7 表示nextRelId的高3位
– [ _ , _ _ x ] 8 表示節點是否可用
• nextRelId (4 bytes ) : 節點關聯的第一條邊的id的低位,加上inUse中的3個bit,relId一共35個bit
• nextPropId (4 bytes):節點關聯的第一個屬性的id的低位,加上inUse中的4個bit,propId一共36個bit
• labels (5 bytes ) : 存儲label信息,前4個byte爲低位,最後一個1個byte爲高位
– [1 x x x ,_ _ ] : 第一個 bit (1)表示 內聯,2-4 表示 label 數量, 剩下的36個bit使用除法均分給每一個label,表明label的id
– [0 _ ,_ _ ] : 第一個 bit (0)表示 非內聯,則低位的36個bit表示第一個動態label記錄的id
• extra (1 byte) : [ _ , _ _ x ] 只用到最後一個bit,用來標記是否爲超級節點
邊的id長度爲35bit,即邊上限320億左右,屬性的id長度爲36bit,則屬性上限約640億。
Relationship 存儲 (34 bytes)
邊存儲文件爲 neostore.relationshipstore.db,定長記錄文件,每一個記錄表明一條邊
• inUse(1 byte)
– [x x x x,_ _ ] 1-4 表示 nextPropId的高4位
– [ _ , x x x ] 5-7 表示firstNodeId的高3位
– [ _ , _ _ x ] 8 表示節點是否可用
• firstNode(4 bytes):邊關聯的第一個節點id的低位,加上inUse中的3個bit,nodeId一共35個bit
• secondNode(4 bytes):邊關聯的第二個節點id的低位,加上relationshipType mid中的3個bit,nodeId一共35個bit
• relationshipType (4 bytes) :
– mid(2 bytes):
• [ x x x , _ , _ , _ ]:2-4表示secondNodeId的高3位
• [ _ , x x x , _ , _ ]:5-7表示first prevRelId的高3位
• [ _ , _ x , x x _ , _ _ ]:8-10表示firstNextRelId的高3位
• [ _ , _ , x x , x _ ]:11-13表示secondPrevRelId的高3位
• [ _ , _ , _ , x x x ]:14-16表示secondNextRelId的高3位
– type(2 bytes):邊類型id
• firstPrevRelId(4 bytes):第一個節點相關的前一條邊id的低位,加上relationshipType mid中的3個bit,relId一共35個bit
• firstNextRelId(4 bytes):第一個節點相關的後一條邊id的低位,加上relationshipType mid中的3個bit,relId一共35個bit
• secondPrevRelId(4 bytes):第二個節點相關的前一條邊id的低位,加上relationshipType mid中的3個bit,relId一共35個bit
• secondNextRelId(4 bytes):第二個節點相關的後一條邊id的低位,加上relationshipType mid中的3個bit,relId一共35個bit
•nextPropId (4 bytes):邊關聯的第一個屬性的id的低位,加上inUse中的4個bit,propId一共36個bit
• firstInChainMarkers(1 byte):
– [ _ , _ x _ ] :第7個bit標識是否爲第一個節點的第一條邊
– [ _ , _ _ x ] :第8個bit標識是否爲第二個節點的第一條邊
經過存儲結構咱們能夠看出,邊存儲了兩端節點的id以及兩條雙向鏈表,參考如圖:
圖片來源於neo4j.com
Neo4j大數據量讀寫優化
讀優化
當咱們遇到一個任務有不少關係的時候,若是要查詢這個任務下全部數據,則須要 match(n)掃描全部的Node,而這樣查詢效率會很是低。爲了解決這個問題,咱們仍然採用空間換時間的方式,引入了輔助 label,這樣能夠高效地抽出指定任務下的全部數據,將原來 8秒 查詢的效率優化到了 100毫秒 之內。
寫優化
Neo4j傳統的數據導入方式是要先建立Node,而後再建立Relation,接着通過 cypher(SQL) 執行計劃分析。在此過程當中,建立Node和Relation 步驟耗時少,但match 操做卻十分耗時。
爲了解決建立 Relation 的過程當中須要 match 操做而致使的耗時問題,咱們先建立 Node 與 Relation (Relation 的起點和終點與建立的Node有共同屬性 ),而後經過Node 某個特定屬性合併Node,並採用空間換時間的方案來實時寫入數據,最終將原來Node、Relation 寫入效率從 40 分鐘 縮減到了 3 分鐘 。
Tips
空間換時間與 時間換空間 是解決性能均衡問題的兩種方式,選擇時間與空間合理的平衡點能極大地提升咱們軟件的服務質量。
Neo4j社區版 HA(high availability)方案探索
通過對比分析,咱們最終選擇採用 Neo4j 圖數據庫。Neo4j企業版功能雖然較全可是價格很是昂貴,爲此咱們將目標瞄向 Neo4j社區版。而Neo4j 社區版存在不支持高可用、數據沒法備份的缺點,不利於其在業務環境下的使用,所以設計一種 HA 方案,來解決單點故障是很是有必要的。如下是 Neo4j社區版高可用的一種探索方案。
**1. Neo4j 部署master 節點與 slave 節點 ,master 可讀可寫,slave 僅可讀。
圖數據庫具備高度關聯的特性,能快速進行復雜關係數據處理,從而能夠有效幫助企業得到更深入的洞察力和更多的競爭優點。業內愈來愈多的公司開始佈局圖數據庫領域研究,研發本身的圖數據庫系統。做爲擁有海量數據沉澱的數據智能上市公司,個推在圖數據庫實踐領域不斷創新,持續打磨自身圖挖掘與分析技術的同時,也期待與業界一同碰撞更多的圖數據庫實踐。
https://db-engines.com/en/ran...
https://www.tutorialspoint.co...
https://www.6aiq.com/article/...
https://www.tony-bro.com/post...