zabbix前端效率極低,大批量更新會造成Oracle tx鎖,因此對於大批量更新,會選擇用sql直接update。當然也可以用其他方式,比如通過PHP代碼來解決等等。
但是在現有條件下,直接跑sql肯定會比其他方式方便很多,其他方式需要通過代碼調用zabbix API來實現。個人覺得在保證數據庫正常完成生產需求的情況下,一些
批量增、刪、改、查通過sql直接跑庫是很不錯的。當然了,你要用sql去操作zabbix數據庫,必須要對zabbix數據表結構有清晰的了解才行。
還有一種情況,zabbix收集了大量的裸數據,其他人可以通過這些數據進行相關的分析,這個時候拿這些數據也需要對zabbix數據庫結構了解才行。
目前沒有看到成型的教程文檔類的東西來指導我們了解zabbix數據庫結構,從網上搜了很多相關的文檔零零散散,最后經過測試、驗證總結出來此文。算是一種對
zabbix、數據庫知識的一個深度學習加復習吧。廢話不多講,直奔主題。
須知
zabbix數據庫中的表的名稱都是復數,比如存放Host信息的表名字是Hosts等。這些可以直接從數據庫中看到。
數據庫操作有風險,一旦出現問題會造成zabbix crash,因此操作需謹慎
普通的查詢可以在備庫上進行,數據時同步的。滿足查詢需求的同時,也不對因為查詢影響生產性能。
表結構概述
zabbix的數據庫設計很有特點,針對zabbix中的每一個資源,都有一張表與其對應,比如hosts表、items表等。而每一張表中都有一個id字段。資源之間的關聯關系是
通過外鍵來完成的。比如host和item的關聯關系,就是在items表中用hostid與hosts表中的資源進行關聯的。
下面以hostid舉例說明,其他itemid、triggerid等都類似。
hostid是每一個host的唯一標識,我們從數據庫查詢時,一般都是以hostid為查詢條件。
我們點開一個host,看其URL:http://192.168.232.130/zabbix/hosts.php?form=update&hostid=10084&groupid=0&sid=07d1c2806378f190
我們可以看到URL里的Get參數:
1、from:標識當前頁面的操作,這里的update是因為我是從Configuration-Hosts中點擊host進去的,所以是一個更新操作
2、hostid:點擊的host的hostid
3、groupid:這里不需要groupid這個字段,因此這個0沒有意義
4、sid:sessionid,標識用戶用的
zabbix前端界面的URL有很多像上面的URL那樣。有的是itemid,有的是triggerid,我們更改一下這個id,就自然能夠跳到對應的界面了。這一點正是zabbix的
靈活之處。
Hosts表
"Host"就是指一台被監控的機器。先看下Hosts表結構:
- hostid:唯一標識Host在zabbix及數據庫的id。不同表之間的關聯也用hostid。和這個類似,zabbix中任意一種資源都有自己的id,比如itemid,groupid等。
- proxy_hostid:如果使用"proxy_server"架構,這個字段表示的是監控這台機器的proxy的hostid。此處有一點需要注意,每個proxy在hosts表里有兩條記錄
一條是和普通機器一樣的、作為被監控機器的記錄;另一條是作為proxy的。作為proxy的那條記錄,IP字段的值為"0.0.0.0"。proxy_hostid中的值就是proxy
proxy記錄中的hostid。 - host:機器的hostname。
- dns:DNS名稱
- useip:是否用IP監控
- port:監控使用的端口
- status:機器目前的狀態。"0"為正常監控,"1"為disable。"2"不清楚,從數據庫里找不到status為"2"的機器。Google后,這個好像是zabbix自身的一個host
available檢查有關。"3"表示是個Template - disable_util,error,available,errors_from(ipmi_disable_util,ipmi_error...):這幾個都是zabbix poller會去修改的值。當poller在第一次取不到值(根據
值得類型不同會更新相應的列,item類型為snmp就會更新snmp_XXX,默認為zabbix類型)的時候,會等待15s(CONFIG_UNREACHABLE_DELAY)重試,如果
15s后依然取不到值,zabbix會在數據庫更新這個host取不到值得信息。而且日志里顯示"another network error" - lastaccess:這一列是專門為proxy准備的。lastaccess表示的是proxy最后一次工作的時間。此處的工作是指zabbix server收到proxy數據
- inbytes,outbytes:
- useipmi,ipmi_*:
- snmp_*:
- maintenanceid,maintenance_*:這個是zabbix另一個機制Maintenance有關,用來將host置於維護狀態而不會報警
常用操作
更新機器的proxy。找到proxy的hostid,更新對應host的proxy_hostid:
select hostid from hosts where host=' '; #get:hostid,proxy的
update hosts set proxy_hostid=' ' where host='';
update hosts set status='0' where host='';
update hosts set status='1' where host='';
Items表
items表也是zabbix的核心表之一,它記錄了item的所有設置。大家都知道,在zabbix中做的最多的操作就是對於items了,下面我們看下items表結構:
- itemid:item的id
- type:item的type,和前端配置item的type對應。數據庫中這一列的值是0-17的數字,分別代表:
0:zabbix agent
1:SNMPv1 agent
2:zabbix trapper
3:simple check
4:SNMPv2 agent
5:zabbix internal
6:SNMPv3 agent
7:zabbix agent(active)
8:zabbix aggregate
9:web item
10:external check
11:database monitor
12:IPMI agent
13:SSH agent
14:TELNET agent
15:calculate
16:JMX agent
17:SNMP trap - snmp_community:
- snmp_old:
- hostid:item所在的host的hostid。如果該item屬於template,那么這里顯示的是templateid
- name:item的名字
- key_:item的key
- delay:這里的delay,實際就是在配置item時候配置的"Update Interval"
- history:前端配置中的存儲history的時間
- trends:前端配置中的存儲trend的時間
- status:item的狀態
0:item是enable狀態
1:item是disable狀態 - value_type:item返回值的類型
0:numeric float
1:character
2:log
3:numeric unsigned
4:text - trapper_hosts:
- units:
- multiplier:
- delta:
- snmpv3_securityname:
- snmpv3_securitylevel:
- snmpv3_authpassphrase:
- snmpv3_privpassphrase:
- formula
- error:item的錯誤信息
- lastlogsize:
- logtimefmt:
- templateid:
- valuemapid:
- delay_flex:
- params:
- ipmi_sensor:
- data_type:
- authtype:
- username:
- password:
- publickey:
- privatekey:
- mtime:
- flags:
- filter:
- interfaceid:
- port:
- description:
- inventory_link:
- lifetime:
- snmpv3_authprotocol:
- snmpv3_privprotocol:
- state:當前item的狀態
0:正常
1:not supported - snmpv3_contextname:
Trigger表結構
Trigger是zabbix的重要部分,平時工作中除了host和item,就屬trigger了。而且trigger相對於host和item來說
更加復雜。host和item在數據庫中對應的hosts表和items表都是非常平面的表,結構簡單,host和item的屬性在
表中一目了然。而trigger在數據庫中對應的triggers表則相對復雜,它和其他表的關聯關系很強,需要仔細分析。
先看下triggers表結構:
下面我們從前端找一個trigger來看下:
這個trigger的URL:http://192.168.153.130/zabbix/triggers.php?form=update&hostid=10084&triggerid=13491&sid=a8af27a7c7b0697b
從URL中我們可以看到起triggerid為13491,那么我們根據triggerid從數據庫中取一下這個trigger:
sql:select * from triggers where triggerid=13491\G
現在可以明白triggers里邊主要字段的作用了吧。trigger的核心是expression,也就是我們定義trigger的邏輯是:{192.168.153.130:agent.ping.nodata(5m)}=1
,但是數據庫里沒有這個東西,只有一個{12900}=1。1是那個閾值,那么這個{12900}又是什么鬼東西呢?根據前端trigger來看,這個邏輯的屬性是"Expressions"
的內容,我們先查一下數據庫中expressions表記錄的內容:
這不是trigger里的expression,而是Administration-General里的"Regular expressions",從前端看:
那這個{12900}究竟是什么呢?原來是function,內容在functions表:
sql:select * from functions where functionid=12900;
對應trigger的expression,一目了然。
Events表
大家都知道,當zabbix server獲取到一個數據,它會檢查跟這個item相關的trigger,然后無論是否出發action,都會生成一個event。events表結構:
- source:event可能由多種源頭生成,這里的source是記錄了這個event是由什么事件生成的
0:由trigger生成的event
1:由discovery rule生成的event
2:由agent auto-registration生成的event
3:internal的event - object:這個字段記錄了和event關聯的zabbix對象
對於trigger相關聯的events,這里的值只可能是0
對於discovery相關的event,"1"表示是discovered host;"2"表示是discovered service
對於auto-registration的event,這里值一定是"3"
對於interval的event,"0"表示trigger,"4"表示item,"5"表示low-level discovery - objectid:根據前面object里的定義,這里可能為triggerid,也可能是discovered hostid
- value:和object字段類似,根據source不同,這里的值有不同的含義
對於trigger類型的event:
0:trigger的狀態位OK
1:trigger的狀態位problem
對於discovery類型的event:
0:host或service正在工作
1:host或service停止工作
2:host或service被偵測到
3:host或service丟失了
對於internal類型的event:
0:normal狀態
1:unknown或者not supported狀態
History和Trends
History和Trends都是存儲歷史數據的地方,但是他們究竟有什么區別,現在我們從數據庫入手看一下這個問題。
首先我們看數據庫中history和trends相關的表:
sql:show tables like '%history%';
sql:show tables like '%trends%';
trends表是比較簡單的,共兩個表,其中trends_unit表示的是unsigned int,這兩張表功能是一樣的,只是存儲
的數據類型不同。
history表就比較多了,單從表名來看,我們能夠很清楚的看到,大多數history表只是分了不同的數據類型,比如str
表示字符串,log表示log文件類型。其中有個synv這個屬性,大家都知道sync一般是"synchronize"的縮寫,在這里
帶有sync后綴的history表,是用作Master-Child同步數據用的。
那么history和trends表的區別呢
它們的相同點是都是存儲歷史數據的,不同點是他們存儲數據的粒度不同。每一次zabbix接收到item數據后,會將其
存入history表。下面是history表結構:
sql:desc history;
這個是很簡單的結構,clock和ns保存着接收item的時間,itemid唯一標識了item,value即為接收到的數據。
而trend表的作用是將history表的數據根據小時的維度進行歸檔。它會針對每一個itemid,計算每個小時的最小值,
最大值和平均值,下面是trends表結構:
sql:desc trends;
num字段表示了該小時使用了多少數據來計算最小值、最大值和平均值。
housekeeper和trends表
history表的作用我們已經清楚了,就是存儲所有item的歷史數據。衡量zabbix性能有一個重要指標,就是vps--Value Per Second。
如果vps為1000的時候,即每秒zabbix要處理1000個數據,每一個數據都會在history表中有一行,現在計算一下,一天有86400秒,
每秒1000行數據,那么一天就是86400000行,8千萬行!如果一直這樣無限制膨脹下去,history表的性能會很差,從而拖累整個
zabbix數據庫的性能。
應對這個問題,zabbix提供了兩方面的解決辦法,一個是housekeeper機制,另一個則是trends機制。
housekeeper非常簡單,就是定期刪除history表中的數據。對於小規模的zabbix來說,這是個省時省力的方法,但對於大規模的zabbix
數據庫,但對於大規模的zabbix數據庫,使用housekeeper效率非常差,特別是InnoDB引擎的MySQL,因為大表的刪除非常慢。對於
規模很大的zabbix,我覺得應該每周truncate一次history相關的表,大家可能會擔心這么暴力的刪除會不會影響數據完整性,我們來看下
trends表的作用,就明白了。
trends表的工作原理大家都清楚了。這里我們看下trends在zabbix的用處。其實在zabbix中,trends只在很少幾個地方出現,最重要的
就是在Graph中了,我們看某個時間點,圖中其實有3個數據。從小到大分別是這個時間點的最小值、平均值和最大值。這里調用的就是
trends表的數據。大家想一下,history的數據真的有必要保存那么久嗎?對於上周的數據,我們要精確到每一分鍾嗎?並不需要,對於
時間越久的數據,我們需要的粒度就更粗。
Graph對於history和trends的選擇
我們來分析下Graph選擇從history表選數據還是從trends選
https://wenku.baidu.com/view/8d56c7b489eb172ded63b7ea.html