Cacti分佈式監控

1、爲何要作分佈式Cacti?

現有的CACTI服務器只有一臺,被監控的網絡設備有332臺,所以每5分鐘須要對332個節點進行一次數據採集,9518個RRD文件進行寫入,致使磁盤出現了嚴重的IO瓶頸,導致在WEB界面上的操做速度慢的讓人沒法忍受,嚴重的影響了Cacti平常管理。所以決定將其改造爲分佈 式。這樣,一方面能夠解決性能問題,另外一方面能夠解決異網內無公網IP地址設備的監控。php

2、分佈式Cacti的架構分析

整個分佈式Cacti由三臺服務器組成:數據庫

一、cacti78.cm3用來採集CDN的數據,同時接收CDN二層設備被動監控的數據;服務器

主動採集CDN設備的RRD數據存放在/home/cacti/rra/cacti78.cm3目錄下網絡

被動採集CDN設備的RRD數據存放在/home/cacti/rra/passive目錄下架構

二、cacti79.cm3用來採集主站的數據。分佈式

採主站的RRD數據存放在/home/cacti/rra/cacti79.cm3目錄下ide

三、cacti80.cm3用來作WEB界面展現;函數

生成圖像時用到的RRD數據經過NFS,將cacti78.cm3和cacti79.cm3採集的數據加載到本地。性能

3、分佈式Cacti數據庫分析

因爲Cacti的數據庫主要是用來存儲配置信息的,所以個人第一個想法就是用一個數據庫來支撐三臺Cacti,這看起來是個不錯的想法,因而 就按這種方法搭建了起了分佈式Cacti。當一切配置完成以後,繪出的圖讓我失望了,開始時是斷斷續續,到了後面乾脆就沒了圖像。一開始我並 沒有想明白是怎麼回事,就處處查資料,結果好不容易找到了一個方法,就是在crontab裏的按期執行命令:php poller.php命令後面加個「--force」參數,強制執行這個命令,這 次讓我看到了一點點的但願,終於能夠繪出斷斷續續的圖來。可爲何會斷斷續續的繪圖呢?fetch

經過閱讀源代碼,我發現原來Cacti每次採集數據的時候,不只僅要讀數據庫,還要寫數據庫。具體的要寫哪些表呢?第一個就是settings表的name字段名爲poller_lastrun的行,該行後 面的value字 段存儲的是上次進行數據採集的時間截,每當採集數據以前,都會讀取這個值,並用當前時間截減去上次時間截,並判斷是否爲300秒(即數據採集間隔5分鐘),若是爲300秒,則進行數據採集,並將當前時間截 寫入數據庫;不然不進行數據採集。加了「--force」參數就是爲了避免進行採集間隔的判斷,直接採集數據,由於有兩臺採集服務器同時寫表,致使時間不對。 加了該參數以後圖是繪出來了,但是不連續。

爲了解決圖不連續的問題,我再次深刻研究,發現Cacti除了寫這個settings的表,還寫了名爲poller的相關表,這些表是用來存儲poller須要的一些臨時數據的。因爲兩個採集服務器同時對這些表進行寫和刪除操盤,形成數據混亂。

基於以上分析,分佈式Cacti只能擁有各自的數據庫,而不能共享同一個庫。所以採用三個庫,一主兩從的方法。cacti80.cm3上的數據庫爲主庫,cacti78.cm三、cacti79.cm3上的庫爲從庫,咱們 平時的配置修改操做都在cacti80.cm3上,這個庫的數據變化都會同步到其它兩個庫上,而對每次數據採集都會寫入數據的幾個表則不進行同步, 這幾個表分別是:poller、poller_command、poller_output、poller_reindex、poller_time。

4、如何讓兩臺Cacti 採集服務器進行數據採集的分工?

爲了讓兩臺服務器(cacti78.cm三、cacti79.cm3)進行數據採集的分工合做,咱們首先須要改造頁面源代碼,就是當咱們新加一臺被動監控設備時,要區 別這臺設備由哪臺服務器來採集數據。修改後的源代碼以下圖,從下圖的「Choose Spine Agent」後面的下拉列表中便可以選擇用哪臺服務器採集數據。咱們規 定,全部CDN的 設備均選擇「cacti78.cm3」這臺服務器來採集數據;主站的設備均選擇「cacti79.cm3」這臺服務器來採集數據;被動監控均選擇「passive」,表示不採集數據。該下拉列表將直接更改host表的disabled字段的值,因爲該字段只支持兩個字符,所以須要修改表結構,我修改的是支持20個字符。

因爲每一個採集服務器採集的數據必須放在不一樣目錄下,以便經過NFS加載到WEB服務器(cacti80.cm3)上。所以,還須要 修改源代碼lib/function.php,以便建立圖片時生成的數據源路徑分別屬於各自的目錄,好比選擇cacti78.cm3採集數據,則建立圖片 時生成的數據源在/home/cacti/rra/cacti78.cm3目錄下;選擇cacti79.cm3採集數據,則建立圖片時生成的數據源在/home/cacti/rra/cacti79.cm3目錄下。所以,選擇由誰來採集數據必定要在建立圖片以前操做,不然數據源的路徑是會出錯的。

兩臺採集服務器採集數據使用的是spine,爲了能讓它們各自採集本身負責的設備,還須要修改 spine.c源代碼。讓它每次採集只選擇host表的disabled爲「cacti78.cm3」或「cacti79.cm3」的設備進行數據採 集。

5、採集服務器上的定 期採集命令:

php poller.php --collect=< 採集服務器>

採集服務器是指你在WEB界面上添加一臺設備時,在「Choose Spine Agent」後 面的下拉框裏選擇的內容。

例如:

Cacti78.cm3 上的crontab裏就寫

*/5 * * * * /opt/php/bin/php pollerr.php --collect=cacti78.cm3

Cacti79.cm3 上的crontab裏就寫

*/5 * * * * /opt/php/bin/php pollerr.php --collect=cacti79.cm3

6、實施步驟

1、建立設備時選擇哪臺代理採集數 據

修改include/global_form.php

"disabled" => array(

"method" => "drop_array",

"friendly_name" => "Choose Spine Agent",

"description" => "Choose a spine agent to checks for this host.",

"value" => "|arg1:disabled|",

"default" => read_disabled("hostname"),

"array" => $spine_agent

),

修改include/ global_arrays.php,添加如下內容

$spine_agent = array(

0 => "",

"cacti78.cm3" => "cacti78.cm3",

"cacti79.cm3" => "cacti79.cm3",

"passive" => "passive");

修改lib/ functions.php,添加如下內容

function read_disabled($ip) {

$disabled = db_fetch_cell("select disabled from host where hostname='$ip'");

return $disabled;

}

2.建立圖片時使用什麼路徑

修改lib/function.php

$host = db_fetch_row("SELECT

host.id,

host.description,

host.disabled

FROM (host, data_local)

WHERE data_local.host_id=host.id

AND data_local.id=$local_data_id

LIMIT 1");

$host_spine = $host["disabled"];

$new_path = "<path_rra>/$host_spine/$host_id/$local_data_id.rrd";

$new_path = "<path_rra>/$host_spine/$host_part$ds_part" . "_" . "$local_data_id.rrd";

3.解決建立圖片頁面的對SNMP接口統計從新加載的Bug

修改lib/snmp.php ,在「function cacti_snmp_walk」函數下面添加如下內容

$banned_snmp_strings = array("End of MIB", "No Such"); //Add by qiudi.

4. 更改RRD路徑

修改include/global.php

#$config["rra_path"] = $config["base_path"] . '/rra';

$config["rra_path"] = "/home/cacti/rra";

5.修改源代碼以便經過命令行參數 來決定Spine Agent採集哪些被監控設備的數據

(1)修改poller.php源代碼

找到:foreach($parms as $parameter)

加入:

case "--collect":

$spine_agent = $value;

break;

修改:

$polling_hosts = array_merge(array(0 => array("id" => "0")), db_fetch_assoc("SELECT id FROM host WHERE disabled = '$spine_agent'

ORDER BY id"));

查找:「$poller == "2") {」

修改:

if ($poller == "2") {

$command_string = read_config_option("path_spine");

$extra_args = "--collect=".$spine_agent;

(2)修改spine.c源代碼

在main函 數裏定義變量:

char *spine_agent = NULL;

找到:for (argv++; *argv; argv++)

加入:

else if (STRMATCH(arg,"-c") ||

STRMATCH(arg,"--collect")){

spine_agent = strdup(getarg(opt,&argv));

}

修改:qp += sprintf(qp, " WHERE disabled=''");(兩處)

爲:

qp += sprintf(qp, " WHERE disabled='%s'",spine_agent);

相關文章
相關標籤/搜索