天天看點

Graph—Elastic Stack 實戰手冊

Graph—Elastic Stack 實戰手冊
https://developer.aliyun.com/topic/download?id=1295 更多精彩内容,請下載下傳閱讀全本《Elastic Stack實戰手冊》 https://developer.aliyun.com/topic/download?id=1295 https://developer.aliyun.com/topic/es100 加入創作人行列,一起交流碰撞,參與技術圈年度盛事吧 https://developer.aliyun.com/topic/es100

創作人:楊叢聿

審稿人:朱榮鑫

圖作為一種現實中廣泛存在的結構,與我們的生活息息相關,如社交網絡、交通網絡等。如何抽象的描述這些結構,并對其進行分析,擷取潛在價值是一個普遍存在的問題。

相比于我們熟悉的關系資料庫的模組化方式,從 Graph 的角度出發,可以讓一些複雜問題和場景的處理變得簡單,如行為分析、個性化推薦、知識圖譜等。

通常來講,對于圖的研究,分為圖存儲和圖計算分析兩個場景,二者解決的問題不同,相應的技術棧也有一些差異。

圖存儲

更強調圖結構的模組化,以及解決諸如鄰居、路徑等查詢問題。

圖計算

則是從全局或子圖的角度為出發點,經過大量計算,來發現更深層次的問題,其關注的技術點,更多的是資源排程,以及各類經典圖分析算法的實作。

Elasticsearch 的 Graph 功能介于二者之間,其定位是對已有的結構化資料進行分析,從圖的角度去審視已有資料,并發現潛在價值。

圖通常是以 vertex 和 edge 的模型管理資料,Elasticsearch 也不例外,隻是差別于圖資料庫的先模組化後存儲,Elasticsearch 中 Graph 的模組化邏輯,是在查詢中動态填入的,其底層實作邏輯是基于 Elasticsearch 的 terms 和 aggregations 相關功能。

相比于圖資料庫通常隻提供基于 vertex 和 edge 的基礎查詢,Elasticsearch 由于本身在建構反向索引時會統計詞頻,這使其在查詢層面,兼具一定的分析能力。可見 Elasticsearch Graph 本身的定位并不是圖結構資料的管理(如知識圖譜),而是在已有的結構化資料中,以圖的視角來發現一些問題。如庫中已存在使用者的聽歌記錄,則可以根據聽衆偏好,為其進行歌曲的推薦。

其他圖資料庫概覽

由于 Elasticsearch 本身從邏輯上更接近圖資料庫,不管是 vertices + connections 的資料模型還是查詢模式,本節先介紹下目前主流圖資料庫的類别和實作邏輯,具體細節不進行展開。

目前主流的圖資料庫,以屬性圖和 RDF 模型為主;

RDF 相對小衆,僅有 DGraph 屬于此範疇;

屬性圖是由節點、邊、屬性三者構成的有向圖,相比于其他資料庫,其關鍵特征之一是邊(或連接配接)與頂點一同被視為模型的核心元件;

基于這些理念,一般屬性圖資料的結構可以歸納如下:

每個頂點(vertex)包括:

  • 唯一辨別符
  • 一組出邊
  • 一組入邊

一組屬性(鍵值對

每條邊(edge)包括:

邊的起點

  • 邊的終點
  • 描述兩個頂點間關系類型的标簽

一組屬性(鍵值對)

對于各類圖資料庫而言,資料模組化的核心便是如何組織這些資料,從存儲和索引的角度來看,目前主要分為自行實作和 Graph 層兩種:

自行實作存儲&索引

代表如 neo4j,其使用了免索引鄰接,即每個節點都會維護其相鄰節點的引用,免去了基于索引查找相鄰節點的開銷,這個設計理念在很多圖資料庫中都可以看到;

以 Graph 層的形式建構,使用外置 Nosql 存儲和外置索引

代表 JanusGraph、HugeGraph,對于此類圖資料庫,Elasticsearch 便可作為其索引層存在。

除此以外,如何在分布式場景下,對存儲和計算進行優化,是各類圖資料庫遇到的最大問題,針對諸如分布式場景下的分片、删除等問題,逐漸誕生了 NebulaGraph、 Dgraph 等。

Elasticsearch 的實作方式

Elasticsearch 的 Graph 功能始于 5.5 版本,屬于 X-pack 的擴充功能組,從 API 的路徑 /_graph/explore 可以看出,其定位更傾向于是探索分析,即在已有的索引上通過聚合的方式進行分析。

正常的 graph 查詢可以了解為,先進行兩層嵌套的 terms 聚合,再将查詢結果以 vertexs 和 connections 的資料模型進行傳回。

在使用 Graph 功能時,有3個核心要素,分别是 vertices、connections、controls,前兩者主要用于确定圖查詢中,前者通過哪些字段産生,後者用于控制一些查詢細節。

如希望通過點選日志探查使用者的搜尋詞和點選的産品間的關聯,可通過如下查詢

POST clicklogs/_graph/explore
{
  "query": {                  
    "match": {
      "query.raw": "midi"
    }
  },
  "vertices": [               
    {
      "field": "product"
    }
  ],
  "connections": {            
    "vertices": [
      {
        "field": "query.raw"
      }
    ]
  }
}           

查詢語句中

  • vertices 用于指定對哪些字段的内容感興趣,後續會作為 target 節點處理,對應的字段必須是已索引的字段。
  • connections 用于指定希望哪些字段和 vetices 的内容進行關聯,後續會作為 source 節點處理,connections 也支援使用 query 縮小關聯内容的範圍。

這個查詢會以聚合的方式得到最終結果,會産生類似兩層嵌套 aggs 的查詢效果

"aggs": {
    "vertices": {
      "terms": {
        "field": "product"
      },
      "aggs": {
        "connections": {
          "terms": {
            "field": "query.raw"
          }
        }
      }
    }
  }           

查詢結果會傳回 vertices 和 connections 兩個數組,通過這兩部分資料,即可構成一個有向圖(方向是由 connections 中設定的 query.raw 指向 vertices 中設定的 product)。

為了能更直覺的反映每個節點,和每條邊的重要程度,vertices 和 connections 的元素中均會額外傳回一個 weight,這點也是 Elasticsearch Graph 差別于其他圖資料庫查詢的功能點之一。

"vertices": [ 
      {
         "field": "query.raw",
         "term": "midi cable",
         "weight": 0.08745858139552132,
         "depth": 1
      },
      {
         "field": "product",
         "term": "8567446",
         "weight": 0.13247784285434397,
         "depth": 0
      }
],
"connections": [ 
      {
         "source": 0,
         "target": 1,
         "weight": 0.04802242866755111,
         "doc_count": 13
      }
]

           

除了上述例子所舉的正常查詢模式外,Elasticsearch 的 Graph API 還可以通過 controls 控制采樣規模和 weight 的計算:

use_significance(預設 false)

如設定為 true,第二層的聚合将會變為 Significant Terms,得到的 weight 會是通過前置和後置頻率算出的,可用來發現一些有趣,或不尋常的節點或關系。

sample_size(預設100)

通過減少采樣規模,可以有效提高檢索效率

除此以外,Elasticsearch 還支援通過 Kibana 配置 Graph 相關的可視化頁面,借此可以快速将上述查詢得到的結果以圖形化的方式進行展現。以下示例基于 7.10 操作:

  1. 在 Kibana 中選擇 Graph 進入導航頁面;
  2. 選取一個資料源,即庫中已存在的索引;
Graph—Elastic Stack 實戰手冊

圖1 Kibana 操作-選取資料源

  1. 添加字段并觸發查詢即可得到如下的圖結構分析頁面 (可變更顔色區分節點),上文提及的 weight 值将通過節點間連線的粗細展現。
Graph—Elastic Stack 實戰手冊

圖2 Kibana 操作-以圖的視角分析索引不同字段

總結

高可用和近實時的能力

Elasticsearch 的 Graph 功能通過 X-pack 提供,其優點是可以對庫中已有的資料,快速進行分析,且具備可視化能力。其天然具備高可用和近實時的能力。

千萬以及億級的資料進行 Graph 分析

依托于已有的反向索引和聚合功能,可以快速以 vertices 和 connections 的資料模型呈現結果。由于聚合本身需要消耗較大的記憶體和計算量,在使用時需要留意資料量級和系統資源,在資源允許的情況下,可以支援對千萬以及億級的資料進行 Graph 分析。

當然 Elasticsearch 的 Graph 也存在一定局限性,它本身定位是對已有索引進行分析,是以不适合需要模組化管理圖結構資料的場景,且無法對多跳的路徑查詢進行有效支援。

并且 Elasticsearch Graph 内部的處理邏輯,是通過對索引進行字段級的聚合,是以産生關系的上下遊節點僅限于同一索引中的不同字段。

綜上,如果你希望發現索引中不同字段的一些潛在價值,不妨使用 Elasticsearch Graph 功能來進行探索。

參考資料

  1. https://www.elastic.co/guide/en/elasticsearch/reference/master/graph-explore-api.html
  2. https://www.elastic.co/guide/en/kibana/current/graph-getting-started.html
  3. https://nebula-graph.io/posts/review-on-graph-databases/