函數計算性能福利篇(一) —— 系統冷啓動優化

背景

函數計算是一個事件驅動的全託管 serverless 計算服務。使用函數計算構建應用,用戶只須要專一於實現應用層的邏輯實現;服務器等基礎設施的容錯、伸縮以及運維工做由平臺來完成。所以用戶能在很短的時間內實現彈性高可用的雲原生應用。python

函數計算在容器中執行用戶函數代碼,這樣的環境咱們稱爲函數實例。實例的生成須要一些額外的系統準備工做,好比選擇執行函數的引擎,下載用戶的代碼,啓動容器,加載函數等等。若是請求的調用鏈路裏包含了上述環節,咱們就稱之爲冷啓動。實例一旦生成,會持續服務請求;當一段時間內沒有請求後,系統將回收實例。所以,冷啓動一般發生在函數首次調用或者負載升高須要更多的實例來處理對應的請求。服務器

"冷啓動"對於毛刺敏感的業務會顯得不那麼友好,因此冷啓動的優化對於函數計算在延時敏感型場景中的應用尤其重要。網絡

系統架構

在探討調度優化以前,咱們先簡要介紹函數計算的架構以及調度方式,以下圖所示。架構

clipboard.png

API 服務層完成身份驗證,元數據的讀寫等功能。同步調用函數時,API 服務模塊從資源調度模塊獲取可用的函數執行引擎併發送請求,函數執行引擎根據函數相關信息準備執行所需環境,啓動容器進行計算,最後取回結果。異步調用函數時,則將事件寫入到消息隊列後即返回。由事件分發模塊分發事件,整個流程和同步調用相似。併發

資源調度模塊主要負責函數計算分佈式系統的負載均衡和實時彈性伸縮。當一個用戶請求達到時,資源調度模塊進行第一層調度——分配函數執行引擎,而後在函數執行引擎中進行第二層調度——分配函數實例,進而纔開始執行用戶函數。而當用戶一段時間內再也不請求,調度系統就會自動回收函數實例和函數執行引擎資源。以下爲用戶請求處理資源調度流程:負載均衡

clipboard.png

爲了保證用戶請求使用的資源,一個函數實例只能同時服務一個請求,因此在用戶請求併發較大的狀況下,系統會調度更多的資源來消費該用戶的請求。less

如架構圖所示,系統層的"冷啓動"就是從函數執行引擎的獲取到函數實例建立的整個過程,主要的步驟以下:運維

clipboard.png

而冷啓動的快慢受限於不少狀況,主要因素有用戶代碼大小、網絡因素、runtime 環境因素等,因此,對於實時性要求高的業務場景來講,冷啓動的存在是不友好的。python2.7

調優策略異步

冷啓動問題致使了大量併發到來的時候,毛刺加重,根源在現存的實例調度方式沒法快速響應請求而引發請求在整條鏈路中長時間處於系統新資源的分配等待中。

因此,要提升實例調度速率、快速響應請求,減小排隊請求數,主要着手於以下兩個方面:

一、加快空閒實例投入使用,提升利用率;

二、在峯值到來時,加快新實例生成,增長實例儲備。

加快空閒實例投入使用速率這一點,能很大程度上減小請求在鏈路上等待冷啓動的時間,從而加快請求被處理的速率。在用戶函數邏輯執行較快的狀況下,實例可以被快速釋放,若是此時一個正在等待冷啓動的請求可以探測到已經有實例進入空閒狀態,那麼就會被處理。而以前的冷啓動則轉入後臺繼續進行,生成新的實例,增大實例儲備,應對更多的請求處理。

另一方面,由於用戶的資源配額在系統層面有限制,好比在超大併發的請求下用戶可能會遇到 ServiceUnavailable 錯誤。而調度策略上若是可以加快空閒實例投入使用的速率,那麼實際上也減小了冷啓動的次數,即減小了對資源配額的開銷,增長資源利用率,從而減小了被系統流控的可能。

調優結果

根據用戶實際使用場景,咱們設計以下兩種測試case來驗證調優效果:

• 負載持續增長模式

• 波峯 burst 模式

測試函數的特性以下:

• 函數自身邏輯運行時間爲 100ms;

• 函數代碼包大小爲 50MB;

• runtime 爲 python2.7;

• Memory 爲 3GB 。

這樣的函數,若是帶有冷啓動,單次端到端的請求 latency 在 1.7s - 3s,不帶冷啓動的請求端到端 latency 在 105 - 120ms。

負載持續增長模式

該模式下,用戶的請求在一段時間內會持續增加。設計請求行爲以下:

• 每波請求併發數翻倍遞增: 1, 2, 4, 8, 16, 32;

• 每波請求的時間間隔爲 10s。

TPS狀況以下,增加率爲100%:

clipboard.png

優化先後對比

10s 聚合的 latency 指標以下監控:

優化前, 平均 latency 在 1000ms 左右,而99%的請求 latency 均在 1.8s 以上。

clipboard.png

優化後,平均 latency 爲 200ms 如下(排除第一個徹底冷啓動),99% 的請求 latency 大部分在 200ms 左右,較以前降低一個數量級。

clipboard.png

單個請求狀況分析

更直觀的分析,咱們把每個請求的端到端 latency列出來比較,以下圖。每一波請求中,都有一半的請求可以直接使用前一波請求現存下來的實例,而另外一半請求都須要等待新的調度。明顯看到,舊的調度策略上,這一半請求幾乎所有都在傻傻等待處於徹底冷啓動狀態;新的調度策略中,明顯看到這一半請求都被調度到了提早釋放的實例上被處理,從而大大優化了毛刺狀況。

優化前:

clipboard.png

優化後:

clipboard.png

波峯 burst 模式

波峯burst模式是指用戶請求比較平穩,可是會有忽然的波峯流量場景。設計請求行爲以下:

• 每波請求時間間隔 10s;

• 每波平穩請求數 2;

• burst 請求數 20;

TPS請求以下,burst 流量猛增 10 倍:

clipboard.png

優化先後對比

10s 聚合的 latency 指標以下監控:

對比99%的請求 latency,毛刺降低了整整一倍多。

優化前

clipboard.png

優化後

clipboard.png

單個請求狀況分析

按處理順序,咱們羅列出優化前和優化後處於 burst 時期 20 個請求的每個 latency 的狀況,以下表。不難發現,除了最前面的兩個請求直接使用了現存的 2 個實例,其餘請求所有都是須要等待調度的。優化前,全部的請求都在徹底等待冷啓動;而優化後,不難發現,每兩個請求的 latency 處於相同的水平,而先後兩組之間相差 100ms (正好是函數執行時間),從而說明新的調度方式有效的複用了已有的"熱"的容器。

clipboard.png

實際在線用戶請求優化結果

對在線某一用戶的實時流量跟進分析,看到優化先後明顯對比,以下圖所示。優化前 TPS 在某一時間點從 11 上升到25,此時 99% 的 latency 出現一個明顯的毛刺現象。在2個小時以後,優化開關打開,某一時間點 TPS 達到了 32,此時 latency 無明顯波動。

clipboard.png

總結

綜上數據分析,在典型的負載變化狀況下,冷啓動對 99% 的請求 latency 的影響已經忽略不計,本次調度上的調優大大改善了函數計算在延時敏感場景下的表現。

將來調度優化

下一步調度優化工做正在緊鑼密鼓進行中,先不劇透,敬請期待!

本文做者:清宵

閱讀原文

本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索