SNMP 協定廣泛應用於網路裝置的效能監控,它允許我們從裝置中讀取各種效能指標。RRDTool 則提供了一個高效的機制,用於儲存和視覺化這些時間序列資料。結合 SNMP 和 RRDTool,我們可以建立一個完整的效能監控系統。本文將逐步講解如何使用 Python 實作 SNMP 資料收集,並使用 RRDTool 進行資料儲存、讀取和圖表繪製。首先,我們會使用 Python 的 SNMP 函式庫查詢裝置的效能資料,接著介紹 RRDTool 的資料函式庫結構和操作方法,包含資料函式庫的建立、更新和讀取。最後,我們將示範如何使用 RRDTool 的圖表功能,將收集到的效能資料以視覺化的方式呈現,方便分析和監控。
使用SNMP讀取與收集效能資料
實作SNMP讀取功能
為了實作SNMP讀取功能,我們需要在應用程式中迭代所有系統列表,並對每個系統迭代所有定義的檢查。對每個檢查執行SNMP GET命令,並將結果儲存在相同的資料結構中。
查詢所有定義的SNMP物件
以下是實作query_all_systems()方法的程式碼範例:
def query_all_systems(self):
cg = cmdgen.CommandGenerator()
for system in self.systems.values():
comm_data = cmdgen.CommunityData('my-manager', system['communityro'])
transport = cmdgen.UdpTransportTarget((system['address'], system['port']))
for check in system['checks'].values():
oid = check['oid']
errInd, errStatus, errIdx, result = cg.getCmd(comm_data, transport, oid)
if not errInd and not errStatus:
print "%s/%s -> %s" % (system['description'],
check['description'],
str(result[0][1]))
程式碼解析
- 初始化CommandGenerator物件:
cg = cmdgen.CommandGenerator()用於生成SNMP命令。 - 迭代系統列表:對每個系統,設定SNMP社群資料(
comm_data)和傳輸目標(transport)。 - 執行SNMP GET命令:對每個檢查,使用
cg.getCmd()方法執行SNMP GET命令,取得OID的值。 - 處理結果:如果沒有錯誤,則列印系統描述、檢查描述和結果值。
使用RRDTool儲存資料
RRDTool是一種用於圖形化監控資料的應用程式,已成為業界標準。我們將探討RRDTool的資料函式庫結構、如何新增資料、檢索資料,以及資料繪圖命令和技術。
RRDTool簡介
RRDTool提供了三種主要功能:
- 資料函式倉管理系統:允許儲存和檢索資料。
- 資料操作:執行複雜的資料操作任務,如資料重取樣和速率計算。
- 圖形生成:建立包含多個資料來源資料的複雜圖形。
RRD資料函式庫結構
RRD資料函式庫具有固定的大小,這意味著資料函式庫大小在初始化時已知,並且永遠不會改變。新記錄會覆寫舊資料。以下是一個簡化的RRD結構示意圖:
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title SNMP效能資料收集與RRDTool圖表繪製
package "資料庫架構" {
package "應用層" {
component [連線池] as pool
component [ORM 框架] as orm
}
package "資料庫引擎" {
component [查詢解析器] as parser
component [優化器] as optimizer
component [執行引擎] as executor
}
package "儲存層" {
database [主資料庫] as master
database [讀取副本] as replica
database [快取層] as cache
}
}
pool --> orm : 管理連線
orm --> parser : SQL 查詢
parser --> optimizer : 解析樹
optimizer --> executor : 執行計畫
executor --> master : 寫入操作
executor --> replica : 讀取操作
cache --> executor : 快取命中
master --> replica : 資料同步
note right of cache
Redis/Memcached
減少資料庫負載
end note
@enduml
此圖示展示了RRD資料函式庫的基本運作原理。
結合RRDTool與應用程式
我們將把RRDTool資料函式庫整合到我們的應用程式中,用於儲存和檢索監控資料,並利用其圖形生成功能來視覺化資料。
使用SNMP讀取與收集效能資料
瞭解RRDTool的基本結構與應用
在效能監控領域中,Round Robin Database(RRD)是一種專門用於儲存時間序列資料的資料函式庫。RRD的設計理念是將資料儲存在固定數量的儲存格中,當所有儲存格都被寫入資料後,新資料將會覆寫最舊的資料,從而實作迴圈寫入的功能。
RRD的結構與運作原理
假設我們初始化了一個可容納12筆記錄的資料函式庫,每筆記錄儲存在各自的儲存格中。當資料函式庫為空時,我們開始將資料寫入第一個儲存格,並更新指標以指向最後寫入的儲存格。圖1-3展示了已經寫入6筆記錄的狀態(以陰影方塊表示)。指標目前位於第6個儲存格,因此當下一次寫入指令到來時,資料將被寫入第7個儲存格,並相應地更新指標。一旦到達最後一個儲存格(第12個儲存格),此過程將重新從第1個儲存格開始。
RRD的重要特性
RRD的主要目的是儲存效能資料,因此不需要維護不同資料表之間的複雜關係。事實上,RRD中沒有傳統意義上的表格,只有個別的資料來源(Data Sources, DSs)。每個記錄都需要標記時間戳,並且在建立新資料函式庫時需要指定取樣率,即資料寫入資料函式庫的頻率。預設值為300秒(5分鐘),但可根據需要進行調整。
儲存在RRD中的資料被稱為Round Robin Archive(RRA)。RRA透過應用可用的整合函式(Consolidation Function, CF)來整合從DS收集到的資料。可以指定四種CF(平均值、最小值、最大值和最後一個值)中的一種來應用於一定數量的實際資料記錄。結果儲存在迴圈的“表格”中。可以根據不同的粒度在資料函式庫中儲存多個RRA。
從Python程式使用RRDTool
在建立RRDTool資料函式庫之前,我們先來看看提供RRDTool API的Python模組。我們在本章中將使用的模組稱為Python RRDTool,可以在http://sourceforge.net/projects/py-rrdtool/下載。
安裝Python RRDTool模組
大多數Linux發行版都預先封裝了這個模組,可以使用標準的套件管理工具進行安裝。例如,在Fedora系統上,您可以執行以下命令來安裝Python RRDTool模組:
$ sudo yum install rrdtool-python
在根據Debian的系統上,安裝命令是:
$ sudo apt-get install python-rrd
安裝完成後,您可以驗證安裝是否成功:
$ python
Python 2.6.2 (r262:71600, Jan 25 2010, 18:46:45)
[GCC 4.4.2 20091222 (Red Hat 4.4.2-20)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import rrdtool
>>> rrdtool.__version__
'$Revision: 1.14 $'
>>>
建立Round Robin資料函式庫
讓我們從建立一個簡單的資料函式庫開始。我們要建立的資料函式庫將會有一個資料來源,這是一個簡單的遞增計數器:計數器的值隨著時間增加。一個典型的例子是透過介面傳輸的位元組數。每5分鐘進行一次讀取。
我們還將定義兩個RRA。一個是用於對單一讀取進行平均,這實際上指示RRDTool儲存實際值,另一個則對六次測量進行平均。以下是建立此資料函式庫的命令列工具語法範例:
$ rrdtool create interface.rrd \
> DS:packets:COUNTER:600:U:U \
> RRA:AVERAGE:0.5:1:288 \
> RRA:AVERAGE:0.5:6:336
同樣,您可以使用Python模組建立相同的資料函式庫:
>>> import rrdtool
>>> rrdtool.create('interface.rrd',
... 'DS:packets:COUNTER:600:U:U',
... 'RRA:AVERAGE:0.5:1:288',
... 'RRA:AVERAGE:0.5:6:336')
>>>
資料來源(DS)的定義結構
DS定義行的結構是:
DS:<名稱>:<DS型別>:<心跳>:<下限>:<上限>
- 名稱欄位是您為這個特定的資料來源命名的名稱。由於RRD允許您儲存來自多個資料來源的資料,因此您必須為每個資料來源提供一個唯一的名稱,以便稍後存取它。
- DS型別(或資料來源型別)欄位指示將提供給此資料來源的資料型別。有四種型別可用:COUNTER、GAUGE、DERIVE和ABSOLUTE。
資料來源型別的詳細說明
- COUNTER型別意味著測量值隨著時間而增加。要計算速率,RRDTool會從當前測量值中減去最後一個值,然後除以測量步長(或取樣率)以獲得速率數字。如果結果為負數,則需要補償計數器溢位。典型的用途是監控不斷增加的計數器,例如透過介面傳輸的總位元組數。
內容解密:
- COUNTER型別的設計目的是追蹤隨時間不斷增加的值,如網路介面傳輸的總位元組數。
- RRDTool透過計算當前值與前一次值之間的差異,並除以時間間隔來得出速率。
- 如果計算出的速率為負,可能需要調整以補償計數器的重啟或溢位。
- DERIVE型別與COUNTER類別似,但它也允許負速率。可以用於檢查網站接收HTTP請求的速率。如果圖表在零線上方,表示請求越來越多;如果低於零線,則表示網站正在變得不受歡迎。
內容解密:
- DERIVE型別提供了比COUNTER更靈活的速率計算,能夠處理值的減少。
- 這對於監測如HTTP請求速率等指標非常有用,能夠顯示出請求量的變化趨勢。
- ABSOLUTE型別表示每次讀取測量值時計數器都會重置。它告訴RRDTool不要執行減法運算,直接使用測量值作為速率。
內容解密:
- ABSOLUTE適用於每次測量後重置的計數器,如某些系統負載平均值的測量。
- 這種型別直接使用測量值作為速率,無需進行差分計算。
- GAUGE型別意味著測量值就是速率值,不需要進行任何計算。例如,CPU使用率和溫度感測器讀數是GAUGE型別的良好候選者。
內容解密:
- GAUGE型別直接代表了當前的測量值或狀態,如即時的CPU使用率或溫度。
- 這種型別無需進行額外的計算,直接儲存測量值。
RRA定義結構
RRA定義結構是:
RRA:<整合函式>:<XFiles因子>:<資料集>:<樣本數>
- 整合函式定義了將對資料集值應用的數學函式。資料集引數是從資料來源接收到的最後一批測量值。在我們的範例中,我們有兩個RRA,一個只有單一讀取在資料集中,另一個有六次測量在資料集中。可用的整合函式有AVERAGE、MIN、MAX和LAST。
整合函式的詳細說明
- AVERAGE指示RRDTool計算資料集的平均值並儲存它。
內容解密:
- AVERAGE函式用於計算一段時間內的平均值,提供了一個總體趨勢的檢視。
- 這對於觀察長期趨勢非常有用,如平均網路流量或平均系統負載。
- MIN和MAX分別選擇資料集中的最小值或最大值並儲存它。
內容解密:
- MIN和MAX函式能夠突出資料中的極端值,如一天中的最高或最低溫度,或網路延遲的最大或最小值。
- 這對於識別系統或網路中的異常或極端情況非常有幫助。
- LAST指示使用資料集中的最後一個條目。
內容解密:
- LAST函式簡單地儲存了最近一次的測量值,這對於觀察即時狀態或最近的變化非常有用。
- 這可以用於監控即時的系統狀態,如當前記憶體使用率或最新的錯誤率。
使用 SNMP 讀取和收集效能資料
Round Robin Database(RRD)的資料儲存與讀取機制
RRDTool 是一種專門用於儲存和處理時間序列資料的工具,特別適用於監控系統的效能資料收集。RRDTool 的核心是 Round Robin Archive(RRA),它以迴圈的方式儲存資料,確保資料函式庫的大小保持固定。
建立 RRD 資料函式庫
建立 RRD 資料函式庫時,需要定義資料來源(Data Source, DS)、資料儲存的時間粒度(step)、以及多個 RRA。每個 RRA 對應不同的資料儲存粒度和儲存時間。
rrdtool create interface.rrd --step 300 \
DS:packets:COUNTER:600:U:U \
RRA:AVERAGE:0.5:1:288 \
RRA:AVERAGE:0.5:6:336
內容解密:
rrdtool create:建立 RRD 資料函式庫的指令。interface.rrd:建立的資料函式庫檔案名稱。--step 300:定義資料更新的時間間隔為 300 秒。DS:packets:COUNTER:600:U:U:定義一個名為packets的資料來源,型別為COUNTER,表示這是一個累計計數器。600表示如果 600 秒內沒有更新,資料將被視為未知(unknown)。U:U表示該資料來源的有效值範圍無限制。RRA:AVERAGE:0.5:1:288:定義第一個 RRA,儲存 288 筆資料(對應 24 小時內的資料,每 5 分鐘一筆),計算平均值,並允許 50% 的資料缺失。RRA:AVERAGE:0.5:6:336:定義第二個 RRA,儲存 336 筆資料(對應 7 天內的資料,每 30 分鐘一筆),同樣計算平均值,並允許 50% 的資料缺失。
寫入與讀取 RRD 資料函式庫中的資料
寫入資料
寫入資料到 RRD 資料函式庫非常簡單,使用 update 命令並提供時間戳和對應的資料值。
rrdtool update interface.rrd 1273008486:10
rrdtool update interface.rrd 1273008786:15
rrdtool update interface.rrd N:25
內容解密:
rrdtool update:更新 RRD 資料函式庫的指令。interface.rrd:要更新的 RRD 資料函式庫檔案。1273008486:10:時間戳(秒數,自 Unix 紀元開始計算)和對應的資料值。N:25:使用N表示當前時間,並提供對應的資料值。
使用 Python 更新 RRD 資料函式庫
import rrdtool
for i in range(20):
rrdtool.update('interface.rrd', '%d:%d' % (1273010886 + (1+i)*300, i*10+200))
內容解密:
- 這段 Python 程式碼使用
rrdtool模組更新 RRD 資料函式庫,每隔 300 秒插入一個新的資料值,資料值每次增加 10。
從 RRD 資料函式庫讀取資料
可以使用 fetch 命令從 RRD 資料函式庫讀取資料。
rrdtool fetch interface.rrd AVERAGE
內容解密:
rrdtool fetch:從 RRD 資料函式庫讀取資料的指令。interface.rrd:要讀取的 RRD 資料函式庫檔案。AVERAGE:指定讀取的整合函式為平均值。
以不同解析度讀取資料
可以指定解析度來讀取資料,例如以 1800 秒(30 分鐘)為單位讀取。
rrdtool fetch interface.rrd AVERAGE -r 1800
內容解密:
-r 1800:指定讀取資料的解析度為 1800 秒。
使用 Python 從 RRD 資料函式庫讀取資料
import rrdtool
for i in rrdtool.fetch('interface.rrd', 'AVERAGE'):
print(i)
內容解密:
- 這段 Python 程式碼使用
rrdtool.fetch方法讀取 RRD 資料函式庫中的資料,並列印出結果。
使用RRDTool繪製效能圖表
RRDTool是一個強大的工具,用於收集和繪製效能資料。它的圖表功能非常受歡迎,能夠輕鬆生成專業的效能圖表。
基本圖表繪製命令
基本的圖表繪製命令與資料提取命令相似:
$ rrdtool graph packets.png --start 1273008600 --end 1273016400 --step 300 \
> DEF:packetrate=interface.rrd:packets:AVERAGE \
> LINE2:packetrate#c0c0c0
這個命令會生成一個簡單的效能圖表,如圖1-4所示。
圖表命令引數解析
圖表命令的第一部分是輸出檔案名稱,接著是可選的時間範圍和解析度設定。解析度以秒為單位表示。
資料選擇器(DEF)語法
資料選擇器語法的格式如下:
DEF:<變數名稱>=<RRD檔案>:<資料來源>:<整合函式>
<變數名稱>:用於儲存從RRDTool資料函式庫檢索出的資料的變數名稱。<RRD檔案>:RRDTool資料函式庫檔案的路徑。<資料來源>:資料來源的名稱。<整合函式>:用於資料整合的函式,例如AVERAGE、MAX、MIN等。
擴充套件資料選擇器語法
資料選擇器語法可以擴充套件以指定開始時間、結束時間和解析度:
DEF:<變數名稱>=<RRD檔案>:<資料來源>:<整合函式>:step=<步長>:start=<開始時間>:end=<結束時間>
例如:
$ rrdtool graph packets.png \
> DEF:packetrate=interface.rrd:packets:AVERAGE:step=300:start=1273008600:end=1273016400 \
> LINE2:packetrate#c0c0c0
繪圖命令語法
繪圖命令的基本語法是:
<繪圖型別>:<變數名稱><#顏色>:<圖例>
<繪圖型別>:可以是LINE或AREA等。<變數名稱>:之前定義的變數名稱。<#顏色>:HTML顏色格式的字串。<圖例>:顯示在圖表底部的文字。
繪圖範例
$ rrdtool graph kbps.png --step 300 --start 1273105800 --end 1273114200 \
> DEF:packetrate=interface.rrd:packets:AVERAGE \
> CDEF:kbps=packetrate,4096,*,8,* \
> LINE2:kbps#c0c0c0
內容解密:
CDEF:kbps=packetrate,4096,*,8,*:這行命令定義了一個名為kbps的新變數,它是透過將packetrate乘以4096(一個封包的位元組數)和8(一個位元組的位元數)來計算的,從而將封包速率轉換為每秒的位元數。LINE2:kbps#c0c0c0:這行命令繪製了一個寬度為2的線條,代表kbps變數,顏色為#c0c0c0。
圖表自定義與轉換
預設情況下,RRDTool會自動在x軸上列印時間戳,但在y軸上顯示的值可能不夠直觀。為了提高可讀性,可以對資料進行轉換,例如將封包速率轉換為每秒的位元數。
使用CDEF進行資料轉換
CDEF允許定義資料轉換函式,可以應用於任何資料選擇器變數。在上述範例中,我們使用CDEF將封包速率轉換為每秒的位元數。