返回文章列表

SNMP效能資料收集與RRDTool圖表繪製

本文探討如何使用 SNMP 協定收集網路裝置的效能資料,並利用 RRDTool 儲存和繪製這些資料。文章涵蓋 SNMP 查詢、RRDTool 資料函式庫建立、資料寫入與讀取,以及圖表生成等關鍵步驟,並提供 Python 程式碼範例,方便讀者快速上手。

網路管理 效能監控

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]))

程式碼解析

  1. 初始化CommandGenerator物件cg = cmdgen.CommandGenerator()用於生成SNMP命令。
  2. 迭代系統列表:對每個系統,設定SNMP社群資料(comm_data)和傳輸目標(transport)。
  3. 執行SNMP GET命令:對每個檢查,使用cg.getCmd()方法執行SNMP GET命令,取得OID的值。
  4. 處理結果:如果沒有錯誤,則列印系統描述、檢查描述和結果值。

使用RRDTool儲存資料

RRDTool是一種用於圖形化監控資料的應用程式,已成為業界標準。我們將探討RRDTool的資料函式庫結構、如何新增資料、檢索資料,以及資料繪圖命令和技術。

RRDTool簡介

RRDTool提供了三種主要功能:

  1. 資料函式倉管理系統:允許儲存和檢索資料。
  2. 資料操作:執行複雜的資料操作任務,如資料重取樣和速率計算。
  3. 圖形生成:建立包含多個資料來源資料的複雜圖形。
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函式用於計算一段時間內的平均值,提供了一個總體趨勢的檢視。
    • 這對於觀察長期趨勢非常有用,如平均網路流量或平均系統負載。
  • MINMAX分別選擇資料集中的最小值或最大值並儲存它。

    內容解密:

    • 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資料函式庫檔案的路徑。
  • <資料來源>:資料來源的名稱。
  • <整合函式>:用於資料整合的函式,例如AVERAGEMAXMIN等。

擴充套件資料選擇器語法

資料選擇器語法可以擴充套件以指定開始時間、結束時間和解析度:

DEF:<變數名稱>=<RRD檔案>:<資料來源>:<整合函式>:step=<步長>:start=<開始時間>:end=<結束時間>

例如:

$ rrdtool graph packets.png \
> DEF:packetrate=interface.rrd:packets:AVERAGE:step=300:start=1273008600:end=1273016400 \
> LINE2:packetrate#c0c0c0

繪圖命令語法

繪圖命令的基本語法是:

<繪圖型別>:<變數名稱><#顏色>:<圖例>
  • <繪圖型別>:可以是LINEAREA等。
  • <變數名稱>:之前定義的變數名稱。
  • <#顏色>: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

內容解密:

  1. CDEF:kbps=packetrate,4096,*,8,*:這行命令定義了一個名為kbps的新變數,它是透過將packetrate乘以4096(一個封包的位元組數)和8(一個位元組的位元數)來計算的,從而將封包速率轉換為每秒的位元數。
  2. LINE2:kbps#c0c0c0:這行命令繪製了一個寬度為2的線條,代表kbps變數,顏色為#c0c0c0。

圖表自定義與轉換

預設情況下,RRDTool會自動在x軸上列印時間戳,但在y軸上顯示的值可能不夠直觀。為了提高可讀性,可以對資料進行轉換,例如將封包速率轉換為每秒的位元數。

使用CDEF進行資料轉換

CDEF允許定義資料轉換函式,可以應用於任何資料選擇器變數。在上述範例中,我們使用CDEF將封包速率轉換為每秒的位元數。