VI SNMP&RRDTool
相关概念:
1、SNMP
Network monitoring:网络流量监控,网络内的主机状态,主机上运行的服务状态,每时每刻按需了解网络中某主机上的某服务在某一时刻的运行状态及访问的人数等都归类到network monitoring,通过一台主机就可管理上千台server的运行状况,并在第一时间取得其警告信息,如某server上有关键服务宕机了,不可用时会触发一种机制通知给管理员采取有效措施;另还有自动网络监测工具,有自动恢复功能,当无法恢复时通知给管理员,当网络出问题时会自动重启网络服务等,如当某个网卡上的地址ping不通时能自动重新启用该网卡地址等,开源体系中用于网络监控方面工具有很多种,无论这些工具如何变化,实现主机监控的方式有以下几种:
SNMP(simple network management protocol);
COMMAND(在远程服务器上执行一个脚本,将脚本运行的结果返回给某一监控主机,或通过网络探测工具不停地抓包查看某台主机的状态等);
Remote script(ssh方式)
监控主机(NMS)接收被监控主机发来的信息,被监控主机上运行某一监控服务(专门监控该主机的关键性服务和系统资源情况),并定期发送给监控主机NMS,监控主机NMS例如定期3S向被监控主机上的监控服务发起请求,请求被监控主机上某个服务当前的状态,将发来的数据记录下来保存至文件方便管理员查看à在NMS上可安装开发好的系统,这个系统可将接收来的信息根据管理员定义的法则予以分析,并将结果报告给管理员(以文档方式保存)à在前端通过图形化的网页或工具将保存在本地文件中的数据展示出来(例如某一时刻带宽占用率过高等都能直观的显示)à网络浪量大到无法承载,在线人数过多导致server崩溃,这时附加报警功能实时监控,给某一指标定义域值设最大上限,当达到上限会触发脚本,这个脚本会自动的向管理员发邮件或短信通知等(可自动获取数据à将数据绘成图à当超出某项数据定义的上限会额外触发一种机制给管理员通知,大多数监控系统就是这样工作的)
有一监控主机监控着诸多主机,监控机每隔一段时间到被监控主机上获取服务或想要的的某些系统信息状态等,并将结果取回到本机保存至某文件中,监控机上的应用会自动分析这些文件,并将分析的结果通过直观的方式展示,而且在超过域值可给管理员发送报警信息,常见的任何监控系统展示方式不同、规模不同,所提供的管理功能风格不同,背后的核心机制是一样的
cacti(一堆PHP脚本,强大的绘图引擎(指挥着rrdtool绘图),它本身不实现任何监控功能,只是将其它监控工具所获取到的数据通过工具给保存下来予以展示,这些数据是时间序列相关的数据,例如要探测一天中的最高温度最低温度)
nagios(监控某主机服务是否在线,状态监控工具,非时间序列数据,一旦有状态转换如onàoff,会触发报警功能)
rrdtool(绘图工具)
注:通常cacti结合nagios使用
NMS为管理员提供命令行接口,可以发送SNMP的操作指令到任何一个被监控主机,被监控端安装一服务(agent)专门用于解析监控端的查询请求,并将数据返回给监控端,agent只用于接收远端的查询指令(管理指令),监测磁盘空间大小,当前登录的用户,当前server的流量,若任何人都可获取这些数据,隐密性将无法保证,这就引入了一种简单的认证机制community社区,双方在建立通信时说明是一个团伙的,例如某一社区aaa,NMS在发送指令获取某主机状态时,说明我就是aaa的,agent若认可aaa将返回本机数据,社区community的名字就是双方建立通信认证的密码,所以很简单,community是明文传输极其不安全
SNMP(真正意义的监控工具,可获取主机的某服务或系统状态等信息,还可自定义域值发送指定的指令)
SNMPv1-->SNMPv2-->SNMPv3(从简单到复杂,v1的安全机制基于community(client和server))
there are typically three communities inSNMPv1有三类communities(read only,read-write,trap)
read only(管理端只能向被管理端获取(读)信息;
read-write(可向对方发送控制指令,监控端有权限操控被监控端)
trap(捕获,通知机制notify,被管理端主动的发信息去联系监控端)
SNMPv2对v1的功能做了强化,仍以community作为认证机制,叫community-string-based,也被称为SNMPv2c,v1、v2过于简化,认证不安全,v3增强了其认证机制,并在数据传输上也增强了安全性,但目前这三种协议中用的最多的还是v1,互联网上的古老设备支持v1而不支持v3
MIBs(management information base管理信息库,类似DNS倒置树状结构,将可被监测的对象归类,其中一个子类internet,其下有遵循tcp/ip的很多种设备,各个公司的都不同,如cisco公司的任何一种switch和router,甚至设备的每个接口,如何获取设备上的唯一接口,为使监控的资源在全球框架下通用,每个监控对象预留有通用对象,如OS的version、运行时间、启动的service、硬盘状况,SNMP把这些通用的拿过来专门创建一个类别,不同的地方在于ip地址,如监控某个主机OS上的version只需指定这个主机即可,这样就不会混淆,如要监控某个router设备或switch的某个接口的流量,如cisco公司的某个router内置了别的公司没有的功能,那定义的规范不会对其生效,例如DNS,域名只要全球唯一,域内的主机自定义即可,cisco申请一个域,在域下自定义任何一个设备的编号,设备上接口的编号也自定义
以上,全球可监控的对象有通用性,不通用的某公司申请后再创建子分支,标识靠对象标识符OID(object identifier),自顶向下,为使管理员方便的引用,对其取名字并与OID建立对应关系,如名字为internet.ibm.host.name会被翻译为对应的OID号,如1.2.3.4
MIB是大多数的监控对象名称与OID的映射关系表,通过文件保存,主机上有什么MIB库才能对主机的相关对象作监控,被监控主机上的agent通过MIB来理解NMS发来的请求指令,常用的是MIB-II(任何一个agent都至少会提供一个MIB库,叫MIB-II),要监控某主机的对象要有相应的MIB库才行
注:MIB库是个纯ASCII文件
如图:1.3.6.1.2.1(iso.org.dod.internet.mgmt.mib-2)
brief description of the MIB-II groups:
system(1.3.6.1.2.1.1)
interfaces(1.3.6.1.2.1.2)
tcp(1.3.6.1.2.1.6)
the concept of network management(fault management故障管理;configuration management配置管理;accounting management记账管理;performance management性能管理;security management安全管理)
注:security management(IDS***检测系统,HIDS(host IDS);IPS***防御系统,NIPS(network IPS))
tcp/ip communication model and SNMP(SNMP基于UDP,agent端应被动打开一端口udp/161随时等待NMS的查询请求,一旦被监控主机故障可通过trap发送通知引起监控端NMS注意(agent-->NMS),NMS也要被动打开一端口udp/162,用到trap时监控端才需打开udp/162端口,对SNMP的community来说系统启用了SNMP功能,都会自动启用两个内置的community,分别为public(ro)和private(rw),类似mysql刚安装好后root密码默认为空,任何人都可连接,SNMP也是这样,在被监控主机上的agent在启用SNMP后若不改任何人都可访问,尽量更改,为安全可禁用private仅启用public)
SNMP operations(SNMP操作,向被监控端发起一系列请求):
get(获取一个指定的被监控对象的相关信息)
getnext(获取一个主机下的某一个监控对象下的所有子项)
getbulk(获取某主机下所有监控对象的所有子项)
set(发起控制指令)
getresponse(获取响应)
trap
例如:某设备为11,监控对象有1、2、3,则
get 11.1.1
getnext 11.1
getbulk 11
在MIB库中有一子node叫host(MIB-II 25,iso.org.dod.internet.mgmt.mib-2.host,其下有6个子对象):hrSystem,hrStorage,hrDevice,hrSWRun,hrSWRunPerf,hrSWInstalled
linux关于SNMP的软件包有两个:net-snmp(agent),net-snmp-utils(NMS用到的命令)
若该主机只用来被监控则只安装net-snmp,用于监控别人安装net-snmp-utils,若用于trap监控端要安装net-snmp包,两个包都安装可用于监控端又用于被监控端
[root@node1 ~]# yum -y install net-snmp net-snmp-utils
[root@node1 ~]# rpm -ql net-snmp
/etc/rc.d/init.d/snmpd
/etc/rc.d/init.d/snmptrapd(若用于trap机制,监控端要安装net-snmp,并启用snmptrapd服务)
/etc/snmp
/etc/snmp/snmpd.conf
/etc/snmp/snmptrapd.conf
/etc/sysconfig/snmpd(agent用)
/etc/sysconfig/snmptrapd(trap服务端用)
/usr/bin/net-snmp-create-v3-user
/usr/bin/snmpconf
/usr/sbin/snmpd
/usr/sbin/snmptrapd
/usr/share/snmp(/usr/share/snmp/mibs/*,当前系统的mib库文件,标准mib库SNMPv2-MIB.txt,另还有很多,提供的监控功能很强大)
……
[root@node1 ~]# service snmpd start
正在启动 snmpd: [确定]
[root@node1 ~]# netstat -unlp | grep 161
udp 0 0 0.0.0.0:161 0.0.0.0:* 6387/snmpd
[root@node1 ~]# snmp
snmpbulkget snmpd snmpget snmpnetstat snmptable snmptrap snmpvacm
snmpbulkwalk snmpdelta snmpgetnext snmpset snmptest snmptrapd snmpwalk
snmpconf snmpdf snmpinform snmpstatus snmptranslate snmpusm
[root@node1 ~]# man snmpwalk(retrieve asubtree of management values using SNMP GETNEXT requests,发送getnext信息获取一个监控对象下的所有子项)
snmpwalk [APPLICATION OPTIONS] [COMMONOPTIONS] [OID]
[root@node1 ~]# snmpwalk -v 2c -c public localhost(-v表示snmp协议的版本号,-c表示community,主要从两个mib库中获取信息SNMPv2-MIB.txt和HOST-RESOURCES-MIB.txt,还有DISMAN-EVENT-MIB.txt)
SNMPv2-MIB::sysDescr.0 = STRING: Linuxnode1.magedu.com 2.6.32-358.el6.x86_64 #1 SMP Tue Jan 29 11:47:41 EST 2013x86_64
SNMPv2-MIB::sysObjectID.0 = OID:NET-SNMP-MIB::netSnmpAgentOIDs.10
DISMAN-EVENT-MIB::sysUpTimeInstance =Timeticks: (32771) 0:05:27.71
SNMPv2-MIB::sysContact.0 = STRING: Root
SNMPv2-MIB::sysName.0 = STRING:node1.magedu.com
SNMPv2-MIB::sysLocation.0 = STRING: Unknown(edit /etc/snmp/snmpd.conf)
……
HOST-RESOURCES-MIB::hrSystemUptime.0 =Timeticks: (458542) 1:16:25.42
HOST-RESOURCES-MIB::hrSystemUptime.0 = Nomore variables left in this MIB View (It is past the end of the MIB tree)
[root@node1 ~]# vim /etc/snmp/snmpd.conf(定义了两项view,这就是为什么#snmpwalk–v 2c –c public localhost得到的信息主要是SNMPv2-MIB和HOST-RESOUCES-MIB)
# name incl/excl subtree mask(optional)
view systemview included .1.3.6.1.2.1.1
view systemview included .1.3.6.1.2.1.25.1.1
注:[root@node1 ~]# vim /usr/share/snmp/mibs/SNMPv2-MIB.txt(此文件中定义的snmpMIBObjectsOBJECT IDENTIFIER ::= { snmpMIB 1 }与/etc/snmp/snmpd.conf中第一个view的.1.3.6.1.2.1.1有对应关系)
[root@node1 ~]# man snmpget(communicate swith a network entity using SNMP GET requests)
#snmpget [COMMON OPTIONS] [-Cf] OID[OID]...
[root@node1 ~]# snmpget -v 2c -c publiclocalhost HOST-RESOURCES-MIB::hrSystemUptime.0
HOST-RESOURCES-MIB::hrSystemUptime.0 =Timeticks: (572755) 1:35:27.55
[root@node1 ~]# vim /usr/share/snmp/mibs/TCP-MIB.txt(记住6这个数字)
tcp OBJECT IDENTIFIER ::= { mib-2 6 }
[root@node1 ~]# vim /etc/snmp/snmpd.conf(添加此行)
view systemview included .1.3.6.1.2.1.6
[root@node1 ~]# service snmpd restart
停止 snmpd: [确定]
正在启动 snmpd: [确定]
[root@node1 ~]# snmpwalk -v 2c -c publiclocalhost
……
SNMPv2-MIB::sysORUpTime.6 = Timeticks: (3)0:00:00.03
SNMPv2-MIB::sysORUpTime.7 = Timeticks: (3)0:00:00.03
SNMPv2-MIB::sysORUpTime.8 = Timeticks: (3)0:00:00.03
TCP-MIB::tcpRtoAlgorithm.0 = INTEGER:other(1)
TCP-MIB::tcpRtoMin.0 = INTEGER: 200milliseconds
TCP-MIB::tcpRtoMax.0 = INTEGER: 120000milliseconds
……
HOST-RESOURCES-MIB::hrSystemUptime.0 =Timeticks: (628173) 1:44:41.73
HOST-RESOURCES-MIB::hrSystemUptime.0 = Nomore variables left in this MIB View (It is past the end of the MIB tree)
[root@node1 ~]# snmpwalk -v 2c -c publiclocalhost tcp | egrep '(established|listen)'
[root@node1 ~]# snmpwalk -v 2c -c publiclocalhost tcp | grep established | wc -l
4
[root@node1 ~]# vim /etc/snmp/snmpd.conf(定义允许哪些主机可获取本机的状态)
#com2sec notConfigUser default public(default表示默认为所有主机都可获取)
com2sec notConfigUser 127.0.0.1 mypublic(在生产中mypublic这个字符串要是随机数,越随机越好)
com2sec notConfigUser 192.168.41.0/24mypublic
[root@node1 ~]# service snmpd restart
停止 snmpd: [确定]
正在启动 snmpd: [确定]
[root@node1 ~]# snmpwalk -v 2c -c public 192.168.41.133 tcp(public则认证失败,要使用mypublic才行)
Timeout: No Response from 192.168.41.133
[root@node1 ~]# snmpwalk -v 2c -c mypublic 192.168.41.133 tcp
TCP-MIB::tcpRtoAlgorithm.0 = INTEGER:other(1)
TCP-MIB::tcpRtoMin.0 = INTEGER: 200milliseconds
TCP-MIB::tcpRtoMax.0 = INTEGER: 120000milliseconds
……
[root@node1 ~]# man snmpnetstat(display networking status and configuration information from a network entity via SNMP,直接通过snmp协议获取另一主机的状态信息)
[root@node1 ~]# snmpnetstat -v 2c -cmypublic -Can -Cp tcp 192.168.41.133(-Ca表示默认配置With the default display, show the state of all sockets; normally sockets used byserver processes are not shown,-n表示numerical,-Cp表示Show statistics about protocol, which is either a well-known namefor a protocol or an alias for it)
Active Internet (tcp) Connections(including servers)
Proto Local Address Remote Address (state)
tcp *.22 *.* LISTEN
tcp *.111 *.* LISTEN
tcp *.39210 *.* LISTEN
tcp 127.0.0.1.25 *.* LISTEN
tcp 127.0.0.1.199 *.* LISTEN
tcp 127.0.0.1.631 *.* LISTEN
tcp 127.0.0.1.6010 *.* LISTEN
tcp 127.0.0.1.6011 *.* LISTEN
tcp 192.168.41.133.22 192.168.41.1.4917 ESTABLISHED
tcp 192.168.41.133.22 192.168.41.1.6197 ESTABLISHED
[root@node1 ~]# chkconfig snmpd on
[root@node1 ~]# chkconfig --list snmpd
snmpd 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭
2、RRDTool
rrdtool(round robin database tool,从其它主机获取数据并展示,可理解为是环状的数据库,每个数据块是一个扇形,轮转数据库,当初始创建扇区时空间大小就指定了,例如分8个扇区,当存第9个数据时第一个就被覆盖了,若要存很多数据,如一天存一个,到第9天时将覆盖第1天的数据,若第一天的数据还要用则在开始预设365个空间即可,这样数据库的总大小是固定的只不过下一年的数据将依次覆盖之前的数据;
数据库名通常以.rrd结尾,rrdtool的子命令create可创建这样的数据库
数据库中存放的是时间序列的数据,保存的数据有时间戳,数据库中保存的并不是取得的数据(未必与获取到的数据一样),直接获取到的数据对我们是没意义的,要将获取到的数据绘成图,如温度在8时9时10时分别为21、18、30,可保存为实际的值,也可保存为相对值例如21、-3、12(后面的实际值减去前一个的值),所以保存的数据具体是什么,未必是直接获取到的数据,真正对我们有用的并不是这些实际的数据,而是经过聚合函数聚合后的数据叫RRA(round robin archive轮转归档信息),指定获取数据时每隔一个固定时长(默认是300s)获取一次数据(时间序列数据),每一个数据获取下来后rrd会将每一个数据解析后保存,这每一个数据node通常会保存至rrd的时间槽上,rrd在创建时就要事先指定好每个槽放的是几点几分几秒的数据(创建时就要指定从几点开始计数),用--step指定每隔300s保存一次获取到的数据(如10:00、10:05、10:10),获取到的数据就放在对应的时间槽上(实际是放到数据库的临时数据表中,用户是看不见的),这每一个数据node叫PDP(primary data point这不是我们真正关心的数据),还要对PDP做聚合函数计算,每多少个为一个分组,为使数据更具代表性,以分组为例取平均值,如可以两两一组取平均值,这个平均值才是保存在时间槽timeslot上的数据,timeslot上数据的时间跨度是600s,绘图是根据600s绘的图,而不是300s的结果,聚合有多种方式如AVERAGE平均值、MAX、MIN、LAST上一个值,每两个的平均值就是RRA,聚合后的值是CDP(consolidation data point),若还想看看每2个小时的趋势、每天的趋势、每月的趋势,例如把每5个PDP分为一组重新归档取平均值保存(第二类归档),继续将30个PDP再分一组归档(第三类归档),这样就定义了每2个PDP平均、每5个PDP平均、每30个PDP平均,若非要看每15个平均,解析度(resolution),时间跨度(类似像素800*600和1440*900),解析度越精细时间跨度越小,每2个平均高解析度,每5个平均低解析度,若要找的解析度没有完全匹配的则找比当前解析度高的最近的解析度的值
rrd可保存多种数据,如对于网卡进出的流量,一个文件可保存多个时间序列数据,每个时间序列叫DS(data source),一个rrd文件至少要有1个或多个DS,每个DS都可单独的做聚合,一个rrd文件要知道从哪取得数据,每隔多长时间取得一次数据,数据取下来后还要定义每几个数据做聚合,还要定义是取最大值、最小值还是平均值
如图:第一个RRA每4个的归档结果,第二个RRA每10个的归档结果
[root@node1 ~]# uname -a
Linux node1.magedu.com 2.6.18-308.el5 #1SMP Fri Jan 27 17:21:15 EST 2012 i686 i686 i386 GNU/Linux
http://packages.express.org/rrdtool/(下载位置)
rrdtool-1.4.7-1.el5.wrl.i386.rpm
rrdtool-devel-1.4.7-1.el5.wrl.i386.rpm
rrdtool-perl-1.4.7-1.el5.wrl.i386.rpm
[root@node1 ~]# yum -y localinstall --nogpgcheck rrdtool-1.4.7-1.el5.wrl.i386.rpm rrdtool-perl-1.4.7-1.el5.wrl.i386.rpm
[root@node1 ~]# man rrdtool
rrdtool - [workdir]| function
create(创建数据时空间大小就指定了,Set up a new Round Robin Database (RRD). Check rrdcreate)
update(填充数据,Store new data values into an RRD. Check rrdupdate)
updatev(同update,Operationally equivalent to update except for output. Check rrdupdate)
graph(将数据绘图,Create a graphfrom data stored in one or several RRDs. Apart from generating graphs, data canalso be extracted to stdout. Check rrdgraph)
dump(将数据取出,Dump the contents of an RRD in plain ASCII. In connection with restore you can use this to move an RRD from one computer architecture to another. Check rrddump)
fetch(从一个数据源中取得数据,Get data for a certain time period from a RRD. The graph function uses fetch to retrieveits data from an RRD. Check rrdfetch)
info(查看文件格式,Get information about an RRD. Check rrdinfo)
[root@node1 ~]# man rrdcreate
#rrdtool create filename [--start|-b starttime] [--step|-s step] [--no-overwrite] [DS:ds-name:DST:dst arguments] [RRA:CF:cf arguments]
--start start time(default:now-10s,指定起始时间,接受从什么时间开始计数,默认当前时间减10s提前10s)
--step step(default:300s,时间跨度,每多长时间接受一个数据,保存下来的是PDP)
--no-overwrite(Do not clobber an existing file of the same name)
DS:ds-name:DST:dst arguments(ds-name为1-19个字符(大小写字符下划线),DST(data source type有GAUGE、COUNTER、DERIVE、ABSOLUTE,每种类型保存值的方式不同),dst arguments有三类heartbeat:min:max)
注:GAUGE(保存一个数值原来的值,它是什么就保存什么,保存的是PDP);
COUNTER(相对值,相对上一个数据而言,COUNTER所指定的值后面跟的必须是递增状态的数据,后一个要大于或等于前一个,如网卡流量数据通常是累加的,日志文件的总条目数);
DERIVE(相对值,相对上一个数据而言,DERIVE保存的值是有时增有时减的数据,如温度);
ABSOLUTE(相对值,相对最原始的值)
举例(初始值为0,之后的数据2、3、6、9,使用GAUGE保存(2、3、6、9),使用COUNTER保存(2、1、3、3,注意若初始值为0之后的数据是2、6、3、9,则COUNTER将不能保存2、4、-3、6必须要是递增的数据),使用DERIVE(2、1、3、3),使用ABSOLUTE(2、3、6、9,均是减初始值的结果)
注:dst arguments(heartbeat:min:max,如定义5s接受一个数据,若数据来的不准时,要晚一些到7s时才来,heartbeat定义当数据来了后,在最长多长时间是这个对应槽上的数据,如5s接受一个数据到10s还不来则会接受下一个数据,只要在10s之前来还是这个槽上的数据,数据未在精确时间点上到来的话,最长在多长时间内接受,若指定10s内到来,在10s内没来这个数据将被标记为*UNKNOWN*,对rrd来讲只要*UNKNOWN*比例不高照样可绘图(智能之处),min:max定义时间槽上的最小值和最大值,接受的值是0-65535,若传来的值是-3虽按时来了仍不接受,会被标记为*UNKNOWN*,min:max也可定义为U:U表示未定、随便,是什么值都保存)
RRA:CF:cf arguments(对DS如何做聚合(归档),一个DS可聚合多次,如5s、50s、500s各一次,CF(consolidation function有AVERAGE、MIN、MAX、LAST),cf arguments有xff:steps:rows)
注:cf arguments(xff:steps:rows,xff定义PDP中有多大比例为*UNKNOWN*,只要小于这个比例rrd仍能猜测推断出PDP进而得出CDP,否则就认为CDP为*UNKNOWN*,例如定义为0.5则是一半为*UNKNOWN*,聚合后的值(RRA,CDP)未必是精确的;steps表示对几个PDP组合起来做聚合;rows表示共保存多少个聚合的结果,如5s一个PDP,steps为10个(每10个PDP一平均则是每50s一个平均),若要保存2天的rows的值为86400*2/50=3456)
[root@node1 ~]# rrdtool create test.rrd --step 5 DS:testds:GAUGE:8:0:U RRA:AVERAGE:0.5:1:17280 RRA:AVERAGE:0.5:10:3456 RRA:AVERAGE:0.5:100:1210(若不指--step 5则默认300s接受一个值,分别对每5s、50s、500s的PDP做聚合,17280为rows保存一天的值86400/5,3456为保存两天的86400*2/50,1210为一周的86400*7/500)
注:在linux中random的值最小0最大32768
[root@node1 ~]# ll –h(test.rrd此文件大小固定,不会再增长)
-rw-r--r-- 1 root root 173K Dec 19 10:42 test.rrd
[root@node1 ~]# rrdtool info test.rrd
filename = "test.rrd"
rrd_version = "0003"
step = 5
last_update = 1450492925
header_size = 928
ds[testds].index = 0
ds[testds].type = "GAUGE"
……
rra[0].cf = "AVERAGE"
rra[0].rows = 17280
……
rra[1].cf = "AVERAGE"
rra[1].rows = 3456
……
rra[2].cf = "AVERAGE"
rra[2].rows = 1210
……
rra[2].cdp_prep[0].unknown_datapoints = 85
[root@node1 ~]# man rrdupdate(实现在指定的时间内向rrdcreate所创建的数据库文件提供数据,Store a new set of values into the RRD)
#rrdtool {update | updatev} filename [--template|-t ds-name[:ds-name]...] [--daemon address] [--]N|timestamp:value[:value...] at-timestamp@value[:value...] [timestamp:value[:value...] ...](filename为rrdtool create创建的数据库文件;--template或-t,对于某个rrd数据库文件它有可能包含多个DS,提供数据时要与DS的次序相对应,若对应则可不使用-t或 --template指定,若不对应要先指定好DS的先后次序再提供数据,看以下举例;N表示当下的时间,timestamp为指定时间戳)
举例:
#rrdtool update test.rrd timestamp:32(往一个数据源里填数据)
#rrdtool update test.rrd –t DS1:DS2 N:32:24(有两个数据源时,如果给定数据的次序与数据源不一样时要使用-t指定新的次序,32表示往第1个DS上填数据,24表示往第二个DS上填数据)
[root@node1 ~]# rrdtool update test.rrd N:$RANDOM
[root@node1 ~]# man rrdfetch(Fetch datafrom an RRD)
#rrdtool fetch filename CF [--resolution|-rresolution]
[root@node1 ~]# rrdtool fetch test.rrd AVERAGE(有很多时间槽已放置好等待往里写数据,nan为*UNKNOWN*没有任何对应的数据,要不停的提供数据才能查看出来)
1450507880: nan
1450507885: nan
1450507890: nan
1450507895: nan
……
[root@node1 ~]# vim genval.sh
-------------script start-------------
#!/bin/bash
#
while true;do
rrdtool update test.rrd N:$RANDOM
sleep 5
done
---------------script end---------------
[root@node1 ~]# chmod 755 genval.sh
[root@node1 ~]# bash -n genval.sh
[root@node1 ~]# bash -x genval.sh
[root@node1 ~]# rrdtool fetch test.rrd AVERAGE -r 5(在另一终端查看,-r|--resolution表示解析度)
……
1450508380: nan
1450508385: 1.3910805351e+04
1450508390: 2.8867697364e+04
1450508395: 1.9593393102e+04
1450508400: 1.1876438942e+04
1450508405: 3.0991827430e+03
1450508410: nan
[root@node1 ~]# rrdtool fetch test.rrd AVERAGE -r 50
1450508400: nan
1450508450: 1.7164162937e+04
1450508500: nan
[root@node1 ~]# rrdtool fetch test.rrd AVERAGE -r 10(不存在10这个解析度,则会列出高解析度的数据)
以上基于填充好的数据就可画图,能看出走势,rrdtool是个强大的绘图引擎可直接在填充数据的基础上画图
[root@node1 ~]# man rrdgraph(Round RobinDatabase tool graphing functions)
#rrdtool graph|graphv filename [option...] [data definition ...] [data calculation ...] [variable definition...] [graph element ...] [print element ...](filename不是test.rrd数据库文件而是生成图片的文件名,生成的图像格式默认是png;option是绘图选项;data definition定义如何取数据,取的是哪个RRA,5s|50s|500s的平均,要定义好;data calculation取得的数据是否做运算;print element显示图形)
注:
option有time range、labels、size、limits、X-Axis、Y-Axis、miscellaneous:
关于time range:
-s|--start time(rrd保存的是时间序列的数据,指定从什么时候开始绘图到什么时候结束,如下图,横轴0表示start time,箭头处表示当前时刻end time)
-e|--end time
-S|--step seconds(解析度)
关于labels:
-t|--title string(标题,如图Localhost – tcp connections)
-v|--vertical-label string(垂直标签,如图ConnectionNumbers)
关于size:
-w|--width pixels(宽度,图像占据的像素)
-h|--height pixels(高度)
-j|--only-graph(只绘预览图,指甲盖大小的图)、
-D|--full-size-mode(图像可自动绽放)
关于limits(图形绘制成多大,指定上下限):
-u|--upper-limit value(上限,图像会根据上限自动把刻度修改,如图若最大到10000相应的最大刻度会自动变为10000,中间的数再进行平均,如果值过大则显示不精确)
-l|--lower-limit value(下限,如图如果值接近0则不会显示)
-r|--rigid(当指定好上下限时若使用此项就以上下限为准固定显示,不允许自动绽放)
-A|--alt-autoscale(自动绽放,指定上下限后仍可自动绽放)
-J|--alt-autoscale-min(只自动绽放最小值)
-M|--alt-autoscale-max(只自动绽放最大值,通常用此项)
-N|--no-gridfit(不显示网格线)
关于X-Axis:
-x|--x-grid GTM:GST:MTM:MST:LTM:LST:LPR:LFM(GTM:GST表示基准网格线多长时间的跨度显示,如图中背景上灰色的线是基准网格线;MTM:MST表示主网格线以多长时间为单位显示,如图中背景上红色的线是主网格线;LTM:LST表示横轴的标签label每隔多久显示一次;LPR:LFM表示时间标签的显示格式,如图中横轴处的Mon 18:00)
注:网格线分主网格线(红色)和基准网络线(灰色)
-x|--x-grid none
举例:--x-grid MINUTE:10:HOUR:1:HOUR:4:0:%X
关于Y-Axis:
-y|--ygrid grid step:label factor(step:label纵轴标签的步进,factor表示每隔多长显示一个标签)
-y|--y-grid none
-Y|--alt-y-grid
关于miscellaneous其它、杂项:
-c|--color COLORTAG#rrggbb[aa](不用改,有默认值,COLORTAG有BACK(background)、CANVAS(画布的颜色)、SHADEA(左边和上边边界线的颜色)、SHADEB(右边和下边边界线的颜色)、GRID和MGRID(主风格线的颜色)、FONT(字体)、AXIS(坐标轴)、FRAME(边框)、ARROW(箭头))
-n|--font FONTTAG:size:[font](若指定中文字体会显示中文,要到微软系统上复制,一般只支持黑体,FONTTAG指定字体名字,[font]指定字体路径)
-R|--font-render-mode {nomal,light,mono}(字体格式)
-a|--imgformat PNG|SVG|EPS|PDF(常用,图片输出格式,默认是PNG)
-W|--watermark string(图片的背景水印)
data definition获取数据的三种格式:
格式一(常用):DEF:vname=rrdfile:ds-name:CF[:step=step][:start=time][:end=time](vname变量名字,只能包含数字字母,最长不能超过255个字符)
格式二:CDEF:vname=RPN expression
格式三:VDEF:vname=RPN expression
注:可绘线条图LINE,面积图AREA,线条是粗是细都可指定
LINE[width]:value[#color][:[legend][:STACK]](width表示线条粗细,1最细3最粗;value以变量的名称绘图;#color表示线条颜色,若不定义线条将不可见)
[root@node1 ~]# rrdtool graph a.png --step 5 -s 1450507850 -t Test -v Vtest DEF:vtest=test.rrd:testds:AVERAGELINE1:vtest#ff0000:"testline"(将图像传至win下打开,-s1450507850是复制的#rrdtool fetch test.rrd AVERAGE –r 5中查询到的没有数据的时间槽)
497x173
注:cacti是个展示工具,支持模板,很强大,支持rrdtool命令的前端工具,把rrdtool绘的图通过网页展示出来,使用rrdtool命令绘图很复杂,cacti提供了接口,在接口上提供了很多选项使之绘图展示变的简单
[root@node1 ~]# rrdtool graph a.png -s 1450513215 DEF:vartest1=/root/test.rrd:testds:AVERAGE:step=5 DEF:vartest2=/root/test.rrd:testds:AVERAGE:step=50 LINE1:vartest1#ff0000:"testline" LINE1:vartest2#00ff00:"testline2"(将两张图合成一张)
481x155
举例:监控mysql-server每3秒、30秒发生的查询次数的平均值、最大值和当前值
[root@node1 ~]# rrdtool create mysql.rrd --step 3 DS:myselect:COUNTER:5:0:U RRA:AVERAGE:0.5:1:28800RRA:AVERAGE:0.5:10:2880 RRA:MAX:0.5:10:2880 RRA:LAST:0.5:10:2880
[root@node1 ~]# ll -h mysql.rrd
-rw-r--r-- 1 root root 294K Dec 19 18:23mysql.rrd
[root@node1 ~]# mysql --batch -e "SHOW GLOBAL STATUS LIKE 'Com_select'"
Variable_name Value
Com_select 1
[root@node1 ~]# mysql --batch -e "SHOW GLOBAL STATUS LIKE 'Com_select'" | awk '/Com_select/{print $2}'
2
[root@node1 ~]# vim getselect.sh
--------------script start-----------------
#!/bin/bash
#
while true;do
SELECT=`mysql --batch -e "SHOW GLOBAL STATUS LIKE 'Com_select'" | awk '/Com_select/{print $2}'`
rrdtool update mysql.rrd N:$SELECT
sleep 3
done
-------------script end----------------------
[root@node1 ~]# chmod 755 getselect.sh
[root@node1 ~]# bash -n getselect.sh
[root@node1 ~]# bash -x getselect.sh
[root@node1 ~]# mysql
mysql> SHOW DATABASES;
mysql> CREATE DATABASE testdb;
Query OK, 1 row affected (10.00 sec)
mysql> USE testdb;
Database changed
mysql> CREATE TABLE tb1 (ID INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,NAME CHAR(50) NOT NULL);
Query OK, 0 rows affected (0.07 sec)
[root@node1 ~]# vim insert.sh
--------------script start------------------
#!/bin/bash
#
for I in {1..200000};do
mysql -e "INSERT INTO testdb.tb1(NAME) VALUES('stu$I')"
mysql-e "SELECT * FROM testdb.tb1" &> /dev/null
done
------------script end----------------
[root@node1 ~]# chmod 755 insert.sh
[root@node1 ~]# bash -n insert.sh
[root@node1 ~]# bash -x insert.sh
[root@node1 ~]# rrdtool fetch mysql.rrd AVERAGE -r 3
[root@node1 ~]# rrdtool fetch mysql.rrd MAX -r 3
[root@node1 ~]# rrdtool fetch mysql.rrd MAX -r 30
[root@node1 ~]# rrdtool fetch mysql.rrd LAST -r 30
[root@node1 ~]# rrdtool graph mysql.png -s 1450522503 -t "mysql server" -v "select/3"DEF:select3=mysql.rrd:myselect:AVERAGE:step=3LINE1:select3#ff0000:"SELECT"
497x173
[root@node1 ~]# rrdtool graph mysql.png -s 1450522503 -t "mysql server" -v "select/3" DEF:select30=mysql.rrd:myselect:AVERAGE:step=30 LINE1:select30#ff0000:"SELECT"
497x173
增加显示最大值和当前值:GPRINT:vname:CF:format
[root@node1 ~]# rrdtool graph mysql.png -s 1450522503 -t "mysql server" -v "select/30" DEF:select30=mysql.rrd:myselect:AVERAGE:step=30 DEF:last30=mysql.rrd:myselect:LAST:step=30 LINE1:select30#ff0000:"SELECT" GPRINT:last30:LAST:"CURRENT\:%10.2lf"
497x173
[root@node1 ~]# rrdtool graph mysql.png -s 1450522503 -t "mysql server" -v "select/30" DEF:select30=mysql.rrd:myselect:AVERAGE:step=30 DEF:max30=mysql.rrd:myselect:MAX:step=30 DEF:last30=mysql.rrd:myselect:LAST:step=30 LINE1:select30#ff0000:"SELECT"GPRINT:max30:MAX:"MAXIMUM\: %5.2lf" GPRINT:last30:LAST:"CURRENT\: %5.2lf"
497x173
理解以上内容,操作cacti就简单多了,写些脚本使用cacti就可做些有意义的事了,可将mysql的语句整合在一起,select、update、insert into在一个图上多画几条线(在一个图上观察所有的走势),将这些写成通用脚本,通过snmp获取远程mysql-server上的数据,要监视哪台server传一个参数即可,用cacti定义制图模板、数据获取模板以通用的机制导入到其它server使用