图解JanusGraph系列-JanusGraph指标监控报警(Monitoring JanusGraph)

本文详细介绍JanusGraph的监控机制;
大家好,我是洋仔,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的属性文件中设置以下内容:

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

此设置使JanusGraph在运行时使用计时器、计数器、直方图等Metrics类记录测量结果。

自定义默认指标名称

默认情况下,JanusGraph为所有度量标准名称添加“ org.janusgraph”前缀。可以通过metrics.prefix配置属性设置此前缀。例如,将默认的“ org.janusgraph”前缀缩短为“ janusgraph”:

1
2
# Optional
metrics.prefix = janusgraph

特定事务指标名称

每个JanusGraph事务都可以选择指定其自己的指标名称前缀,从而覆盖默认的指标名称前缀和 metrics.prefix配置属性。例如,可以将前缀更改为打开JanusGraph事务的前端应用程序的名称。

请注意,Metrics在内存中维护度量标准名称及其相关对象的ConcurrentHashMap,因此,保持不同度量标准前缀的数量较小可能是个好主意。

下面使用案例:

1
2
3
JanusGraph graph = ...;  // 获取图实例连接
TransactionBuilder tbuilder = graph.buildTransaction(); // 开启一个事务构建器
JanusGraphTransaction tx = tbuilder.groupName("foobar").start(); // 开启一个事务,并开启指标收集,Metrics前缀为foobar

下面为groupName的方法定义:

1
2
3
4
5
6
7
8
 * 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的操作等;

如果想要分开每种操作类型收集的指标,配置以下参数:

1
metrics.merge-basic-metrics = false

metrics.merge-basic-metrics = false在JanusGraph的属性文件中进行设置时,指标标准名称“stores”将被替换为对应“ idStore”,“ edgeStore”,“ vertexIndexStore”或“ edgeIndexStore”,如下述:

1
2
3
4
<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片段,每分钟将指标输出到控制台一次:

1
2
3
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/(相对于进程的工作目录):

1
2
3
4
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为falsetrue
metrics.ganglia.uuid要报告而不是IP:主机名的主机UUID空值
metrics.ganglia.spoof覆盖IP:向Ganglia报告的主机名空值

示例janusgraph.properties片段,每30秒发送一次单播UDP数据报到默认端口上的localhost:

1
2
3
4
5
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和主机名:

1
2
3
4
5
6
7
8
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.portGraphite纯文本协议报告发送到的端口2003
metrics.graphite.prefix发送到Graphite的所有度量标准名称前都带有任意字符串空值

每分钟将指标发送到192.168.0.1上的Graphite服务器的示例janusgraph.properties片段:

1
2
3
4
5
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示例片段:

1
2
3
4
5
6
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

1
2
3
4
5
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实例,该实例保存了它的所有度量;

使用方法如下:

1
2
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

完整具体文件配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 其他配置
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,并创建图实例:

1
2
3
./gremlin.sh

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

我们就会发现,每隔一分钟就会在控制台打印出对应指标信息,因为指标信息很多,为了便于文章阅读,下述只展示出主要部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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监控架构图

整体分为: 收集指标 –> 解析指标数据 –> 格式化存储 –> 监控组件|报警组件

有任何问题,欢迎交流沟通

参考:JanusGraph官网

图解JanusGraph系列-JanusGraph指标监控报警(Monitoring JanusGraph)

http://coderstudy.vip/article/图解JanusGraph系列-JanusGraph指标监控报警(Monitoring_JanusGraph).html

作者

洋仔

发布于

2021-03-03

更新于

2021-03-03

许可协议