任務調度系統如何通過隔離提升可用性?

今天聊的任務調度系統,在開源領域中近似的就是Ansible了。Ansible通過在集羣上執行命令解決各類業務問題,從而管理千臺規模的集羣,自身安裝和維護都非常簡單,因此得到迅速普及,深受運維人員喜歡。

下圖就是Ansible的典型場景,在Ansible-Server上,對一組機器列表下發指定的命令並回收執行結果,從而完成一次任務的執行。

在大型的互聯網公司中,任務調度系統多以自研爲主,本文希望藉助於任務調度系統,能夠將隔離這個話題,講的較爲透徹一些。

從隔離的角度看任務調度系統的高可用

任務調度系統要支持公司內部的各個場景,如上線,配置修改,數據備份,文件傳輸,批處理命令等等,每天數以萬計的任務量,這裏面任何的任務失敗,可能都會導致較爲嚴重的後果,例如關鍵報表任務故障,重大新聞素材推送失敗,緊急回滾功能故障等等。因此任務調度系統的高可用能力一定是面面俱到的。

那爲什麼本文要從隔離角度來看任務調度系統的高可用呢?因爲隔離能力是以下高可用能力的前提和基礎:

  • 灰度發佈

  • 異地多活

  • 故障隔離

  • 混沌工程

因此,接下來,我們主要從隔離角度對任務調度系統進行分析

任務調度系統的隔離能力建設

下圖是典型的任務調度系統的架構示意圖,數據流如下:

  1. 用戶請求:用戶通過上層各種業務平臺發起請求

  2. 接入調度層:基於用戶在上層平臺的TAG標記進行任務類型的識別,並將任務分配到合適的任務處理平臺,同時,接入層還起到鑑權,配額管理,合規性,流量控制和流量調度的作用。

  3. 任務調度層:用戶發起的任務,通過接入層的檢查放行後,就被分發到不同任務類型的調度集羣上,然後按照任務的機器列表要求,分發到各個機房對應的Master上

  4. 任務執行層:調度層會預先基於IP地址進行拆分,將一個機房的機器列表,按照確定的規則分發給不同的Master,每個Master又將各類任務劃分爲不同的隊列進行處理

租戶隔離,適用於不同的業務場景

舉例來說,每天的凌晨整點開始,會發起大量的備份任務,涉及線上絕大部分機器,此時,如果不進行隔離,那麼同時段發起的上線任務可能就會受到影響。通過對不同的租戶進行隔離,同樣的情形下,因爲備份和上線的集羣是獨立的,且每個集羣都有相應的配額,因此兩者之間不會互相影響,單個租戶也不會影響整套系統。換言之,備份任務所在的集羣宕機,也不會影響到上線的任務。

類似的一些租戶隔離的場景

  • PC,移動端和APP的流量進行隔離

  • 報表系統和用戶請求流量進行隔離

  • 線上環境和線下環境隔離

重要性隔離,適用於同一類業務場景

以當下較爲熱門的直播應用爲例,不同主播的訪問量相差極大,對於熱門主播,可能隨便一次直播都可以帶來百萬用戶的訪問量,那麼假設直播應用主播的信息均勻分佈存儲於Redis中,數據以三副本存儲,那麼對於這種百萬直播的場景,因爲熱門主播的數據分散存儲於整個集羣當中,極有可能會將整個Redis集羣壓垮,進而導致所有主播的業務都無法使用。基於重要性隔離的思路,就需要將這類熱門主播的數據,存儲於獨立的Redis集羣,並將副本數調整到較高的數量,進而滿足大壓力的要求。雖然副本數增加,但因爲熱門主播數量畢竟有限,因此整體的存儲成本未必會增加許多。而一般的主播雖然訪問量較小,但其基數較大,繼續沿用之前的三副本策略,也能夠滿足需求。

以下是單一業務場景內,基於重要性不同進行隔離的例子:

  • 付費用戶和免費用戶隔離

  • 廣告系統中,將公益廣告和付費廣告隔離

  • 冷熱數據的隔離

  • 將正常請求和爬蟲請求、安全掃描、壓測請求、灰度請求等進行隔離

讀寫隔離,避免突發的讀/寫請求影響服務

對於任務調度系統來講,必然會有任務執行結果查詢的需求。因此,在接入調度層,將查詢類需求,全部調度到特定的集羣上,即可以滿足用戶的各類查詢需求,也不會因爲查詢壓力過大而導致任務發起功能受到影響

類似的,讀寫隔離應用最廣的場景是在數據庫中。通過讀寫隔離,可以大幅降低數據庫的故障率,是數據庫優化中最常見也是最重要的手段之一

地域隔離,最小化故障的影響範圍

如果北京聯通網絡異常,不太會影響到濟南聯通用戶;中西部地區的地震,其震感也不會傳導到華北等區域;而每年的洪災,也主要集中在長江中下游地區;華中地區夏季電力供應緊張,也不會要求華北地區拉閘限電。

地域隔離,主要是參照故障域的概念(有些地方叫做隔離域),處於一個地域的用戶,共享該地域的基礎設施如骨幹網,運營商等,同時自然災害也會呈現地域範圍的特點。將一衆共享同一故障域的用戶,其流量集中在一個集羣中進行處理,既可以最小化故障的影響範圍,同時,也能夠降低故障處理的難度。

在實際的執行中,不同公司的地域劃分不盡相同,其劃分標準不僅僅會考慮故障域,同時也會考慮到各地的請求分佈,時延以及IDC佈局等因素。

類似的,一個公司的基礎設施如DNS、LB等也都是按照機房粒度進行部署的,也可以理解是一種地域隔離的場景。

隊列隔離

在任務執行層,是以機房爲粒度,處理該機房所有類型的任務,因此勢必會出現一個實例要處理各種類型的任務,如果所有的任務使用默認的隊列,那麼一旦某類任務因爲種種原因開始積壓,在達到隊列長度限制後,後續新增的任務就會被丟棄,這時候,是這個機房的所有任務均被無差別的傷害了。如果對每類任務創建一個隊列並基於任務類型的特點和重要性設置隊列長度,則能夠有效避免單一任務類型的異常導致所有類型任務失敗的問題

資源隔離,避免單機多進程間的資源競爭

這是最基本的隔離要求,當下的硬件設備,手機都8核8G內存了,就更別說服務器了。因此單一進程很難佔滿整個服務器的資源,這樣,勢必就會出現混部需求。那麼兩個進程部署在同一個服務器上,可能就會出現各種資源競爭了。可能某個進程因爲流量突增,把CPU資源佔滿這都是家常便飯了,但你把CPU資源耗光了,你讓人家怎麼活。

因此資源隔離技術,就開始應運而生,對CPU、內存、磁盤空間、IO、網卡等進行隔離,從而避免單個物理機上多個進程間互相影響。較爲簡單的有通過taskset、ulimit等命令對CPU和MEM進行限制,也有更好的Cgroup的隔離,當然,直接上Docker這種解決方案更爲方便一些。

數據隔離

在進行了基於租戶、重要性、地域隔離之後,對應的隔離的集羣,其數據也需要做到完整的隔離,避免單個集羣異常後,導致所有集羣的數據被破壞而無法使用,進而實現了真正的多活。

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