前言
今年一直在做的事情就是成本優化,今天分享的是如何打造一個彈性可伸縮服務。
why? 為什麼需要彈性伸縮?
一個網站,通常流量大小不是每時每刻都一樣,有高峰,有低谷,如果每時每刻都要保持能夠扛住高峰流量的機器數目,那麼成本會很高。一個誘人的想法就是根據流量大小自動調節機器的數量,這就需要我們開發彈性伸縮服務。
How?怎麼實現彈性伸縮?
我們公司使用的是阿里的ECS,而它提供彈性伸縮組機器,按秒計費,可以隨時申請隨時釋放,它是我們能夠進行彈性伸縮的最基本條件。由於這個How內容較多,接下來就詳細說一下這個How如何實現。
彈性伸縮服務
這塊著實是做了不少的工作,前前後後經歷了大半年的時間,接下來一一詳述。
工作模式由“推”改“拉”
我們的彈性分配策略依賴實時的qps,需要實時的獲取流量大小,所以必須能夠在某個地方獲取當前請求的QPS,自然而然會想到使用訊息佇列,我們可以使用佇列提供的介面,獲取某段時間內的qps,並根據速率調整我們的機器服務數,這涉及到服務的改造。由於我們的一些服務都是以RPC呼叫進行互動(即“推”模式),所以勢必要改造這些服務,使其主動從佇列中拉取訊息並處理。如下圖所示。
服務拆分,機器降配
我們的計算服務使用的高配置機器(16核16G),而阿里雲伸縮組的機器配置很低(最高配置4核,記憶體大小可調),所以一些計算型服務需要拆分,使其能夠在低配機器執行。如下圖,是我們做的一個拆分示意。
服務快速部署
由於需要隨時增加和減少機器,這需要服務有快速部署上線和下線的能力,所以可以使用docker。具體使用方法本文不贅述。
日誌收集
由於彈性伸縮服務隨時上下線,但是日誌不能扔。需要日誌收集服務跟隨業務服務一同部署,同樣可以利用docker,日誌隨時收走。
實時分配演算法
完成了如上3個基本工作,接下來就好辦多了,我們設計一個彈性分配演算法:根據佇列中進去的訊息速率來決定機器數目。
每個服務都需要有一個配置檔案
[strategy]
#一個服務能夠扛多少qps
speed_ratio = 2.5
#部署一個服務大概需要多少秒
start_time = 300
#每次部署多少個,至少為1
incr_num = 2
#固定機器有多少個
persistence = 16
演算法大致流程:
- 取一段時間間隔內佇列中訊息速率,假設為A。
- 獲取當前正在執行的服務數S。
- 計算當前已經啟動的服務(固定+彈性分配)能夠扛住的速率B(B=S*speed_ratio)。
- 假設佇列中速率波動幅度C(通過觀察流量波動寫死的固定值)。
- 如果A>B+C,則申請新機器,根據配置檔案,申請incr_num個機器,並部署服務。
- 如果A<B-C,則釋放機器,根據配置檔案,釋放incr_num個機器,並下線服務。
- 注意要保持至少persistence指定的機器數,這些機器不能釋放,它主要是應付平時低谷時的流量。
問題:
- 可不可以根據佇列中unack的數目來分配機器?
答案是不行。能夠唯一表示當前請求大小的指標只有qps,而我們服務可以提前知道的只有效能資料:即單臺機器能扛多少qps,而不是單臺機器能夠減少多少個unack。此外如果使用unack為分配指標,當服務出現bug,大面積當機時,unack累積非常快,會導致演算法分配無限多的機器,而此時解決問題的正解為:回滾服務-查詢bug-修正-上線,而不是分配更多的機器,因為新分配的機器部署的服務可能也會當機。 - 如何應對流量突增?
本演算法主要應對正常情況下的機器分配,對於突增流量分為兩種情況。1:正常可預測的突增(比如淘寶雙11,雙12),這種情況下我們可以先提前準備好大量固定機器,然後把配置中的incr_num調的儘可能大,這樣只要流量上漲,可以一次增加幾百臺甚至上千臺機器扛過突增流量。2:異常突增,這種情況對於各種部署方式的服務(即使隨時隨地保證扛過平時正常情況下的流量峰值)都可能造成危害,並不是只有彈性分配的服務專有,這個時候的正解的是防攻擊、流量過濾、降級。 - 阿里雲機器分配集中造成介面失敗
當短時間內頻繁呼叫阿里雲的機器分配介面,會返回錯誤資訊,造成分配失敗。解決方法為,呼叫加入時間間隔(比如每隔1s呼叫一次機器分配介面),並且進行失敗重試。 阿里雲ECS啟動失敗
有的時候機器申請成功,但是啟動失敗,情況有兩種,1:啟動時間過長,2:根本啟動不起來。解決這兩種問題的方法為,嘗試啟動一段時間,超過一定時間(比如start_time)後果斷放棄,重新申請新機器,防止整個服務啟動過程過長跟不上qps的上漲速度。總結
如今,彈性伸縮服務穩定執行半年有餘,節省了大概60%~70%的機器成本,加上前面兩個演算法優化《我是如何利用跳錶優化搜尋引擎的?》,《最長公共子序列與最小編輯距離-你有更快的演算法麼?》,使得我們負責的服務機器成本下降了80%以上。這也導致了阿里雲的小夥伴對我們產生了質疑,懷疑我們正在逐步把服務遷出阿里雲,但是這真的是冤枉了我們,誰規定使用阿里雲的ECS就不能對服務進行優化了。對於同樣使用雲ECS的小夥伴,可以考慮用彈性伸縮節省成本,這將是一件很有意思並且富有挑戰的事情。