Winse Blog

走走停停都是风景, 熙熙攘攘都向最好, 忙忙碌碌都为明朝, 何畏之.

Hadoop内存环境变量和参数

问题:

https://www.zhihu.com/question/25498407

问题是hadoop内存的配置,涉及两个方面:

  • namenode/datanode/resourcemanager/nodemanager的HEAPSIZE环境变量
  • 在配置文件/Configuration中影响MR运行的变量

尽管搞hadoop有好一阵子了,对这些变量有个大概的了解,但没有真正的去弄懂他们的区别。乘着这个机会好好的整整(其实就是下载源码然后全文查找V^)。

HEAPSIZE环境变量

hadoop-env.sh配置文件hdfs和yarn脚本都会加载。hdfs是一脉相承使用 HADOOP_HEAPSIZE ,而yarn使用新的环境变量 YARN_HEAPSIZE

hadoop/hdfs/yarn命令最终会把HEAPSIZE的参数转换了 JAVA_HEAP_MAX,把它作为启动参数传递给Java。

  • hadoop

hadoop命令是把 HADOOP_HEAPSIZE 转换为 JAVA_HEAP_MAX ,调用路径:

hadoop -> hadoop-config.sh -> hadoop-env.sh

1
2
3
4
5
6
7
8
JAVA_HEAP_MAX=-Xmx1000m 

# check envvars which might override default args
if [ "$HADOOP_HEAPSIZE" != "" ]; then
  #echo "run with heapsize $HADOOP_HEAPSIZE"
  JAVA_HEAP_MAX="-Xmx""$HADOOP_HEAPSIZE""m"
  #echo $JAVA_HEAP_MAX
fi
  • hdfs

hdfs其实就是从hadoop脚本里面分离出来的。调用路径:

hdfs -> hdfs-config.sh -> hadoop-config.sh -> hadoop-env.sh

  • yarn

yarn也调用了hadoop-env.sh,但是设置内存的参数变成了 YARN_HEAPSIZE 。调用路径:

yarn -> yarn-config.sh -> hadoop-config.sh -> hadoop-env.sh

1
2
3
4
5
6
7
8
9
10
JAVA_HEAP_MAX=-Xmx1000m 

# For setting YARN specific HEAP sizes please use this
# Parameter and set appropriately
# YARN_HEAPSIZE=1000

# check envvars which might override default args
if [ "$YARN_HEAPSIZE" != "" ]; then
  JAVA_HEAP_MAX="-Xmx""$YARN_HEAPSIZE""m"
fi
  • 实例:

配置hadoop参数的时刻,一般都是配置 hadoop-env.sh 如:export HADOOP_HEAPSIZE=16000 。查看相关进程命令有:

1
2
3
4
5
6
7
/usr/local/jdk1.7.0_17/bin/java -Dproc_resourcemanager -Xmx1000m
/usr/local/jdk1.7.0_17/bin/java -Dproc_timelineserver -Xmx1000m
/usr/local/jdk1.7.0_17/bin/java -Dproc_nodemanager -Xmx1000m 
/usr/local/jdk1.7.0_17/bin/java -Dproc_journalnode -Xmx16000m
/usr/local/jdk1.7.0_17/bin/java -Dproc_namenode -Xmx16000m
/usr/local/jdk1.7.0_17/bin/java -Dproc_journalnode -Xmx16000m
/usr/local/jdk1.7.0_17/bin/java -Dproc_datanode -Xmx16000m

与hdfs有关的内存都修改成功了。而与yarn的还是默认的1g(堆)内存。

MR配置文件参数

分成两组,一种是直接设置数字(mb结束的属性),一种是配置java虚拟机变量的-Xmx。

* yarn.app.mapreduce.am.resource.mb、mapreduce.map.memory.mb、mapreduce.reduce.memory.mb
    用于调度计算内存,是不是还能分配任务(计算额度)
* yarn.app.mapreduce.am.command-opts、mapreduce.map.java.opts、mapreduce.reduce.java.opts
    程序实际启动使用的参数

一个是控制中枢,一个是实实在在的限制。

  • 官网文档的介绍:
  • mapreduce.map.memory.mb 1024 The amount of memory to request from the scheduler for each map task.
  • mapreduce.reduce.memory.mb 1024 The amount of memory to request from the scheduler for each reduce task.
  • mapred.child.java.opts -Xmx200m Java opts for the task processes.
  • 下面用实践来验证效果:

    • 先搞一个很大大只有一个block的文件,把程序运行时间拖长一点
    • 修改opts参数,查看效果
    • 修改mb参数,查看效果
  • 实践一

mapreduce.map.memory.mb设置为1000,而mapreduce.map.java.opts设置为1200m。程序照样跑的很欢!!

同时从map的 YarnChild 进程看出起实际作用的是 mapreduce.map.java.opts 参数。memory.mb用来计算节点是否有足够的内存来跑任务,以及用来计算整个集群的可用内存等。而java.opts则是用来限制真正任务的堆内存用量。

注意 : 这里仅仅是用来测试,正式环境java.opts的内存应该小于memory.mb!!具体配置参考:yarn-memory-and-cpu-configuration

  • 实践二

map.memory.mb设置太大,导致调度失败!

  • 实践三

尽管实际才用不大于1.2G的内存,但是由于mapreduce.map.memory.mb设置为8G,整个集群显示已用内存18G(2 * 8g + 1 * 2g)。登录实际运行任务的机器,实际内存其实不多。

reduce和am(appmaster)的参数类似。

mapred.child.java.opts参数

这是一个过时的属性,当然你设置也能起效果(没有设置mapreduce.map.java.opts/mapreduce.reduce.java.opts)。相当于把MR的java.opts都设置了。

获取map/reduce的opts中间会取 mapred.child.java.opts 的值。

admin-opts

查找源码后,其实opts被分成两部分:admin和user。admin的写在前面,user在后面。admin设置的opts可以覆盖user设置的。应该是方便用于设置默认值吧。

实例

同时在一台很牛掰的机器上跑程序(分了yarn.nodemanager.resource.memory-mb 26G内存),但是总是只能一次跑一个任务,但还剩很多内存(20G)没有用啊!!初步怀疑是调度算法的问题。

查看了调度的日志,初始化的时刻会输出 scheduler.capacity.LeafQueue 的日志,打印了集群控制的一些参数。然后 同时找到一篇http://stackoverflow.com/questions/33465300/why-does-yarn-job-not-transition-to-running-state 说是调整 yarn.scheduler.capacity.maximum-am-resource-percent ,是用于控制appmaster最多可用的资源。

appmaster的默认内存是: yarn.app.mapreduce.am.resource.mb 1536(client设置有效), yarn.scheduler.capacity.maximum-am-resource-percent 0.1

跑第二job的时刻,第二个appmaster调度的时刻没有足够的内存(26G * 0.1 - 1.536 > 1.536),所以就跑不了两个job。

CLIENT_OPTS

一般 HADOOP 集群都会配套 HIVE,hive直接用 sql 来查询数据比mapreduce简单很多。启动hive是直接用 hadoop jar 来启动的。相对于一个客户端程序。控制hive内存的就是 HADOOP_CLIENT_OPTS 环境变量中的 -Xmx 。

所以要调整 hive 内存的使用,可以通过调整 HADOOP_CLIENT_OPTS 来控制。(当然理解这些环境变量,你就可以随心随欲的改)

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
[hadoop@cu2 hive]$ sh -x bin/hiveserver2 
...
++ exec /home/hadoop/hadoop/bin/hadoop jar /home/hadoop/hive/lib/hive-service-1.2.1.jar org.apache.hive.service.server.HiveServer2

[hadoop@cu2 hive]$ grep -3  "HADOOP_CLIENT_OPTS" ~/hadoop/etc/hadoop/hadoop-env.sh
export HADOOP_PORTMAP_OPTS="-Xmx512m $HADOOP_PORTMAP_OPTS"

# The following applies to multiple commands (fs, dfs, fsck, distcp etc)
export HADOOP_CLIENT_OPTS="-Xmx128m $HADOOP_CLIENT_OPTS"
#HADOOP_JAVA_PLATFORM_OPTS="-XX:-UsePerfData $HADOOP_JAVA_PLATFORM_OPTS"

# On secure datanodes, user to run the datanode as after dropping privileges.

[hadoop@cu2 hive]$ jinfo 10249
...

VM Flags:

-Xmx256m -Djava.net.preferIPv4Stack=true -Dhadoop.log.dir=/home/hadoop/hadoop-2.6.3/logs -Dhadoop.log.file=hadoop.log -Dhadoop.home.dir=/home/hadoop/hadoop-2.6.3 -Dhadoop.id.str=hadoop -Dhadoop.root.logger=INFO,console -Djava.library.path=/home/hadoop/hadoop-2.6.3/lib/native -Dhadoop.policy.file=hadoop-policy.xml -Djava.net.preferIPv4Stack=true -Xmx128m -Dhadoop.security.logger=INFO,NullAppender

[hadoop@cu2 hive]$ jmap -heap 10249
...
Heap Configuration:
   MinHeapFreeRatio = 40
   MaxHeapFreeRatio = 70
   MaxHeapSize      = 134217728 (128.0MB)
...

–END

安装配置OpenVPN

由于测试环境搭建不在同一个网络,平时查看hadoop集群状态、提交任务都可以通过hadoop-master的外网来操作。但是要读写kafka,需要直接连通所有的节点,全部映射端口太麻烦。一开始想到了VLAN(虚拟局域网),远远超出能力范围。最后通过搭架VPN来实现与测试环境的透明访问。

使用集成版本

参考 https://linux.cn/article-4733-1.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# download https://openvpn.net/index.php/access-server/download-openvpn-as-sw.html

# 安装
[root@cu2 ~]# rpm -ivh openvpn-as-2.0.25-CentOS6.x86_64.rpm 
Preparing...                ########################################### [100%]
   1:openvpn-as             ########################################### [100%]
The Access Server has been successfully installed in /usr/local/openvpn_as
Configuration log file has been written to /usr/local/openvpn_as/init.log
Please enter "passwd openvpn" to set the initial
administrative password, then login as "openvpn" to continue
configuration here: https://192.168.0.214:943/admin
To reconfigure manually, use the /usr/local/openvpn_as/bin/ovpn-init tool.

Access Server web UIs are available here:
Admin  UI: https://192.168.0.214:943/admin
Client UI: https://192.168.0.214:943/

[root@cu2 ~]# passwd openvpn

然后通过web admin进行配置。如主机的信息、hostname以及监听绑定的IP

配置好以后,本地通过网页下载client程序安装。连接配置后:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

C:\Users\winse>tracert  cu3

通过最多 30 个跃点跟踪
到 cu3 [192.168.0.148] 的路由:

  1     2 ms     2 ms     2 ms  172.27.232.1
  2     2 ms     2 ms     2 ms  cu3 [192.168.0.148]

跟踪完成。


C:\Users\winse>route print
===========================================================================
IPv4 路由表
===========================================================================
活动路由:
网络目标        网络掩码          网关       接口   跃点数
          0.0.0.0          0.0.0.0      192.168.1.1    192.168.1.102     20
          0.0.0.0        128.0.0.0     172.27.232.1     172.27.232.2     20
...

http://designmylife.blog.163.com/blog/static/2067142542013527101659960/

路由匹配按最大(最亲)方式匹配。上面路由会先匹配mask为 128.0.0.0 的路由。最终把所有的流量经由VPN出去。

通过 Access Server 安装简单,配置通过网页来弄,和网上资料的都匹配不上,还有用户数量的限制,囧。

编译源码安装方式

参考:
Installation Notes
Installing OpenVPN
如何在Centos 7安裝openVPN

下载 tar.gz 后,查看里面的 INSTALL 文件内容,确认选择依赖软件的版本。

  • 服务端安装配置
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
[root@cu2 openvpn-2.3.10]# yum install libpam* (centos7是pam*)
[root@cu2 openvpn-2.3.10]# yum install pam-devel.x86_64

[root@cu2 ~]# rz
rz waiting to receive.
Starting zmodem transfer.  Press Ctrl+C to cancel.
Transferring lzo-2.06.tar.gz...
  100%     569 KB     569 KB/sec    00:00:01       0 Errors  

[root@cu2 ~]# tar zxvf lzo-2.06.tar.gz 
[root@cu2 ~]# cd lzo-2.06
[root@cu2 lzo-2.06]# ./configure 
[root@cu2 lzo-2.06]# make &&  make install

[root@cu2 openvpn-2.3.10]# ./configure --prefix=/usr/local/openvpn 
[root@cu2 openvpn-2.3.10]# make && make install

[root@cu2 openvpn-2.3.10]# /usr/local/openvpn/sbin/openvpn --version
OpenVPN 2.3.10 x86_64-unknown-linux-gnu [SSL (OpenSSL)] [EPOLL] [MH] [IPv6] built on Mar  9 2016

https://github.com/OpenVPN/easy-rsa/releases

[root@cu2 EasyRSA-3.0.1]# ./easyrsa  help

[root@cu2 EasyRSA-3.0.1]# ./easyrsa init-pki
[root@cu2 EasyRSA-3.0.1]#  ./easyrsa build-ca

[root@cu2 EasyRSA-3.0.1]# ./easyrsa gen-req openvpn nopass
client
[root@cu2 EasyRSA-3.0.1]# ./easyrsa sign client openvpn

[root@cu2 EasyRSA-3.0.1]# ./easyrsa gen-req esw-cu nopass
server
[root@cu2 EasyRSA-3.0.1]# ./easyrsa sign server esw-cu

commonName随便取,但是不能重!

[root@cu2 EasyRSA-3.0.1]# tree pki/
pki/
├── ca.crt
├── certs_by_serial
│   ├── 01.pem
│   └── 02.pem
├── index.txt
├── index.txt.attr
├── index.txt.attr.old
├── index.txt.old
├── issued
│   ├── esw-cu.crt
│   └── openvpn.crt
├── private
│   ├── ca.key
│   ├── esw-cu.key
│   └── openvpn.key
├── reqs
│   ├── esw-cu.req
│   └── openvpn.req
├── serial
└── serial.old

[root@cu2 EasyRSA-3.0.1]#  ./easyrsa gen-dh
[root@cu2 EasyRSA-3.0.1]# cd pki
[root@cu2 pki]# cp ca.crt dh.pem issued/esw-cu.crt private/esw-cu.key /etc/openvpn/ 

[root@cu2 openvpn-2.3.10]# cp sample/sample-config-files/server.conf /etc/openvpn/

  proto tcp
  cert esw-cu.crt
  key esw-cu.key 
  dh dh.pem
  # 在客户端额外添加这条路由到VPN
  push "route 192.168.0.0 255.255.255.0"
  # 和AS一样,会添加0.0.0.0到VPN的路由。所有请求默认走VPN https://www.digitalocean.com/community/tutorials/how-to-setup-and-configure-an-openvpn-server-on-centos-7
  ;push "redirect-gateway def1 bypass-dhcp"
  # 内网特定的域名解析地址
  ;push "dhcp-option DNS 10.16.6.88"
  #Enable multiple client to connect with same key
  duplicate-cn
  user nobody
  group nobody

[root@cu2 pki]# cd /etc/openvpn/
[root@cu2 openvpn]# /usr/local/openvpn/sbin/openvpn --config /etc/openvpn/server.conf --启动完后Ctrl+C
[root@cu2 openvpn]# /usr/local/openvpn/sbin/openvpn --daemon --config server.conf 
  • 安装客户端:

https://openvpn.net/index.php/open-source/downloads.html 下载安装 对应 的版本, 客户端的版本最好最好与服务端一致!! 不同版本默认配置不同。

拷贝sample-config/client.ovpn和服务端的ca.crt、openvpn.crt、openvpn.key到config目录下面。

修改client.ovpn:

1
2
3
4
proto tcp
remote webcu2 1194
cert openvpn.crt
key openvpn.key

然后启动 OpenVPN GUI ,右键connect就行了。

1
2
3
4
5
6
7
8
9
10
11
12
13
$ route print
...
IPv4 路由表
===========================================================================
活动路由:
网络目标        网络掩码          网关       接口   跃点数
          0.0.0.0          0.0.0.0      192.168.1.1    192.168.1.102     20
         10.8.0.1  255.255.255.255         10.8.0.5         10.8.0.6     20
         10.8.0.4  255.255.255.252            在链路上          10.8.0.6    276
         10.8.0.6  255.255.255.255            在链路上          10.8.0.6    276
         10.8.0.7  255.255.255.255            在链路上          10.8.0.6    276
      192.168.0.0    255.255.255.0         10.8.0.5         10.8.0.6     20
...

问题

  • 连接到VPN服务端的机器是没有问题,但是不能访问该机器的应用(端口不同)

被防火墙限制了,在服务端把10.8.0.0/24加入到防火墙允许。

1
iptables -A INPUT -s 10.8.0.0/24 -j ACCEPT  # 反正能访问OpenVPN的端口即可
  • 不能访问服务端其他机器

在iptables上增加转发

1
iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE

centos7 firewall:(注:在centos7上面一样可以用上面的iptables命令!! https://www.centos.org/forums/viewtopic.php?t=53819)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ firewall-cmd --permanent --add-masquerade 
查看写入的内容: cat zones/public.xml

$ firewall-cmd --permanent --direct --add-rule ipv4 nat POSTROUTING 0 -o eth0 -j MASQUERADE 
查看写入的内容: cat /etc/firewalld/direct.xml

$ firewall-cmd --reload


https://www.server-world.info/en/note?os=CentOS_7&p=firewalld&f=2
http://www.mjhall.org/centos7-firewalld-nat-router/
https://www.centos.org/forums/viewtopic.php?t=53819

#如果防火墙默认是reject,需要增加
# #开放主机IP firewall-cmd --permanent --zone=trusted --add-source=192.168.2.0/24
[root@bigdata-dev ~]# firewall-cmd --zone=public --add-port=1194/tcp --permanent
success
[root@bigdata-dev ~]# firewall-cmd --reload
success

查看iptables规则:

1
iptables -nL -t nat

测试下:

1
2
3
4
5
$ ping cu3

正在 Ping cu3 [192.168.0.148] 具有 32 字节的数据:
来自 192.168.0.148 的回复: 字节=32 时间=5ms TTL=63
来自 192.168.0.148 的回复: 字节=32 时间=5ms TTL=63

其他(未实践,记录下来)

必须在服务器端的内网网关上将到10.8.0.0/24网段的路由指向到openvpn服务器,不然从服务器端内网其他机器根本找不到去往10.8.0.0/24网段的路由。这里又分两种情况,一种是服务端有内网网关设备的(按如上说法即可);一种是服务端内网没有网关设备,即服务器通过交换机相连,相互通讯靠广播的情况。我的就是这种情况。需要在想访问的server上增加到10.8.0.0/24的路由,如下

route add -net 10.8.0.0/24 gw 192.168.1.211 #1.211为openvpn服务器的内网IP

Make sure that you’ve enabled IP and TUN/TAP forwarding on the OpenVPN server machine. 确定开启了转发功能,然后在openvpn服务器Iptables添加如下两条规则

iptables -A FORWARD -i tun0 -s 10.8.0.0/24 -j ACCEPT #简单说,允许数据从客户端到后端server iptables -A FORWARD -i em2 -d 10.8.0.0/24 -j ACCEPT #允许数据从后端server到客户端

参考

–END

Rsync与scp优势

今天在做flume写kafka数据时,数据从其他目录cp拷贝过来,flume采集程序报错 程序采集的时刻文件发生了改变

1
2
3
4
07 Mar 2016 16:46:05,535 ERROR [pool-3-thread-1] (org.apache.flume.source.SpoolDirectorySource$SpoolDirectoryRunnable.run:256)  - FATAL: Spool Directory source s1: { spoolDir: /home/hadoop/flume/data/ }: Uncaught exception in SpoolDirectorySource thread. Restart or reconfigure Flume to continue processing.
java.lang.IllegalStateException: File has changed size since being read: /home/hadoop/flume/data/hbase-hadoop-master-cu2.log
        at org.apache.flume.client.avro.ReliableSpoolingFileEventReader.retireCurrentFile(ReliableSpoolingFileEventReader.java:326)
        at org.apache.flume.client.avro.ReliableSpoolingFileEventReader.readEvents(ReliableSpoolingFileEventReader.java:259)

联想到scp和rsync,好像rsync是有重命名这样的步骤的。网上也有很多对比这个两个工具的资料。

这里只关注最后一点,对于按照名称来采集的程序非常关键!下面使用inotify监控目录的操作,在进行scp和rsync时发生的操作:

1
2
3
4
5
6
7
8
9
[hadoop@cu2 test]$ scp -r source target/
[hadoop@cu2 test]$ rm target/source/1234
[hadoop@cu2 test]$ rsync -vaz source target/
sending incremental file list
source/
source/1234

sent 141 bytes  received 35 bytes  352.00 bytes/sec
total size is 34  speedup is 0.19

对应的inotify的输出为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[hadoop@cu2 test]$ inotifywait -m target/source/ # yum install -y inotify*
Setting up watches.
Watches established.
target/source/ CREATE 1234
target/source/ OPEN 1234
target/source/ MODIFY 1234
target/source/ CLOSE_WRITE,CLOSE 1234

target/source/ DELETE 1234

target/source/ ATTRIB,ISDIR 
target/source/ CREATE .1234.ARUg56
target/source/ OPEN .1234.ARUg56
target/source/ ATTRIB .1234.ARUg56
target/source/ MODIFY .1234.ARUg56
target/source/ CLOSE_WRITE,CLOSE .1234.ARUg56
target/source/ ATTRIB .1234.ARUg56
target/source/ MOVED_FROM .1234.ARUg56
target/source/ MOVED_TO 1234

rsync会先写把内容复制到一个临时文件,复制完成后,再重命名为正式的名称。

在生产环境尽量使用rsync来进行文件(夹)的复制/同步操作,即快键有安全。

当然还有奇葩的快速删除海量文件夹的方式也用的是rsync:

1
2
3
rsync --delete-before -d /data/blank/ /var/spool/clientmqueue/ 

rsync --delete-before -a -H -v --progress --stats /tmp/test/ log/

–END

Ganglia页自定义视图

官网自带的页面指标太拥挤,同一个组各指标的顺序不能指定(默认好像是按名称排序的)不便于观察。通过页面的Views页签可以查看自定的图标。

在conf文件夹(由conf_default.php中views_dir指定)下面建立文件名以 view 开头的json文件。通过Views还可以聚合多个指标,在一个图中查看整体的变化趋势。配置聚合视图前可以先在 Aggregate Graphs 弄出来先瞧一瞧。

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
[root@cu2 ~]# cd /var/www/html/ganglia/
# 查看view放置的位置
[root@cu2 ganglia]# grep views_dir conf_default.php 
$conf['views_dir'] = $conf['gweb_confdir'] . '/conf';

# view配置目录
[root@cu2 conf]$ ll
......
-rw-rw-r-- 1 apache apache    58 Oct  2 04:38 view_default.json
-rw-r--r-- 1 root   root    2344 Feb 25 20:12 view_qbevery.json
-rw-r--r-- 1 root   root     241 Feb 25 18:59 view_qb.json

[root@cu2 conf]# cat view_qb.json 
{
"default_size" : "xlarge",
"view_name": "qb",
"items": [
{
"aggregate_graph": "true",
"graph_type": "stack", 
"host_regex":  [ { "regex" : "cu2" } ], 
"metric_regex": [ { "regex":  "qb_.*" } ],
"title": "qb"
}
],
"view_type": "standard"
}
[root@cu2 conf]# cat view_qbevery.json 
{
"default_size" : "medium",
"view_name": "qbevery",
"items": [
{ "hostname":"cu2","metric":"qb_520k_53d_9.82_120807"},
{ "hostname":"cu2","metric":"qb_500k_98d_7.81_116763"},
{ "hostname":"cu2","metric":"qb_400k_91d_7.67_116762"},
{ "hostname":"cu2","metric":"qb_350k_42d_9.08_120802"},
{ "hostname":"cu2","metric":"qb_350k_83d_7.40_116761"},
{ "hostname":"cu2","metric":"qb_300k_78d_7.12_116760"}
],
"view_type": "standard"
}

参考

–END

Ganglia扩展-Python

最简单的添加metric的方式使用 gmetric

1
/usr/local/ganglia/bin/gmetric -n "TITLE" -v VALUE -t int16 -g GROUP

有时指标计算复杂,通过简单的shell不能满足功能需要。我们可以使用python模块来定制。

安装

默认安装会检查Python环境,符合条件会自动的安装Python模块。

1
2
3
4
5
6
7
8
9
10
11
12
[root@cu2 ganglia-3.7.2]# yum install -y python-devel
[root@cu2 ganglia-3.7.2]# ./configure --with-gmetad --enable-gexec --enable-status --prefix=/usr/local/ganglia
...
Checking for python
checking for python... /usr/bin/python
checking Python version... 2.6
checking Python support... yes
checking Perl support... no
checking for pkg-config... /usr/bin/pkg-config
checking pkg-config is at least version 0.9.0... yes
...
[root@cu2 ganglia-3.7.2]# make && make install

安装成功

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
[root@cu2 ganglia]# pwd
/usr/local/ganglia
[root@cu2 ganglia]# ll lib64/ganglia/
total 704
-rwxr-xr-x 1 root root 87344 Feb  1 16:52 modcpu.so
-rwxr-xr-x 1 root root 84566 Feb  1 16:52 moddisk.so
-rwxr-xr-x 1 root root 17896 Feb  1 16:52 modgstatus.so
-rwxr-xr-x 1 root root 84526 Feb  1 16:52 modload.so
-rwxr-xr-x 1 root root 86280 Feb  1 16:52 modmem.so
-rwxr-xr-x 1 root root 31695 Feb  1 16:52 modmulticpu.so
-rwxr-xr-x 1 root root 84928 Feb  1 16:52 modnet.so
-rwxr-xr-x 1 root root 84246 Feb  1 16:52 modproc.so
-rwxr-xr-x 1 root root 53994 Feb  1 16:52 modpython.so
-rwxr-xr-x 1 root root 85584 Feb  1 16:52 modsys.so
[root@cu2 ganglia]# ll etc/conf.d/
total 4
-rw-r--r-- 1 root root 408 Feb  1 16:52 modpython.conf

[root@cu2 ganglia]# vi etc/gmetad.conf
 rrdtool_dir

[root@cu2 ganglia]# cat etc/conf.d/modpython.conf 
/*
  params - path to the directory where mod_python
           should look for python metric modules

  the "pyconf" files in the include directory below
  will be scanned for configurations for those modules
*/
modules {
  module {
    name = "python_module"
    path = "modpython.so"
    params = "/usr/local/ganglia/lib64/ganglia/python_modules"
  }
}

include ("/usr/local/ganglia/etc/conf.d/*.pyconf")

Hello World

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
[root@cu2 ganglia]# cd lib64/ganglia/
[root@cu2 ganglia]# mkdir python_modules
[root@cu2 ganglia]# cd python_modules/

[root@cu2 python_modules]# cp ~/ganglia-3.7.2/gmond/python_modules/example/example.py ./
[root@cu2 python_modules]# 

[root@cu2 python_modules]# cd /usr/local/ganglia/etc/conf.d/
[root@cu2 conf.d]# vi example.pyconf
modules {
  module {
    name = "example"
    language = "python"
    param RandomMax {
      value = 600
    }
    param ConstantValue {
      value = 112
    }
  }
}

collection_group {
  collect_every = 10
  time_threshold = 50
  metric {
    name = "PyRandom_Numbers"
    title = "Random"
    value_threshold = 70
  }
  metric {
    name = "PyConstant_Number"
    title = "Constant"
    value_threshold = 70
  }
}

[root@cu2 conf.d]# service gmond restart

example.py 初始化函数 metric_initexample.pyconf 文件获取配置、返回可用指标对象( call_back 关联执行的handler; groups 数据的分组)。

模块中必须包含的三个方法是:

  • def metric_init(params):
  • def metric_cleanup():
  • def metric_handler(name):

前面两个方法的名字必须是一定的,而最后一个 metric_handler与 metric_init 返回对象的callback对应。__main__ 函数用于debug,可以单独调试该模块,以检测是否有错。 更详细的内容看官网的文档Ganglia-GMond-Python-Modules

参考

–END