您好,登錄后才能下訂單哦!
本篇內容介紹了“OpenFalcon在高并發場景的應對手段有哪些”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
OpenFalcon 在高并發場景的 7 種應對手段
數據采集推拉抉擇
對于監控系統來說,包含幾個核心功能:數據采集、歷史數據存儲、報警,最后是繪圖展示及數據挖掘。
數據采集
這一塊我們希望做一個大一統的東西,因此要采集很多監控指標,比如 Linux 本身的監控指標,像 CPU、內存、網卡、IO 等,一些硬件指標,比如風扇的轉速、溫度等等,再加上一些開源軟件如 MySQL,Nginx,OpenStack,HBase 等監控指標。
公司內部有很多產品線,每一個服務運行狀況都希望采集到,比如中間層服務開了一些 RPC 端口,每一個 RPC 端口在服務過程中,latency 是多少,QPS 是多少,我們都希望了解到。
所以需要覆蓋很多監控指標,監控團隊剛開始只有兩個人,不可能把所有監控指標都采集到——人力不行、技術水平也達不到。
所以我們需要共建監控數據,讓專業的人干專業的事。
DBA 同學對 MySQL 比較熟,那他們去采集 MySQL 相關指標,分布式團隊同學去采集 HBase 或 Hadoop 等指標,網絡組同學去采集交換機路由器指標。
而作為監控團隊要做的,就是制訂一個規范。制定一個數據進來的機制,然后公司開發人員和運維人員按照規范去推送數據。
數據收集沒有采用拉的方式,因為太多數據源,作為一個 Client 去連接源端,采集數據,再關閉連接,會產生很多 time_wait 狀態連接,其吞吐必然是不高,所以要把自己做成 Server 端。現在每個周期有 1 億多條數據。
這個周期簡單解釋一下,監控數據是一個持續上報,比如 Linux 一些基本監控項一分鐘一次采集之后上報,下一分鐘再采集再上報。一些像業務監控有 3 分鐘的,有 5 分鐘的。
因此周期是指數據量是 5 分鐘以內,有上報動作的數據。
中間節點快速轉發與容錯
數據有很多要 Push 到 Server 端,Server 端最前端組件是 Transfer,Transfer 接收到數據后要把它轉發給后面兩個組件,一個是 Graph(用來做繪圖),一個是 Judge(用來做報警判斷)。
首先對每一個后端實例創建一個 Queue 出來,比如 20 個 Graph 實例,60 個 Judge 實例,為每個實例創建一個 Queue,每個 Transfer 內存中有 80 個 Queue,
當一條監控數據過來之后,需要判斷數據發到哪一個實例,然后放到這個實例對應 Queue。Transfer 接收數據 RPC 邏輯非常簡單,數據拿到后放到 Queue 就立馬返回。
Agent 到 transfer,transfer 到 judge,judge 到 Redis,Redis 到 alarm,報警鏈路比較長,如果希望盡快觸發報警,鏈路每一個環節都希望比較快速處理,用 Queue 方式,Transfer 吞吐特別大,不會拖慢整個鏈路。
數據放在 Queue 中有一個問題,如果不及時轉發,比如后端 load 比較高或者掛了,Queue 數據就會堆積,超過內存就會 crash,所以做了一個簡單保護措施,將 Queue 設成定長,超過 Queue 長度,數據就放不進來。
數據 Push 到 Queue 后,有一個專門對 Queue 讀入 worker,讀到了之后轉發。轉發這個動作由一堆寫 worker 完成,這里 worker 是指 goroutine,如此這般,一堆 goroutine 協同工作,來提高轉發性能。
一致性哈希分片提高吞吐容量
一致性哈希分片
這么多數據上來不可能由一臺機器處理,因此做了一個數據分片,即一個機器只處理一部分數據,報警數據是由 Judge 做分片,繪圖數據由 Graph 做分片,這兩個都是使用一致性哈希。
一致性哈希分片有一個問題,就是擴縮容比較麻煩,數據打到某個 judge 之后,就會一直打到這個 judge。
當列表發生變化時候,由于一致性哈希算法,原來打到一臺 judge 實例的數據就會打到另外一個 Judge 實例,所以 Judge 一定要保證沒有狀態,這樣才能方便擴縮容。
狀態標記
其實說它沒有狀態也不太合適,judge 內存里也存了幾個點。比如某一臺機器 cpu.idle 數據上來之后,連續 3 ~ 5 次達到一個特定閥值才去報警,而不是達到閥值立馬報警。像 CPU,是一直都忙碌狀態才去報警,Judge 判斷的時候它是判斷多個點。
產生報警之后,還有一些后續處理,比如對這個報警事件做一個判斷,上次產生事件是什么狀態,他是第幾次報警,是不是達到了最大報警次數不能再報了,避免重復報警給處理人員造成干擾。一般大家都設置報警 3 次。
因此報警事件需要記錄一個狀態,標記是否健康,如果有問題,記錄當前是第幾次。Judge 狀態存在數據庫,雖然 1 億條數據上來,實際上報警數據不多,可能只有 10 萬條數據級別,因此可以存入數據庫,這樣 Judge 就剝離了報警事件狀態。
雖然 Judge 內存當中還存一些前面所說數據狀態,但也不是一個大問題。因為監控數據是源源不斷上來,即使丟掉一些狀態,新的 Judge 實例很快就會又填充數據。
擴容
一致性哈希對擴容不是很友好,比如 20 臺 Graph 的機器如果變成 40 臺,勢必有老的 Graph 實例的一部分數據打到新的 Graph 上,因此我們做了一個自動數據遷移。
這個自動遷移是由于一致性哈希造成的問題,如果用映射表做分片,在映射表這統一維護數據和 graph 實例對應關系,擴容就簡單很多。
數據與策略快速匹配
當數據上來后,要判斷這個數據是不是觸發了報警策略,策略有很多種,比如我們現在系統中有幾千上萬條。
上來一條數據之后,要判斷這個數據跟哪一條策略相關,然后再判斷閥值是多少,是不是要觸發報警。
我們選擇去數據庫同步所有報警策略列表,因為策略列表整個公司不會特別多,雖然數據量多,但是策略不是特別多,比如只有幾千條或者幾萬條。
在策略數據庫做了一個簡單索引,方便數據上來之后快速定位策略,然后根據閥值看是否要需要報警處理。
為了加快策略判定,需要知道近期一些歷史數據,歷史存在 Judge 內存中,這樣獲取速度相對來說快一些。
第一個版本做測試時沒有放到內存中,當時用了 56 個 Redis 實例,每個實例大概有 3,000 QPS,那時上的量不大,仍然達到了一個這么高的 QPS。由于并發高,把數據放到 Redis 中并不是一個很好的解決辦法,后來就把它放到了Judge 內存里。這樣處理起來就快很多。
報警狀態也存在 Judge 內存及 DB。如果每個報警判斷都去訪問 DB 比較耗時,所以就加載到 Judge 內存,相當與緩存的機制,內存沒有再去 DB 加載。在 Judge 重啟的時候,內存沒有數據,這時報警狀態的判斷需要去 DB 加載,然后再讀到內存里。
數據延遲寫入,減少 RRD 文件打開次數
時間序列數據自動歸檔
報警數據存儲采用 RRD,RRD 比較有名。大量開源監控軟件存儲時間序列數據都選用 RRD。
RRD 最大的優點是自動歸檔。監控數據有一個特點,不需要關心歷史監控數據具體的值,只需知道當時的趨勢即可。
最新 6 個小時可能有看原始值需求。但是最近 3 天 及 1 個月原始值的需求就很小。而且那個點特別多,一分鐘 1 個點,一天有 1440 個點。如果加載 1 個月瀏覽器不崩才怪。
由于對歷史點只要能看到趨勢就行。因此監控數據特別需要歸檔功能。比如一個小時的數據歸檔為一個點,RRD 可以幫我們做這個事情。
RRD 優化:延遲合并寫入
RRD 默認操作性能比較差,它的邏輯是打開 RRD 文件,然后去 seek,write,seek,write,最后 close 文件句柄。一個監控指標對應一個 RRD 文件,比如這個機器上面處理了大約 200 萬個監控指標,實際上就有 200 萬個 RRD 的文件。
每次寫入數據的時候,打開這個 RRD 文件,讀頭部信息,包含一些 meta 信息,記錄了歸檔策略、數據類型之類數據,然后去做寫入操作。
如果每一個數據上來之后都做這個操作,RRD 讀寫會造成特別大的 IO。雖然現在磁盤都是 SSD,但由于 IO 居高不下,于是做了一個延遲寫入的優化。
現在數據都是 1 分鐘上報一次,可能有的數據 10 秒或 30 秒上報一次。并不是上報上來立馬打開 RRD 文件寫入,而是等 10 分鐘或者 30 分鐘,在內存中緩存一段時間,緩存 30 個點或者 60 個點,一次性把文件打開,一次性寫入再關閉,這樣可以減少 RRD 文件打開的次數,讓 IO 降低一些。
我們根據緩存的時間,比如緩存半個小時,再按照半個小時時間長度來做數據打散,比如現在半個小時是 1,800 秒,舉個例子,1,800 秒把它做成 1,800 個槽位,每個數據上來之后平均分散到 1,800 個槽位當中,寫的時候慢慢地寫,這樣做了一個打散操作,避免讓 IO 出現一些峰值。
報警事件按優先級入隊列緩沖
報警事件量通常不是特別大,但個別時候會比較大——觸發一些大面積報警的時候,比如某一個核心交換機掛掉了,會產生特別大的報警。
比如服務依賴于上游某幾個服務,上游服務掛了,所有下游服務都報警。如果核心交換機掛了,很多核心服務都受影響,核心服務受影響之后,下游很多服務就產生報警,這樣產生一個大面積報警。但通常情況下,報警量都是一個很平穩的一個量。
當大面積報警出現時,我們仍然是應用 Queue 機制,用 Queue 來抹平峰值。
報警的分級處理
我們將報警進行分級,從 P0、P1 一直到 P5,P0 最高。
基于優先級的分級策略
P0、P1 發短信發郵件,并且是收到報警立即發; P2 這個級別發短信不是立即發,而是做一個報警合并; P3、P4 那些低級別就做報警合并,同時不發短信,只發郵件。
我們對報警事件做一個分級,每一個級別就對應 Redis 里面一個Queue。利用 Redis BRPOP 簡單實現按照優先級處理報警事件,即先處理 P0,再處理 P1、P2 順序。
通過限制 Worker 數目發送接口限流
系統本身可能鏈路比較長,每個鏈路都希望能夠扛住高并發,實際上在系統開發過程當中,我們依賴于其他基礎設施,比如內部有 SMTP 服務器來發送郵件,有短信通道來發送短信,但是這些接口扛不住很大的并發。
當要系統依賴調用幾個并發能力較差的接口,最好做一個限流。
有一個專門的模塊 Sender 發送報警郵件或者報警短信,它發送時候可以給它配置一個 Worker 數量,大家可以理解成最多有多少個線程來調用發送接口。這樣就可以保護后端發送接口,不至于把它打掛。
“OpenFalcon在高并發場景的應對手段有哪些”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。