圖解JanusGraph系列 - JanusGraph指標監控報警(Monitoring JanusGraph)

洋仔聊程式設計發表於2020-12-23

大家好,我是洋仔,JanusGraph圖解系列文章,實時更新~

圖資料庫文章總目錄:

原始碼分析相關可檢視github碼文不易,求個star~): https://github.com/YYDreamer/janusgraph

轉載文章請保留以下宣告:

作者:洋仔聊程式設計、微信公眾號:匠心Java、原文地址:https://liyangyang.blog.csdn.net/

正文

JanusGraph框架提供了一些可監控的指標,用於我們在使用janus圖資料庫時可以對一些指標進行監控,下面我們看下如何配置使用Janusgraph監控!

本文主要講解了3部分:

  1. 監控的指標型別和配置
  2. 監控指標資料展示儲存的位置(Reporter)
  3. 實戰應用案例,並對列印出的指標進行了分析
  4. 最後給出一個監控設計的架構圖

一:監控的底層實現

JanusGraph通過支援Metrics來實現指標資料收集,什麼是Metrics?

Metrics是框架Dropwizard提供的一個lib包,主要用於專案指標的收集作用,JanusGraph就是基於Metrics這個元件開發的指標收集模組;

Dropwizard是一個Java框架,用於開發對操作友好的高效能RESTful Web服務,將來自Java生態系統的穩定,成熟的庫彙集到一個簡單的程式包中,使我們可以專注於完成工作。

Dropwizard對複雜的配置,應用程式指標,日誌記錄,操作工具等提供了開箱即用的支援;

二:JanusGraph中的指標

JanusGraph可以收集以下指標:

  • begin,commit和 roll back的事務數
  • 每種儲存後端操作型別的 請求次數 和 失敗次數
  • 每種儲存後端操作型別的響應時間分佈

2.1 配置指標收集

要啟用指標標準收集,需要在JanusGraph的屬性檔案中設定以下內容:

# Required to enable Metrics in JanusGraph
metrics.enabled = true

此設定使JanusGraph在執行時使用計時器、計數器、直方圖等Metrics類記錄測量結果。

自定義預設指標名稱

預設情況下,JanusGraph為所有度量標準名稱新增“ org.janusgraph”字首。可以通過metrics.prefix配置屬性設定此字首。例如,將預設的“ org.janusgraph”字首縮短為“ janusgraph”:

# Optional
metrics.prefix = janusgraph

特定事務指標名稱

每個JanusGraph事務都可以選擇指定其自己的指標名稱字首,從而覆蓋預設的指標名稱字首和 metrics.prefix配置屬性。例如,可以將字首更改為開啟JanusGraph事務的前端應用程式的名稱。

請注意,Metrics在記憶體中維護度量標準名稱及其相關物件的ConcurrentHashMap,因此,保持不同度量標準字首的數量較小可能是個好主意。

下面使用案例:

JanusGraph graph = ...;  // 獲取圖例項連線
TransactionBuilder tbuilder = graph.buildTransaction(); // 開啟一個事務構建器
JanusGraphTransaction tx = tbuilder.groupName("foobar").start(); // 開啟一個事務,並開啟指標收集,Metrics字首為foobar

下面為groupName的方法定義:

 * Sets the name prefix used for Metrics recorded by this transaction. If
 * metrics is enabled via {@link GraphDatabaseConfiguration#BASIC_METRICS},
 * this string will be prepended to all JanusGraph metric names.
 *
 * @param name Metric name prefix for this transaction
 * @return Object containing transaction prefix name property
 */
TransactionBuilder groupName(String name);

分開指標統計

JanusGraph在預設情況下組合了其各種內部儲存後端控制程式碼的指標,也就是說:會將所有的操作統一收集為一種型別指標;

儲存後端互動的所有指標標準都遵循“ <prefix> .stores.<opname>”模式,無論它們是否是idStore,edgeStore的操作等;

如果想要分開每種操作型別收集的指標,配置以下引數:

metrics.merge-basic-metrics = false

metrics.merge-basic-metrics = false在JanusGraph的屬性檔案中進行設定時,指標標準名稱“stores”將被替換為對應“ idStore”,“ edgeStore”,“ vertexIndexStore”或“ edgeIndexStore”,如下述:

 <prefix>.idStore.<opname>
 <prefix>.edgeStore.<opname>
 <prefix>.vertexIndexStore.<opname>
 <prefix>.edgeIndexStore.<opname> 

2.2 配置指標報告

要訪問這些收集好的指標值,必須配置一個或多個Metrics的Reporting; 也就是說配置一個或多個指標的輸出儲存的位置;

JanusGraph 支援下述的這7種 Metrics reporters:

  • Console
  • CSV
  • Ganglia
  • Graphite
  • JMX
  • Slf4j
  • User-provided/Custom

每種reporter型別獨立於其他reporter,並且可以共存。

例如,可以將Ganglia、JMX和Slf4j Metrics報告器配置為同時執行,只需在janusgraph.properties中設定它們各自的配置鍵即可(並啟用metrics.enabled = true

Console Reporter

配置鍵 是否必須? 預設
metrics.console.interval 將指標轉儲到控制檯之間需要等待的毫秒數 空值

示例janusgraph.properties片段,每分鐘將指標輸出到控制檯一次:

metrics.enabled = true
# Required; specify logging interval in milliseconds
metrics.console.interval = 60000

CSV檔案 Reporter

配置鍵 是否必須? 預設
metrics.csv.interval 寫入CSV行之間需要等待的毫秒數 空值
metrics.csv.directory 寫入CSV檔案的目錄(如果不存在則將建立) 空值

示例janusgraph.properties片段,每分鐘將CSV檔案寫入一次到目錄./foo/bar/(相對於程式的工作目錄):

metrics.enabled = true
# Required; specify logging interval in milliseconds
metrics.csv.interval = 60000
metrics.csv.directory = foo/bar

Ganglia Reporter

注意

由於Ganglia的LGPL許可與JanusGraph的Apache 2.0許可衝突,因此配置Ganglia需要一個附加的庫,該庫未與JanusGraph一起打包。要使用Ganglia監視執行,請org.acplt:oncrpc此處下載 jar 並將其複製到JanusGraph/lib目錄,然後再啟動伺服器。

配置鍵 是否必須? 預設
metrics.ganglia.hostname 將指標傳送到的單播主機或多播組 空值
metrics.ganglia.interval 傳送資料包之間等待的毫秒數 空值
metrics.ganglia.port 我們向其傳送指標資料包的UDP埠 8649
metrics.ganglia.addressing-mode 必須為“unicast”或“multicast” unicast
metrics.ganglia.ttl 組播資料包TTL; 忽略單播 1個
metrics.ganglia.protocol-31 布林值 使用Ganglia協議3.1為true,使用3.0為false true
metrics.ganglia.uuid 要報告而不是IP:主機名的主機UUID 空值
metrics.ganglia.spoof 覆蓋IP:向Ganglia報告的主機名 空值

示例janusgraph.properties片段,每30秒傳送一次單播UDP資料包到預設埠上的localhost:

metrics.enabled = true
# Required; IP or hostname string
metrics.ganglia.hostname = 127.0.0.1
# Required; specify logging interval in milliseconds
metrics.ganglia.interval = 30000

示例janusgraph.properties片段,將單播UDP資料包傳送到非預設目標埠,並且還配置報告給Ganglia的IP和主機名:

metrics.enabled = true
# Required; IP or hostname string
metrics.ganglia.hostname = 1.2.3.4
# Required; specify logging interval in milliseconds
metrics.ganglia.interval = 60000
# Optional
metrics.ganglia.port = 6789
metrics.ganglia.spoof = 10.0.0.1:zombo.com

Graphite Reporter

配置鍵 是否必須? 預設
metrics.graphite.hostname 將Graphite純文字協議資料傳送到的IP地址或主機名 空值
metrics.graphite.interval 將資料推送到Graphite之間需要等待的毫秒數 空值
metrics.graphite.port Graphite純文字協議報告傳送到的埠 2003
metrics.graphite.prefix 傳送到Graphite的所有度量標準名稱前都帶有任意字串 空值

每分鐘將指標傳送到192.168.0.1上的Graphite伺服器的示例janusgraph.properties片段:

metrics.enabled = true
# Required; IP or hostname string
metrics.graphite.hostname = 192.168.0.1
# Required; specify logging interval in milliseconds
metrics.graphite.interval = 60000

JMX Reporter

配置鍵 是否必須? 預設
metrics.jmx.enabled 布林型 false
metrics.jmx.domain 指標將顯示在此JMX域中 Metrics’s own default
metrics.jmx.agentid 指標將使用此JMX代理ID報告 Metrics’s own default

janusgraph.properties示例片段:

metrics.enabled = true
# Required
metrics.jmx.enabled = true
# Optional; if omitted, then Metrics uses its default values
metrics.jmx.domain = foo
metrics.jmx.agentid = baz

Slf4j Reporter

配置鍵 是否必須? 預設
metrics.slf4j.interval 將指標轉儲到記錄器之間需要等待的毫秒數 空值
metrics.slf4j.logger 要使用的Slf4j記錄器名稱 "metrics"

示例janusgraph.properties片段每分鐘將一次指標記錄到名為的記錄器中foo

metrics.enabled = true
# Required; specify logging interval in milliseconds
metrics.slf4j.interval = 60000
# Optional; uses Metrics default when unset
metrics.slf4j.logger = foo

使用者自定義 Reporter

如果上面列出的Metrics報告程式配置選項不足以支援我們當前的業務,JanusGraph提供了一個實用方法來訪問單個MetricRegistry例項,該例項儲存了它的所有度量;

使用方法如下:

com.codahale.metrics.MetricRegistry janusgraphRegistry = 
    org.janusgraph.util.stats.MetricManager.INSTANCE.getRegistry();

以這種方式訪問janusgraphRegistry的程式碼可以將非標準報告型別或具有外來配置的標準報告型別附加到janusgraphRegistry。

如果周圍的應用程式已經有了度量報告器配置的框架,或者如果應用程式需要JanusGraph支援的報告器型別的多個不同配置的例項,這種方法也很有用。

例如,可以使用這種方法來設定多個Graphite Reporter,而JanusGraph的屬性配置僅限於一個Graphite Reporter。

三:實際應用

配置如下:

  1. 開啟指標收集
  2. 使用Console Reporter,配置指標列印在Console中,時間間隔為1分鐘
  3. 關閉指標收集merge操作
  4. 配置指標收集字首由預設的org.janusgraph修改為myprefix

完整具體檔案配置如下:

# 其他配置
gremlin.graph=org.janusgraph.core.JanusGraphFactory

storage.backend=hbase
storage.hostname=127.0.0.1
storage.port=2184
storage.hbase.table=testGraph

cache.db-cache=true
cache.db-cache-clean-wait=20
cache.db-cache-time=180000
cache.db-cache-size=0.5

index.search.backend=elasticsearch
index.search.hostname=127.0.0.1
index.search.index-name=search
index.search.port=9200
index.search.elasticsearch.http.auth.type=basic
index.search.elasticsearch.http.auth.basic.username=test
index.search.elasticsearch.http.auth.basic.password=test
query.batch=true
query.batch-property-prefetch=true

# janusgraph監控相關配置
metrics.enabled = true
metrics.prefix = myprefix
metrics.console.interval = 60000
metrics.merge-basic-metrics = false

我們在伺服器使用gremlin.sh指令碼啟動gremlin console,並建立圖例項:

./gremlin.sh

graph=JanusGraphFactory.open('/opt/soft/janusgraph-0.5.1-test/conf/janusgraph-hbase-es.properties')

我們就會發現,每隔一分鐘就會在控制檯列印出對應指標資訊,因為指標資訊很多,為了便於文章閱讀,下述只展示出主要部分:

12/23/20 10:37:28 AM ===========================================================

-- Counters --------------------------------------------------------------------
global.storeManager.openDatabase.calls
             count = 20
global.storeManager.startTransaction.calls
             count = 461
myprefix.caches.misses
             count = 5
// 此處省略部分統計
myprefix.tx.begin
             count = 12
myprefix.tx.commit
             count = 3
myprefix.tx.rollback
             count = 9
org.janusgraph.caches.misses
             count = 3
org.janusgraph.caches.retrievals
             count = 3
// 此處省略部分統計
org.janusgraph.sys.stores.getSlice.calls
             count = 286
org.janusgraph.sys.stores.getSlice.entries-returned
             count = 231
org.janusgraph.sys.stores.mutate.calls
             count = 7
org.janusgraph.tx.begin
             count = 1

-- Histograms ------------------------------------------------------------------
myprefix.stores.getSlice.entries-histogram
             count = 7
               min = 0
               max = 8
              mean = 1.57
            stddev = 2.88
            median = 1.00
              75% <= 1.00
              95% <= 8.00
              98% <= 8.00
              99% <= 8.00
            99.9% <= 8.00
org.janusgraph.stores.getSlice.entries-histogram // 具體指標統計省略
org.janusgraph.sys.schema.stores.getSlice.entries-histogram // 具體指標統計省略
org.janusgraph.sys.stores.getSlice.entries-histogram // 具體指標統計省略


-- Timers ----------------------------------------------------------------------
myprefix.query.graph.execute.time
             count = 2
         mean rate = 0.01 calls/second
     1-minute rate = 0.01 calls/second
     5-minute rate = 0.07 calls/second
    15-minute rate = 0.14 calls/second
               min = 1.19 milliseconds
               max = 2.25 milliseconds
              mean = 1.72 milliseconds
            stddev = 0.75 milliseconds
            median = 1.72 milliseconds
              75% <= 2.25 milliseconds
              95% <= 2.25 milliseconds
              98% <= 2.25 milliseconds
              99% <= 2.25 milliseconds
            99.9% <= 2.25 milliseconds
myprefix.query.graph.getNew.time // 具體指標統計省略
myprefix.query.graph.hasDeletions.time // 具體指標統計省略
myprefix.query.vertex.execute.time // 具體指標統計省略
myprefix.query.vertex.getNew.time // 具體指標統計省略
myprefix.query.vertex.hasDeletions.time // 具體指標統計省略
myprefix.storeManager.mutate.time // 具體指標統計省略
myprefix.stores.getSlice.time // 具體指標統計省略
myprefix.stores.mutate.time // 具體指標統計省略

org.janusgraph.query.graph.execute.time
             count = 2
         mean rate = 0.00 calls/second
     1-minute rate = 0.00 calls/second
     5-minute rate = 0.02 calls/second
    15-minute rate = 0.09 calls/second
               min = 2.52 milliseconds
               max = 221.12 milliseconds
              mean = 111.82 milliseconds
            stddev = 154.57 milliseconds
            median = 111.82 milliseconds
              75% <= 221.12 milliseconds
              95% <= 221.12 milliseconds
              98% <= 221.12 milliseconds
              99% <= 221.12 milliseconds
            99.9% <= 221.12 milliseconds
org.janusgraph.query.graph.getNew.time // 具體指標統計省略
org.janusgraph.query.graph.hasDeletions.time // 具體指標統計省略
org.janusgraph.stores.getKeys.iterator.hasNext.time // 具體指標統計省略
org.janusgraph.stores.getKeys.iterator.next.time // 具體指標統計省略
org.janusgraph.stores.getKeys.time // 具體指標統計省略 // 具體指標統計省略
org.janusgraph.stores.getSlice.time // 具體指標統計省略
org.janusgraph.sys.schema.query.graph.execute.time // 具體指標統計省略
org.janusgraph.sys.schema.query.graph.getNew.time // 具體指標統計省略
org.janusgraph.sys.schema.query.graph.hasDeletions.time // 具體指標統計省略
org.janusgraph.sys.schema.stores.getSlice.time // 具體指標統計省略
org.janusgraph.sys.storeManager.mutate.time // 具體指標統計省略
org.janusgraph.sys.stores.getSlice.time // 具體指標統計省略
org.janusgraph.sys.stores.mutate.time // 具體指標統計省略

觀察上述指標統計資料,我們可以發現,主要分為4大部分:

  1. 當前統計指標時間,年月日,時間精確到秒
  2. 統計所有不同操作的數量Counters
  3. 統計資料直方圖的表示Histograms
  4. 統計所有操作的執行時間Timers

第一部分:當前統計指標時間,年月日,時間精確到秒

可以作為janusgraph指標監控的橫向維度和時間維度

第二部分:統計所有不同操作的數量Counters

這一部分主要用於收集所有操作的總數量,包含事務相關統計、快取命中相關統計、資料的CURD統計、後端儲存不同操作呼叫統計等48個維度!

具體可以自行嘗試;

第三部分:統計資料直方圖的表示Histograms

首先,什麼是直方圖? 直方圖,形狀類似柱狀圖卻有著與柱狀圖完全不同的含義。直方圖牽涉統計學的概念,首先要對資料進行分組,然後統計每個分組內資料元的數量。 在平面直角座標系中,橫軸標出每個組的端點,縱軸表示頻數,每個矩形的高代表對應的頻數,稱這樣的統計圖為頻數分佈直方圖

此部分主要涉及對後端儲存的統計;

第四部分:統計所有操作的執行時間Timers

這一部分主要收集統計資料CURD操作和資料插入等操作的時間統計包含23種維度!

時間維度包含平均值最大值最小值時間分佈14個時間維度;

四:監控架構圖

整體分為: 收集指標 --> 解析指標資料 --> 格式化儲存 --> 監控元件|報警元件

有任何問題,歡迎交流溝通

參考:JanusGraph官網

相關文章