TiDB 在中國銀行 Zabbix 監控方案中的應用

Zabbix 作爲一個老牌的開源監控方案,長期被用於生產實踐。但是原生方案一般會採用 MySQL 作爲後端存儲,無法應對更大規模的監控。因此我們選擇使用TiDB來替換MySQL,TiDB 兼容 MySQL 協議,替換 MySQL 之後可以增強 Zabbix 的大規模監控能力,實現新的監控方案 TiZabbix。

通過優化監控實施邏輯,TiZabbix 彌補了因 TiDB 和 MySQL 差異造成的諸多問題,成功完成了 10000+ 監控對象和 16T 數據存儲查詢的實踐。本文就將爲大家介紹我們是如何把 TiDB 應用在金融行業的後臺運維監控上。

一、傳統的 Zabbix 監控方案及主要問題

Zabbix 是一個比較老牌的開源監控方案,這裏只做一個簡單介紹,Zabbix 主要分爲四個部分:

  • Agent:數據採集代理,部署於被監控服務器上;
  • Server:Zabbix 的服務端,用於數據的採集和發送告警等;
  • Web:用於數據採集和告警規則等配置,前端數據展示和 API 調用;
  • 數據庫:MySQL 用的比較多,用於配置信息和監控數據的存儲。當然了,隨着 Zabbix 的版本的迭代升級,除了 MySQL 也支持了其他的數據庫,在後面會簡要的提到一些。

傳統的 Zabbix 監控方案主要有以下幾個問題,這些問題都是由單機數據庫 MySQL 引起的:

  1. 數據庫 MySQL 是單機的,因此不能支持較大量(指上幾 T 量級的數據)的數據;

  2. 由於這個的原因,所以監控對象的數量和數據存儲時間不能兼得;

  3. 官方給出了 proxy 的解決方案,想通過 proxy 來提升監控納管被監控對象的能力,但是 proxy 最終也是要把數據發到最後面的主 MySQL 上,其實並沒有減輕數據庫的壓力。由於 MySQL 對 Zabbix 的限制,所以後來考慮用 TiDB 在 Zabbix 中直接替換掉 MySQL,來提升 Zabbix 的數據採集量。

二、TiDB 在 Zabbix 中的應用

1. 應用時間軸

這裏是一個簡單的時間軸:

  • 2016 年:用的單實例的 Zabbix,用了 MySQL,監控了 1000 + 的 Linux 服務器,當時存儲了 60 天的分鐘級數據。

  • 2017 年:使用 Zabbix Server 進行雙實例部署,各監控 1000 + 的 Linux 的服務器,嘗試將歷史數據用 Python 寫入 Elasticsearch。但是,由於中間用了 Python 的讀取寫入過程,不如直接往數據庫裏寫些穩定。所以當時用了一段時間,沒有繼續用下去。

  • 2018 年:開始嘗試使用 TiDB 代替 MySQL,這時的生產環境開始使用原生 Zabbix ,原生的 Zabbix 方案也已經支持 Elasticsearch 作爲後端存儲。但是考慮到 TiDB 兼容 MySQL 協議,且 TiDB 是分佈式數據庫,可能比 Elasticsearch 會有一些優勢。再加上 Elasticsearch 在當時的易用性也不是很好,特別是升級的操作對於剛入門的用戶來說是比較痛苦的,而 TiDB 的升級就比較平滑,因此,綜合考慮後開始使用 TiDB 代替 MySQL。

  • 2019 年:通過解決若干的替換問題後,TiZabbix 監控對象達到 9000+ ,數據量達到 15T。

  • 2020 年:TiZabbix 監控對象達到了 10000+,數據量達到 18T,每日採集的數據條目大概是 14.5 億條。同時,穩定性也得到顯著的提升,這裏的穩定性,不是指單獨 TiDB 的穩定性,由於 TiDB 官方建議用的硬件性能要求比較高,但是由於各種原因的限制,我們使用到的 TiZabbix 環境下 TiDB 的硬件性能不是很好,所以硬件性能的問題,會限制 TiDB 的穩定性。在 2020 年,通過解決了若干問題,在這些較差的硬件上,同樣將 TiDB 的穩定性是達到了一個比較理想的水平。

2. 實踐歷程

接着分享一下具體的實踐歷程,我們在這個過程中陸陸續續解決了一些問題,才達到了剛纔說的 18T 的監控數據的一個相對穩定的狀態。

首先,一開始是不改動 Zabbix 的源碼,半黑盒替換數據庫。改源碼是一個系統性的工程,難度比較大。爲什麼說半黑盒替換呢?因爲雖然沒有改源碼,但是在遇到問題時,需要通過閱讀源碼來通過一些替換方案或者繞行方案來解決替換過程中遇到的問題。

下面就是實踐中遇到的一些問題。和原生不一樣,監控對象自動註冊我們改爲使用 API 延遲註冊,Zabbix 自動註冊功能是它實現監控自動化的一個重要功能。但是 TiDB 是樂觀鎖(較新的版本已經支持悲觀鎖了),和 MySQL 的悲觀鎖是有區別的,當大規模的自動註冊時,它是有嚴重的事務衝突的,所以就把自動註冊功能改爲用串行的 API 的延遲註冊,通過 API 調用的方法,來將新上的監控分區註冊上來,解決事務衝突的問題。

接着就遇到了 History 表的問題,因爲 Zabbix 裏幾個 History 表是監控數據的存儲表,是非常大的。當時一開始,我們用的是 TiDB 2.1 版本,還不支持表分區,所以存儲時間長了後,刪數據的問題比較難處理。升級到 3.0 版本,支持了表分區,通過 Drop Partition 來解決歷史數據的刪除問題。所以在用的過程中,對於大表的表分區還是非常重要的。

接下來還遇到一個問題,Log 類型的數據是一個長字符串,在 2.1 版本的時候,到了一定的數據量後發現所有數據都寫入不進去。當時,看了 TiDB 的官方手冊裏提到寫放大的問題,覺得可能是 Log 類型的長字符串引起的。對於監控來說,數值性的數據它的歷史參考價值比較大,像 Log 的參考價值比較小。因此,把 Log 型的採集關掉後,數據庫的寫入就恢復了。

規模更大了以後,又遇到了外鍵約束的問題。因爲 TiDB 是不支持外鍵約束的,而原生 Zabbix 後端數據庫是 MySQL,是有外鍵約束的要求的,特別是在外鍵裏,有一個主鍵和外鍵的級聯刪除功能,相當於從數據庫層面實現而不是應用代碼實現這個功能。所以,因爲外鍵的問題也造成了某些因爲 Low level discovery(Zabbix 裏的自動發現功能)的問題,簡單舉例來說,就是比如說 Linux 和掛載點,需要發現每個掛載點來監控每個掛載點的磁盤使用量,這種自動發現的功能產生的告警就會因爲外鍵的問題發生錯亂。

除了外鍵約束的問題外,又發生了數據無法寫入的問題。後來閱讀了 Zabbix 的源碼,在源碼中發現,在判斷告警規則的時候,有一個鎖緩存的操作,可以鎖掉 Zabbix Server 上的緩存。因爲 Zabbix Agent 採上來的數據是先緩存到 Zabbix Server 的內存裏,鎖緩存以後,緩存的東西就不往數據庫裏寫了,因此,後端數據庫就無法寫入。

最終因爲這兩方面的原因,我們決定把告警功能裁減掉,將TiDB 用在 Zabbix 後,只用它來採集、存儲和查詢數據。但是告警去掉了,怎麼來彌補這個功能呢?在生產環境上,我們通過使用 Zabbix Agent 的本身雙寫能力(雙寫到不同 Server),往兩個方向的 Server 上寫數據。一個 Server 上對應的是 MySQL,用來實現告警功能,它的告警不會受外鍵的影響,但是它的數據存儲就特別特別少,可以解決性能問題。另一方向的數據把它寫到對接 TiDB 的 Server上,就不要告警功能,只要數據的訪問和大規模存儲。最終通過數據和告警的分離解決了這個問題。

3. 一些技巧

接下來,簡單說一下使用過程的一些小技巧。

1)在設計過程中,架構要儘量的簡單。Zabbix 支持主 Server 上再放 proxy,但是一開始使用,建議先不用 proxy,因爲 proxy 會引入複雜度。單 Zabbix Server 的情況下,按照現在的性能指標,保持現在的數據採集頻率和存儲時間,20000+ 的監控對象應該是沒有問題的。

2) Agent 採用主動模式即 Zabbix agent active,這種模式可以有效減少 Zabbix server 的壓力。因爲在被動模式下,Zabbix server 性能消耗比較多,而在主動模式下,相當於把壓力下推到 Zabbix Agent 的採集端,這個壓力對單個服務器來說是微乎其微的;但是如果都疊加壓到 Server 上, Server 肯定受不了的,所以通過選擇 active 的模式,來減小 Server 的壓力。

3)將 Zabbix 裏的配置項 HistoryCache Size 設置爲 2G 最大值,可以彌補硬件的不穩定性。剛纔也提到了,因爲沒有用到 TiDB 建議的比較好的硬件,所以硬件性能的缺失就造成了 TiDB 的一些不穩定因素,有時數據寫入會比較慢,就會積壓到緩存裏,把緩存設置的儘量大就會保證數據的不流失。雖然積壓了,但是隨着性能的恢復,數據是可以重新再寫進去的,只是產生了一定的延時,但沒有造成數據的丟失。

4) API 的調用不要過於頻繁。因爲 API 調用過程中權限的檢查是要頻繁的查和寫同一個表的同一行數據,這會產生嚴重的事務衝突,特別是在 TiDB 樂觀事務下,嚴重的事務衝突會拖垮數據庫的。所以,API 調用不要過於頻繁,如果需要多進程,或者多線程的調用 API,最好是多用幾個 Session ID,Session ID 是權限檢查的最小單元,這樣可以避免這種情況。

5)隨着數據量的增大,Web 的一些操作會失效,需要靈活的使用 API。失效主要是因爲數據庫事務比較大,前端會超時,因此,當數據量比較大時,比如說要在前端大規模的改一些東西,這時就要靈活的使用 API。因爲 API 是一個自動化非常好的手段,通過靈活的使用 API,會規避這個問題。

4. TiZabbix 方案優勢

我們通過以上的探索來解決了一些問題,完成了 TiDB 在 Zabbix 中的有效應用。

1)監控的數據中臺化方案。TiZabbix 是用在監控數據的中臺化方案,主要解決數據大量的採集、存儲和查詢,可以提供更大量的、更長時間監控的歷史數據,方便我們進行數據分析、查詢和一些複雜問題的定位。

2) Zabbix-Server 高效且支持多種數據採集方式。我們知道,原生的告警規則是比較簡單的,只有通過較多歷史數據的關聯查詢分析纔能有效定位一些問題。同時, Zabbix-Server 比較高效,單 Server 下我們用的是虛機(一般最大 64G 內存),它是支持 20000+ 的 Linux 的採集的管理分區沒有問題,而且它支持多種的數據採集方式,這就是一個很好的數據集成的支持。

3)Zabbix-Web 提供豐富的 API,可以通過 API 來調用數據。

4)TiDB 本身就是良好的橫向擴展能力,且易用性極高。通過橫向擴展提高數據庫的容量和性能,這樣可以獲取更多的數據和更長時間的存儲。

三、TiZabbix 的優化提升

上圖是 TiZabbix 簡單的架構圖, Zabbix Proxy 在這裏是沒有用到的,但當規模更大的時候會使用它來分攤 Zabbix Server 的壓力。因爲在單 Zabbix Server 下,它的內存會是潛在的瓶頸,當被管理端多了後,對應 Server 的內存肯定會不斷的增長,增長到一定程度後單機就無法再增大了,就需要 proxy 來分擔 Server 的壓力。所以,當達到更大的規模後 proxy 是需要引入的。架構圖的右半部分是提供 API 的 Web ,相當於第三方的調用來消費監控到的數據。

架構圖最下面一層是 TiDB,TiDB 目前來看也是存在着一定的潛在的瓶頸,可能主要是併發衝突。因爲用到的是比較差的硬件,肯定是要受點限制的,具體表現在併發的性能上會下降一些,不過這個也可以通過邏輯上的方案來規避一下,就是 item(Zabbix 的一個關鍵數據模型)。在一些極端場景下,自動產生的 item 會比較多,如果它不斷的自動生成,相當於會出現寫熱點,然後會產生併發衝突,進而拖垮整個數據庫。所以,在更大規模下,需要優化自動生成的 item 策略。將 item 的自動生成策略打散,不要在同一時間點生成過多的 item,來緩解可能引起的併發衝突。當然,通過提升硬件的性能,也能夠來彌補這個問題。

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