zabbix 的一次優化嘗試

背景

筆者維護的 zabbix 數據庫,由於監控幾千臺機器,幾百個監控項,後臺數據庫壓力比較大。zabbix 數據默認存放在 MySQL,基本 SQL 都是自己生成,當監控的機器數多了,監控項也多了之後,很多低效 SQL 的問題就暴露出來了。下面記錄下對 zabbix 的運維改造過程。

問題

  • 讀寫量大。寫量每天 1 億次,曾一度超過微博最大端口的寫量。讀量每天 2 億,也排在所有端口讀量的前 6 名。
  • 數據量大。history、history_uint 表,trends 表等是不斷積累的。
  • zabbix 自帶有定期刪除的機制,但每次刪除從庫就延遲,加上讀寫量又大,從庫延遲追不回來。
  • 很難備份。
  • 讀寫都在主庫上,主庫壓力較大

改造

針對以上這些問題,開始了一步步的改造,只要是能優化、容易優化的方法基本都使了。

  • 讀寫分離。zabbix 本身不支持讀寫分離,業務層面使用 oneproxy,而後臺則使用主從架構,用 DNS 做的負載均衡,在從庫上表現就是輪詢多個 ip。這有個問題,雖然主庫壓力小了,但從庫壓力相對大了。線上服務器基本是 8 核,32-64 G 內存,sas raid 10 配置,因爲機器資源不夠,怕影響其它服務也不能混跑,因此只配了一主兩從。大部分讀都切到從庫了,主庫上還是有部分讀。
  • 部分表用 tokudb 壓縮。先清空一遍 history 和 trends 表,再將引擎改爲 tokudb ,分 100 個分區。zabbix 官方用的存儲過程來定時創建和刪除分區,但按照規範不使用存儲過程,因此改爲手動一次性創建分區,7 天一個分區夠 3 年用了。
  • 停止 zabbix 自帶的 housekeeper 刪數據,改爲外部的定時任務去刪。 housekeeper 採用的 delete,不加約束的 delete 很容易造成從庫延遲;而採用 cron 的話只需要定期刪除一些分區即可,比 delete 高效。
  • 用 cgroup 限制 cpu 的使用。一個是 tokudb 引擎比較耗 cpu ,第二個是 zabbix 本身負載較高,需要做些限制。
  • 爲了省資源,也不做備份了,監控數據本身也不是特別重要,業務也允許丟數據。
  • tokudb 開啓 RFR 特性,但對 insert 效果比較好,而 zabbix 主要是 update,提升並不是很大。

改造後

改造完成後主庫壓力降了很多,服務看似正常了。一段時間過後又冒出了新問題,主庫每過一段時間就重啓,並且發現 swap 用完後要麼是 MySQL 實例被 kill,要麼是機器重啓。如下是被 kill 的情況。

kill

通過查看服務器一段時間的資源使用情況,發現一個規律:每天晚上 0 點開始的一段時間,機器負載異常,cpu idle 掉的厲害,memfree 和 swapfree 突然減少。詢問業務後,原來每天晚上 zabbix 都要重啓一次,很多表項需要重新加載。猜測造成的原因爲重啓這段時間內訪問壓力過大,可用內存不夠導致 swap。如下兩幅圖是主庫的 CPU 和 MEM 使用情況。

cpu

mem

從庫上也有 swap ,但是從庫並沒有因爲內存不夠而被 kill 的情況。如下是從庫的 CPU 情況,下降的並不明顯

6

slave

最後跟業務溝通,業務調整了刷新數據的策略,避免在短時間內出現負載的高峯,於是該端口恢復了正常。

三個問題

  • 爲什麼主庫機器內存耗的這麼快(跟 update 語句有關?),實例經常被 kill(主從 swappiness 都設置爲 1,並且主庫內存有 64G,tokudb 20G,innodb 16G。從庫都只有一半)
  • tokudb 除了分配的內存,難道還會大量使用 OS 內存?
  • 有必要對 Server 或者引擎層面的參數做個監控,根據參數的變化趨勢來及時發現問題。

一個 BUG

這是最近維護 zabbix 過程中發現的一個 bug https://support.zabbix.com/browse/ZBX-10652

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章