深入理解 Ganglia 之 Overview

0. 引言

Ganglia 是目前最广泛的应用是用来监控 Hadoop 相关指标,亚马逊、阿里云、Cloudera Manager 等都在使用。但是目前网络上的文档非常的少,所以打算写一系列关于 Ganglia 的文章,包括安装、使用、扩展、架构以及源码等。

1. Ganglia 简介

Ganglia 包括三个部分:gmond, gmetad, gweb。最常用的 Ganglia 架构如下图所示(数据流向从左到右)。

1
2
3
4
5
[gmond collector 1]                        [gweb]
\ /
[gmetad] --> [rrdtool]
/ \
[gmond collector 2] [disk]

1.1 gmond

gmond 可以类比成 server-agent 架构中的 agent,负责指标收集。与 agent 不同的,gmond 之间可以互相通信,我们可以将多个 gmond 的监控数据发送给一个或者几个 gmond (unicast mode,单播),也可以让所有 gmond 之间都收集其他 gmond 的监控数据(multicast mode,广播)。

集群监控的时候,每一台机器都需要运行一个 gmond 进程用来做监控数据采集。如果是 unicast 的话,会有一个或者几个 gmond 负责指标的收集和汇总。gmond 之间是通过 udp 协议来通信的,如果要设置发送指标的 gmond host,需要设置配置文件(gmond.conf) 中的 udp_send_channel。同时还要保证接收者的 udp_recv_channel 中的 port 和发送者的一致。

1.2 gmetad

gmetad 可以类比成 server-agent 架构中的 server。gmetad 通过 tcp poller 的方式从 gmond 拉取数据,然后处理成 rrd 文件格式落盘。

关于 rrd,是 Round Robin Database 的缩写,中文一般叫环状数据库。这里的 Round Robin 和负载均衡里面的是两回事。rrd 一般用来存放时间序列的数据,time-series。所谓环状就是说老数据会被新数据覆盖,而且距当前时间越久远,时间存放的粒度会越大。

rrd 文件操作,一般使用 rrdtool。关于 rrdtool 的使用可以通过 help 查看。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ rrdtool -help
RRDtool 1.4.8 Copyright 1997-2013 by Tobias Oetiker <tobi@oetiker.ch>
Compiled Nov 20 2015 19:23:48

Usage: rrdtool [options] command command_options
Valid commands: create, update, updatev, graph, graphv, dump, restore,
last, lastupdate, first, info, fetch, tune,
resize, xport, flushcached

RRDtool is distributed under the Terms of the GNU General
Public License Version 2. (www.gnu.org/copyleft/gpl.html)

For more information read the RRD manpages

1.3 gweb

gweb 也就是数据可视化,内部是 php 实现的,这个就不细说了。 监控数据可视化可以有多种解决方案,比如最近比较流行的 grafana。

2. 安装

安装可以拉源码下来自己 make install,或者直接通过包管理(apt-get 或者 yum)安装二进制文件。安装过程这里不再展开。

3. Hadoop 指标采集

Hadoop 支持将部分监控数据发送给 gmond,我们前面说到 gmond 之间数据交互使用 udp 协议,Hadoop 的指标就是自己主动发送给 gmond。对于 Hadoop 2.0 以上版本只需要修改配置文件 hadoop-metrics2.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
*.sink.file.class=org.apache.hadoop.metrics2.sink.FileSink
# default sampling period, in seconds
*.period=10

# for Ganglia 3.1 support, 3.1 以上版本
*.sink.ganglia.class=org.apache.hadoop.metrics2.sink.ganglia.GangliaSink31

*.sink.ganglia.period=10

*.sink.ganglia.supportsparse=true

*.sink.ganglia.slope=jvm.metrics.gcCount=zero,jvm.metrics.memHeapUsedM=both
*.sink.ganglia.dmax=jvm.metrics.threadsBlocked=70,jvm.metrics.memHeapUsedM=40

#filter 自己可以自由设置
*.source.filter.class=org.apache.hadoop.metrics2.filter.RegexFilter
*.record.filter.class=${*.source.filter.class}
*.metric.filter.class=${*.source.filter.class}

datanode.sink.ganglia.record.filter.exclude=UgiMetrics|MetricsSystem|rpcdetailed
nodemanager.sink.ganglia.record.filter.exclude=UgiMetrics|MetricsSystem|rpcdetailed
namenode.sink.ganglia.record.filter.exclude=UgiMetrics|MetricsSystem
resourcemanager.sink.ganglia.record.filter.exclude=UgiMetrics|MetricsSystem
mrappmaster.sink.ganglia.record.filter.exclude=UgiMetrics|MetricsSystem|rpcdetailed
jobhistoryserver.sink.ganglia.record.filter.exclude=UgiMetrics|MetricsSystem

namenode.sink.ganglia.servers=yourgangliahost_1:8649,yourgangliahost_2:8649

datanode.sink.ganglia.servers=yourgangliahost_1:8649,yourgangliahost_2:8649

resourcemanager.sink.ganglia.servers=yourgangliahost_1:8649,yourgangliahost_2:8649

nodemanager.sink.ganglia.servers=yourgangliahost_1:8649,yourgangliahost_2:8649

mrappmaster.sink.ganglia.servers=yourgangliahost_1:8649,yourgangliahost_2:8649

jobhistoryserver.sink.ganglia.servers=yourgangliahost_1:8649,yourgangliahost_2:8649

指标发送的 gmond server 配置在最后,可以使用 IP 或 host name。如果不加端口号,默认使用 8649。如果有 多个 server,可以使用逗号或者空格隔开。关于分割符,我之前使用逗号的时候只能解析出来第一个 server,最后把逗号换成空格问题解决。这个地方非常诡异,我翻了一下 Hadoop 源码对这个参数的解析,分隔符是逗号和空格都 OK 的。

4. 实践

下面我们来配置一个单播的集群,gmond 主要配置如下。

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
cluster {   // 分组
name = cluster_workers
owner = "unspecified"
latlong = "unspecified"
url = "unspecified"
}

udp_send_channel { // 发送 metrics 的目的 host, port 设置
host = host-1 // 换成你的 hostname
port = 8649
}

/* You can specify as many udp_recv_channels as you like as well. */
udp_recv_channel { // 如果是 gmond 收集点,这个需要设置
port = 8649
retry_bind = true
}

/* You can specify as many tcp_accept_channels as you like to share
an xml description of the state of the cluster */
tcp_accept_channel { // 提供了一个读取 xml 文件的 tcp 端口, gmetad 也是从这读取的数据
port = 8649
# If you want to gzip XML output
gzip_output = no
}

配置完之后重启 gmond,通过查看系统 /var/log/messages 可以查看一些 log 信息。telnet 8649 端口就能取到汇总的指标数据了。

1
2
3
4
5
6
7
8
9
10
# service gmond restart
# telnet host-1 8649
<?xml version="1.0" encoding="ISO-8859-1" standalone="yes"?>
<!DOCTYPE GANGLIA_XML [
<!ELEMENT GANGLIA_XML (GRID|CLUSTER|HOST)*>
<!ATTLIST GANGLIA_XML VERSION CDATA #REQUIRED>
<!ATTLIST GANGLIA_XML SOURCE CDATA #REQUIRED>
<!ELEMENT GRID (CLUSTER | GRID | HOSTS | METRICS)*>
<!ATTLIST GRID NAME CDATA #REQUIRED>
...

其中指标数据类似如下。

1
2
3
4
5
6
<METRIC NAME="tcp_outsegs" VAL="7.26570" TYPE="float" UNITS="count/s" TN="1" TMAX="60" DMAX="0" SLOPE="both">
<EXTRA_DATA>
<EXTRA_ELEMENT NAME="GROUP" VAL="tcp"/>
<EXTRA_ELEMENT NAME="DESC" VAL="outsegs"/>
<EXTRA_ELEMENT NAME="TITLE" VAL="TCP segments sent"/>
</EXTRA_DATA>

gmetad 配置主要是设置数据采集源。

1
2
3
data_source "cluster_workers" host-1

rrd_rootdir "/dev/shm/ganglia/rrds" # RRD 文件存放地址

配置完之后重启 gmetad,如果没有出现问题就能在 rrd_rootdir 下面看到落盘的 rrd 文件的。

Hadoop 指标的采集配置如前所述,配置完需要重启 Hadoop 相关进程:NameNode, DataNode, ResourceManager, NodeManager 等。

5. 参考:

  1. Round Robin Database Storage Engine