最新進展:Serverless 冷啟動優化技術

2023-07-18     InfoQ

原標題:最新進展:Serverless 冷啟動優化技術

作者 | 華為雲 Serverless 團隊

策劃 | 褚杏娟

問題背景

Serverless 計算也稱伺服器無感知計算或函數計算,是近年來一種新興的雲計算編程模式。其致力於大幅簡化雲業務開發流程,使得應用開發者從繁雜的伺服器運維工作中解放出來(例如自動伸縮、日誌和監控等)。藉助 Serverless 計算,開發者僅需上傳業務代碼並進行簡單的資源配置便可實現服務的快速構建部署,雲服務商則按照函數服務調用量和實際資源使用收費,從而幫助用戶實現業務的快速交付 (fast built & Relia. Deliv.) 和低成本運行。

在當前階段,業界公認的 Serverless 計算的準確定義應該為「FaaS+BaaS」,即 Function-as-a-Service 同 Backend-as-a-service 的組合。Serverless 計算改變了用戶使用雲的方式,為了實現細粒度的資源供給和高度彈性的擴縮容能力,Serverless 計算提供了無狀態函數的編程抽象,即將用戶的應用程式構建為多個無狀態的函數集合,並通過中間存儲、BaaS 等業務組件交互,繼而構建完整的雲應用。

然而,Serverless 計算的無狀態函數編程在帶來高度彈性和靈活性的同時,也導致了不可避免的冷啟動問題。由於函數通常在執行完請求後被釋放,當請求到達時,如果沒有可用實例則需要從零開始啟動新的實例處理請求(即冷啟動)。當冷啟動調用發生時,Serverless 平台需要執行實例調度、鏡像分發、實例創建、資源配置、運行環境初始化以及代碼加載等一系列操作,這一過程引發的時延通常可達請求實際執行時間的數倍。相對於冷啟動調用,熱調用(即請求到達時有可用實例)的準備時間可以控制在亞毫秒級。

在特定領域例如 AI 推理場景,冷啟動調用導致的高時延問題則更為突出,例如,使用 TensorFlow 框架的啟動以及讀取和加載模型可能需要消耗數秒或數十秒。

因此,如何緩解 Serverless 函數的冷啟動問題,改善函數性能是當前 Serverless 領域面臨的主要挑戰之一。

從研究思路上看,目前工業界和學術界主要從兩個方面入手解決冷啟動問題:

業界最新進展

在本篇文章中,我們首先從提高實例啟動速度方面介紹下業界的前沿進展。

提高實例啟動速度

當冷啟動發生時,Serverless 平台內部實例的初始化過程可以劃分為準備和加載兩個階段。其中,準備階段主要包括控制面決策調度 / 鏡像獲取、Runtime 運行時初始化、應用數據 / 代碼傳輸幾個部分。而加載階段位於實例內部,包括用戶應用框架和代碼的初始化過程。在工業界和學術界公開的研究成果中,針對實例啟動過程中的每個階段都有大量的技術手段和優化方法。如下圖所示,經過優化,實例冷啟動的準備階段和加載階段時間可被極大地縮短。

下面列舉了一些近年來發表在計算機系統領域知名會議的相關工作,主要可以分為五個方面:

  • 調度優化 / 鏡像快速分發 / 本地池化:例如利用文件級鏡像緩存復用機制和並行化鏡像構建技術,加快容器構建速度 FAST-BUILD [MSST'19];阿里雲基於樹結構的跨節點快速鏡像分發 FaasNet [ATC'21];AWS 基於 Block 和分布式多級緩存的鏡像分發策略 [Arxiv'23];Pod 池 + 特化實例跳過鏡像傳輸 [華為雲 FunctionGraph]。其中,快速鏡像分發依賴於 VM 節點的上 / 下行網絡帶寬,Pod 池特化技術則是典型的以空間換時間的做法。
  • 輕量級虛擬化 / 安全容器:例如針對傳統容器 Docker 的精簡優化工作 SOCK [ATC'21];更側重安全性的輕量級虛擬化技術(Kata Containers, gVisor 等);基於安全容器的進一步的精簡優化工作 (Catalyzer [ASPLOS'20], REAP[ASPLOS'21])。通過裁剪優化,安全容器的啟動時延最快可以被壓縮至亞毫秒級。
  • 數據共享 / 跨節點傳輸優化:例如基於 RDMA 共享內存減少跨節點啟動過程的數據拷貝 RemoteFork [OSDI'23];或者利用本地代碼緩存跳過代碼傳輸 [華為 FunctionGraph, 位元組 ByteFaaS 等]。基於 RDMA 技術的跨節點數據傳輸時延可降低至微妙級。
  • 用戶代碼精簡 / 快速加載:例如針對 Java 語言的 JVM(Java Virtual Machine)運行時優化技術 [FunctionGraph];以及針對 Python 運行時庫的裁剪優化工作 FaasLight [arxiv'23]。通過特定的優化,JVM 啟動時間可由數秒降低至數十毫秒,而 Python 代碼的啟動加載時延可降低約 1/3。
  • 其它非容器運行時技術:例如 WASM(即 WebAssembly)技術以及針對 WASM 的內存隔離方面的優化工作 Faasm [ATC'20]。相比容器化技術,直接以進程和線程方式組織運行函數,可在保證低開銷函數運行的同時具備高度靈活性。

接下來,針對上述 5 個方面的優化工作進行詳細介紹。

鏡像壓縮 / 快速分發 / 本地池化

  • 快速請求 / 實例調度。

在 Serverless 場景下,由於函數的體積更小、動態性更高,Serverless 平台在負載高峰時也會面臨較大壓力。因此主流的 Serverless 服務商通常採用「大小流區分的負載均衡 + 本地優先調度」的設計來實現請求的快速分發,降低調度時延。即在流量較小的時候,採用工作負載聚合的方式來分發請求,減少集群資源使用;在流量較大的時候,通過一致性 hash 或輪詢等方法將請求快速映射到後端節點,從而降低排隊時延。這種「自頂向下」的調度設計簡單,易於實現,但是在超大規模的函數並發場景下仍可能面臨頂層控制器的性能瓶頸問題,因此,根據實際場景架構適當地探索「自下而上」的調度框架設計將有助於緩解該問題。

此外,也有相關研究人員提出可將 Serverless 集群劃分為多個小型的 worker 池,每個 worker 池由一個單獨的 semi-global 子調度器管理,降低各個調度器的壓力,從而改善調度時延[1]

  • 鏡像壓縮與快速分發。

鏡像壓縮與快速分發。

在 Serverless 平台中,用戶的函數鏡像通常被存儲在 cluster-level 的鏡像倉庫,節點(通常指虛擬機 Virtual Machine, 簡稱 VM)創建實例時首先需要將鏡像文件通過網絡傳輸到對應的節點(1 個 100MB 的鏡像文件從傳輸到容器創建完成需要耗費約 20 秒 [阿里雲,Borg])。在這個過程中,影響鏡像傳輸時延的因素主要為鏡像體積和節點網絡帶寬。因此,Serverless 平台通常會採用鏡像壓縮技術縮小鏡像體積,例如開源工具 fastfreeze[2] 除此之外,為了解決節點網絡帶寬受限導致的拉取鏡像時間過長的問題,阿里雲的 FaasNet[29] 工作提出了一種基於樹狀網絡的跨節點鏡像分發策略,即通過根節點的 VM 將鏡像下發給子節點(通常為 2),子節點獲取到鏡像後以同樣方式擴展到更多的節點,從而充分利用節點的上 / 下行帶寬實現短時間內快速擴容大量實例的目的。

此外,在節點中設立鏡像緩存也是一種有效的方法,可以在一定程度上減少鏡像傳輸操作,例如 AWS Lambda 採用了一種基於 Block 的鏡像切分和緩存方法[30],相比於基於 Layer 的鏡像構建方法,基於 Block 的鏡像切分粒度更細,可以極大地提高鏡像復用度,同時這些鏡像 Block 被存儲在由本地緩存,分布式緩存和 S3 組成的三級緩存系統中,從而實現快速鏡像分發和實例創建速度。

  • Pod 池與實例特化。

類似於本地鏡像緩存的概念,在集群中預留包含函數運行時基礎鏡像的實例(即具備用戶代碼運行環境的熱容器)也是一種常用的「以時間換空間」的做法[3]這種方法在集群中建立 Pod 池,預先啟動一定數量的具有不同資源規格和語言運行時的實例(例如 Java, Nodejs, Python 等)。當冷啟動調用發生時,Serverless 平台可以快速從 Pod 池中取出所需要的實例進行特化(掛載代碼文件並加載執行),從而跳過鏡像獲取和運行時環境啟動階段,實現快速創建實例的目的。

生產環境下的數據測算顯示,Node.js 實例特化時的啟動時間僅需 15ms。然而,在 Pod 池中預留實例會占用大量集群資源,增加雲供應商的服務成本。如何權衡用戶函數性能和 Pod 池預留成本也是該類方法所面臨的一個問題。

輕量級虛擬化 / 安全容器加速

  • 傳統容器加速。

相比於傳統的 VM 動輒數十秒至數分鐘的創建時間,容器的啟動速度和運行時開銷更小,因此 Serverless 平台通常使用容器技術來隔離用戶的函數實例,例如 Docker[4] 然而在考慮函數的實際運行性能時,Docker 之類的傳統容器設計包含了很多不必要的運行開銷,因此並不適合直接作為函數沙盒環境。為此,SOCK 工作[5] 基於 Linux container 的設計分析了 Docker 文件系統和網絡模塊的性能瓶頸,通過裁剪不必要的啟動項並對網絡模塊進行特定優化,大幅降低了 Docker 容器的內核擴展開銷(超過 18 倍)。

  • 兼顧安全性的輕量化容器或 microVM。

在非 Serverless 的雲場景中,VM 的強安全隔離性使其在雲租戶的服務部署中扮演著重要角色。在 Serverless 場景中,租戶函數間的安全隔離性也同樣重要。為了彌補傳統容器的安全性不足的問題,研究學者嘗試將 VM 的高安全性同容器技術進行融合,例如 Intel 和 HyperHQ 團隊主導的 Kata Containers 項目[6] ,Kata Containers 的本質是一個精簡後的輕量級虛擬機,在其上面運行著用戶的容器進程。為了減少暴露給容器進程的攻擊面,Kata Containers 基於傳統的虛擬化技術通過硬體虛擬出一個 microVM,而 microVM 里則運行了一個裁剪後的 Linux 內核來實現進程間的強隔離(註:裁剪即屏蔽掉非必須的系統調用接口)。AWS Lambda 的 Firecracker[7] 也採用了類似 microVM 的技術路線來實現多租戶隔離性和函數性能間的權衡。

除此之外,gVisor[8] 則是谷歌推出的輕量級安全容器項目。gVisor 採用了另一條技術路線,其核心原理是給容器進程配置一個類似「Guest Kernel」的極小的「獨立內核」(即守護進程),通過攔截容器進程的系統調用來向宿主機 OS 發起有限的、可控的系統調用,從而提高系統安全性。由於這個獨立內核運行在用戶態,免去了大量地址空間轉換和內核態切換的操作,因此具有較小的性能開銷和更好的靈活性,同時又達到了將容器和宿主機 OS(Operation System)隔離的目的。

無論是 Kata Containers 類容器技術,還是 gVisor 安全容器技術,它們實現安全容器的方法在本質上是殊途同歸的。這兩種技術都採用了「系統分層」的設計思想,即向容器進程分配了一個獨立的「作業系統內核」,從而避免了讓租戶的容器直接共享宿主機的內核。這樣,容器進程的攻擊面就從整個宿主機內核變成了一個極小的、獨立的、以容器為單位的內核,從而有效解決了容器進程發生「逃逸」或者奪取整個宿主機控制權限的問題。

  • 針對安全容器的進一步加速。

儘管 gVisor 之類的安全容器極大地彌補了傳統容器的安全隔離性不足的問題,然而,安全性提高的同時也帶來了額外的性能損失,例如攔截調用會增大啟動和運行開銷。為此,Catalyzer[9] 基於快照技術和狀態重用技術針對 gVisor 安全容器的啟動過程進行了進一步優化,大幅縮短了 gVisor 的啟動時間。Catalyzer 的設計思想是「避免從零開始啟動」,即通過檢查點和快照恢復機制跳過啟動過程關鍵路徑上的初始化(零初始化),從而實現快速啟動的目的。此外,Catalyzer 還提出了一個新的作業系統原語 sfork 技術,通過直接重用正在運行的沙箱實例的狀態來進一步減少啟動延遲。評估表明,Catalyzer 在最佳情況下可將 gVisor 的啟動延遲降低至<1ms。

值得注意的是,儘管 Catalyzer 實現了「用戶角度」的快速啟動,但是其並不能保證內部所有的系統狀態都為最新可用狀態,為此,Catalyzer 採用了按需加載機製作為補救措施,即通過在後續運行過程中逐步恢復用戶級內存狀態和系統狀態來最終恢複函數性能。該領域的另一項研究工作 REAP[10] 發現 Catalyzer 的設計機制帶來的開銷並不是可忽略的,運行過程中頻繁的系統缺頁在最壞的情況下會導致時延提高接近一倍。為此,REAP 提出了一種頁面預加載機制,通過識別函數運行過程中所需的必要工作集並提前載入內存,從而顯著改善了 Catalyzer 的缺頁開銷問題。

註:該部分涉及的一些術語可以參考擴展知識部分進行了解。

數據共享 / 傳輸優化

  • 基於 RDMA 的跨節點分發。

在 Serverless 平台內部,藉助網絡進行跨節點數據、代碼或者狀態的傳輸也是一個較為耗時的操作,尤其是在大量實例並發創建的場景中,遠程容器初始化的頻繁需求進一步加劇了這種現象。為了解決該問題,MITOSIS[11] 工作在支持 RDMA 的作業系統中實現了一個新的作業系統原語,即 remote fork,remote fork 允許不同節點的作業系統之間通過 RDMA 技術進行內存共享映射,從而實現快速遠程內存讀取和跨節點容器間的數據傳輸。MITOSIS 可以大幅降低跨節點的實例初始化時間,從單個實例跨節點複製 10,000 個新實例的時間小於 1 秒。然而,MITOSIS 的實現涉及對作業系統內核代碼的大量修改,同時還依賴於 RDMA 硬體的支持,這些都使得它在實際部署中會面臨著挑戰。

除此之外,新型網絡設備例如 DPU 硬體等也提供了基於 RDMA 的高速跨節點互聯的機制,即通過內存映射和共享來加快網絡數據傳輸速度,這些硬體都可以被探索用於改善 Serverless 平台跨節點數據傳輸的效率。

代碼加載延遲優化

前面章節提到的加速技術都集中在系統層和框架層,在應用層,容器運行時環境的啟動和函數代碼的加載也在冷啟動延遲中占據了相當的比例,尤其是對於機器學習等應用,運行庫的加載和框架的啟動時間可達數秒[12]值得注意的是,即便調度時延和容器初始化時間再短,長的用戶側啟動時延仍然會使得冷啟動問題變得棘手。

為此,Serverless 平台通常會針對函數的運行時進行優化,例如華為的 FunctionGraph 內部針對 JVM 的優化技術可將簡單 Java 應用的初始化時間降低至數十毫秒。在學術研究領域,也有針對 Python 函數運行時庫的裁剪優化工作例如 FaasLight [13],FaasLight 的核心思想是「在函數啟動過程中儘可能地只加載少量運行必需的代碼」。為了實現這一目標,FaaSLight 構建了函數級調用圖來識別和篩選與應用程式功能相關的代碼,並對非強相關的代碼(即可選代碼)進行按需加載,避免必要代碼識別不準確導致應用失敗。實驗結果顯示 FaaSLight 可最高降低 78% 的 Python 代碼加載延遲,平均延遲降低約 28%。

非容器化運行時技術

  • WASM 運行時。

WSAM(即 WebAssembly)[14]技術也是近年來一種新興的編程運行時,可以用在雲場景中代替部分容器運行時來部署用戶函數。WSAM 的運行原理類似於 JVM,可直接運行在宿主機 OS 上,其支持多種語言編碼,用戶函數代碼在運行前需要編譯成 WASM 運行時,繼而實現跨平台運行。WASM 同樣提供了高性能沙盒環境,並具備高靈活性和一定的安全性。

儘管 WASM 有諸多優勢,但是也存在著諸如內存隔離性弱這樣的問題,因此並不能完全替代現有的容器技術,而是在大多數情況下與 Docker 容器技術互相配合使用。據悉,基於 WASM 的函數計算平台目前在國內著名的雲計算廠商內部都有布局,有的平台已經推出了初步的商用版本。

在研究領域,也有針對 WASM 的內存隔離性開展優化的工作,例如 Faasm[15]Faasm 提出了一個新的隔離抽象「faaslets」,並基於 WebAssembly 的 software-default isolation (SFI) 機制實現了函數間的內存隔離。此外,在 faaslets 的設計中,來自不同租戶的多個函數可共享相同的內存地址空間,這樣就可以避免函數間通信時大量的數據交換所導致的性能開銷。faaslets 還可以與 Linux cgroups 機制配合使用,繼而實現例如 CPU, 網絡資源等資源的隔離。這些優化措施可以使得 Faasm 獲得接近 2 倍的性能加速同時降低內存使用 10 倍以上。

值得注意的是,上述的這些技術手段,無論是容器技術、VM 技術還是 WASM 技術,它們本質上都是以進程方式運行在伺服器內部,因此都可以藉助快照技術(例如 Linux CRIU[16])實現更快的系統狀態保存和恢復,從而進一步加快初始化速度。

  • Unikernal 技術。

從前面列舉的一些技術的特徵可以看到,函數運行環境的啟動速度和安全性之間總是存在一個折中,即為了改善安全性必須添加一些中間層來增強系統的控制能力,然而中間層的引入勢必會降低系統啟動速度。那麼是否存在能夠同時滿足快速啟動和高安全性的技術方案呢?答案就是 Unikernel[17]Unikernel 顧名思義,是指定製化的作業系統內核。它的核心思想是將「用戶程序和運行必需的庫文件統一編譯成為一個特殊的、單地址空間的內核鏡像」。由於只有一個作業系統進程(這裡不再有用戶態和內核態的區分),同時編譯時去掉了不必要的運行庫,所以 Unikernel 運行速度可以非常快。如果將 Unikernel 加載到 VM 運行,也可以實現高安全性和隔離性。

但是 Unikernel 的缺點也十分明顯,即靈活性差。由於 Unikernel 是與某種語言緊密相關的,所以一個 Unikernel 只能用一種語言編寫,如果用戶程序有所變動,則需要重新編譯 Unikernel,之後加載並重啟 VM。同時,Unikernel 的編碼門檻也很高,這與 Serverless 計算的簡化編程的設計初衷相悖,也是其難以被廣泛應用的原因之一。

擴展知識介紹

傳統裸金屬、VM 和容器技術的區別(在體系結構中所處的層級圖、用戶態和內核態概念)

在計算機的體系結構中,各種物理設備例如 CPU 處理器、磁碟、網卡等首先組成計算機的物理硬體,也成為「裸金屬伺服器」。裸金屬伺服器的運行需要作業系統的支持,比如我們熟知的 Linux 作業系統。藉助作業系統就可以編寫運行各種軟體例如網頁伺服器、資料庫等來提供外部服務。

在雲計算場景中,通過虛擬機共享資源是早期雲服務商的主要做法。藉助虛擬化技術例如 Microsoft hyper-V、Citrix Xen 等,可以將裸金屬伺服器虛擬為多個單獨的 VM,VM 間共享裸金屬伺服器(也稱宿主機)的物理資源,但是在每個 VM 內對租戶來說是獨占資源的(例如 CPU,內存和磁碟)。實現這一目的的手段就是藉助 Hypervisor(即虛擬機監視器)來管理劃分各個 VM 使用的物理資源,實現高安全性和隔離性。Hypervisor 的內部比較複雜,涉及到系統調用、物理地址劃分等操作,這裡不再展開。

在 Hypervisor 劃分出來的每個 VM 內部都可以運行一個獨立的作業系統(也稱 Guest OS),相比於 VM,宿主機的作業系統則稱為 Host OS。Guest OS 對於租戶來講是一個類似本機的作業系統,包含運行程序所需要的各種系統調用庫和可執行文件,具體的層級劃分如左側子圖所示。

容器則是相比 VM 更為輕量級的虛擬化技術,例如 Linux Container(LXC)和基於 LXC 實現的 Docker 等技術(右側子圖所示)。容器的本質是一個用戶態進程,因此它可以直接運行在 Host OS 上,我們稱之為 Container Engine。Container Engine 可以創建出多個容器給租戶使用,並通過 Linux cgroups 等機制實現 namespace 和租戶資源(例如 CPU 和內存)的隔離。不同於 VM 的運作方式,容器內部並沒有 Guest OS,而是復用底層的宿主機的作業系統,通過創建文件系統和加載用戶程序運行所需要的庫來實現運作。因此,相比 VM 來講,容器的運行方式更加輕便靈活,但是安全性較差(例如某個租戶的程序可能導致宿主機 OS 被攻擊,繼而使得其他租戶的程序也無法運行)。為了解決這個問題,早期的雲廠商做法通常是將容器部署在 VM 中,從而實現安全性和靈活性的折中取捨。

註:作業系統通常運行在內核態,權限最高,而租戶程序則運行在用戶態。用戶態程序執行系統調用需要切換至內核態,執行完後再切換回用戶態。

VM、容器和 Unikernel 對比 (靈活性,啟動速度和隔離性)

前面我們提到,Serverless 平台中函數運行的技術路線有 VM,容器和 Unikernal 幾種或是它們的組合。無論哪種方式,基本都在圍繞技術方案的靈活性(Flexibility),啟動速度(Startup Latency)和隔離性(Isolation Level)進行權衡。

下圖總結並列出了這幾種虛擬化方案的對比:

可以看到,VM 具有高隔離性,靈活性較好,但是啟動速度最慢。

而傳統容器以用戶態進程運行,具有高度靈活性,較快的啟動速度,但是隔離性較差。

安全容器是針對傳統容器進行了裁剪和進一步控制,具有較高的隔離性,但是啟動速度和靈活性有所降低。

WASM 技術類似 JVM 的設計理念,編譯完成後即可運行,因此具有更快的啟動速度和較高的靈活性,但是隔離性較差。

Unikernel 採用了定製化 OS 和單地址空間,因此可以兼顧快的啟動速度和高隔離性,但是靈活性很差。

不難發現,這三個要素的關係非常類似於分布式系統的 CAP 原理,即一致性 (Consistency),可用性 (Availability) 和分區容忍性 (Partitiontolerance) 在分布式系統中最多只能同時實現兩點,不可能三者兼顧。

下表展示了各虛擬化技術的啟動延遲等指標的具體對比:

註:表格數據引用出處 The serverless computing survey[31]

小結

在實際場景中,不同的函數計算廠商往往有自己的虛擬化技術方案,往往根據自家產品的業務線,技術積累或者客戶群體需求進行綜合考慮。在出於商業意圖或者個人需要搭建函數計算平台進行研究時,可以根據安全性需求制定自己的技術路線。例如個人或者高校團體研究可以歸類為非安全性場景,基於目前的"VM+Kuberneters (k8s)+Docker+runtime 優化"技術棧就可以實現一個可用版本,其中 VM 可以提供資源強隔離性,基於多個 VM 節點組建 k8s 集群,函數計算框架例如 OpenWhisk 或 OpenFaaS 可以依託 k8s 進行部署。儘管同一個 VM 內的多租戶共享會導致面臨一定的安全隱患,但對於實驗環境來說是足夠的。

在注重租戶間隔離性和強調安全的場景下,AWS Lambda 採用的「裸金屬 +Hypervisor+microVM+ 容器」技術路線通過 microVM 實現強隔離性,並且 VM 內一般只允許部署同一個租戶的函數來提高安全性。而谷歌採用的「裸金屬 +Hypervisor+VM+gVisor」則是另一種技術方案,Hypervisor 和 VM 負責提供硬體虛擬化及資源強隔離性,安全性則由 gVisor 提供。其中,Firecracker 和 gVisor 均已開源。

討論:VM 在每種技術方案都屬於必需品的地位,但是這樣勢必會導致高開銷的存在。那麼能不能採用「裸金屬 + 輕量級 Hypervisor+Host OS+ 安全容器」或者直接「裸金屬 +Host OS+ 安全容器」的技術方案減少中間層的存在呢?其實這種方式並非不可以,比如劍橋大學就提出了 CHERI[18] 指令集擴展從而實現在硬體層面進行內存隔離,通過卸載掉虛擬化軟體的部分職責,使得 Hypervisor「變薄」。儘管這項工作只基於模擬器進行了實現,但是也驗證了未來更輕量化的 Serverless 計算底座的可行性。

降低冷啟動發生率

在文章的上半部分,我們主要介紹了如何加速函數實例初始化過程的一些技術方案,包括通過優化調度和鏡像分發策略,採用更輕量級的虛擬化技術,或者藉助 RDMA 硬體改善跨節點數據傳輸等方法,儘管這些方法已經可以將實例運行時環境的初始化的時間壓縮至數十毫秒甚至是數毫秒,然而用戶側的延遲卻仍然存在,例如程序狀態的恢復,變量或者配置文件的重新初始化,相關庫和框架的啟動。具體來講,在機器學習應用中,TensorFlow 框架的啟動過程往往需要花費數秒,即使實例運行時環境的啟動時間再短,應用整體的冷啟動時延對用戶而言依然是無法接受的(註:通常大於 200ms 的時延可被用戶察覺)。

在這種情況下,可以從另一個角度入手解決冷啟動問題,即降低冷啟動調用的發生率。例如,通過緩存完整的函數實例,請求到達時可以快速恢復並處理請求,從而實現近乎零的初始化時延(例如 Docker unpause 操作時延小於 0.5ms)。

降低冷啟動發生率的相關研究可以分為如下幾個方面:

  • 實例保活 / 實例預留:例如基於 Time-to-Live 的 keepalive 保活機制 [AWS Lambda, OpenWhisk];或者通過並發配置接口預留一定數量的實例 [AWS Labmda 等];這些方法原理簡單,易於實現,但是在面對負載變化時緩存效率較低。
  • 基於負載特徵學習的動態緩存:例如基於請求到達間隔預測的動態緩存方案 Serverless in the Wild [ASPLOS'20];學習長短期負載變化特徵的動態緩存方案 INFless [ASPLOS'22];基於優先級的可替換緩存策略 FaasCache [ATC'21];面向異構伺服器集群的低成本緩存方案 IceBreaker [ASPLOS'22]。這些動態緩存方案根據負載特徵學習決定實例緩存數量或時長,從而在降低冷啟動調用率的同時改善緩存資源消耗。
  • 優化請求分發提高命中率:例如兼顧節點負載和本地化執行的請求調度算法 CH-RLU [HPDC'22]。通過權衡節點負載壓力和緩存實例的命中率來對請求的分發規則進行優化設計,避免節點負載過高導致性能下降,同時兼顧冷啟動率。
  • 改善並發 / 實例共享或復用:例如允許同一函數工作流的多個函數共享 Sandbox 環境 SAND [ATC'18];使用進程或線程編排多個函數到單個實例中運行 Faastlane [ATC'21];提高實例並發處理能力減少實例創建 Fifer [Middle'20]; 允許租戶復用其它函數的空閒實例減少冷啟動時間 Pagurus [ATC'22]。這些實例共享或者復用技術可以同緩存方案結合使用,降低冷啟動帶來的性能影響。

接下來,針對上述 4 個方面的研究工作進行詳細介紹。

實例保活 / 實例預留

  • 實例並發設置和預留。

商用的 Serverless 平台例如 AWS Lambda[19]、華為雲 FunctionGraph[20]都內置了 Time-to-live 實例保活機制即 keepalive 方法。其原理是將執行完請求的實例內存中保活一段時間再釋放。如果保活期間有新的請求到達,則可以立即執行並重置剩餘的保活時間。除此之外,雲伺服器通常會向用戶提供實例並發設置的接口,用戶在部署函數後可以設置預留一定數量的實例(需額外支付費用),從而降低由於突發負載導致的冷啟動調用率。然而,這類靜態的緩存方法易於實現,但是實例預留數量或保活時長難以根據負載變化進行實時調整,從而導致性能下降或者資源超分浪費。

基於負載特徵學習的動態緩存

  • 基於直方圖統計的動態實例緩存。

微軟的研究團隊通過分析 Azure 的生產環境 trace,發現請求的到達間隔普遍分布在秒級、數分鐘乃至數小時,基於 Time-to-live 的靜態保活策略會導致大量的資源浪費。因此,作者提出了基於混合直方圖的策略來統計函數請求的調用間隔,並根據這些信息動態的釋放或提前拉取函數實例,從而在減少冷啟動調用率的同時減少 Serverless 平台內部的緩存資源浪費[21] 然而,這套設計方案只針對 0-1 的函數擴縮場景進行了評估,因為它只控制實例的緩存時長,而無法感知實例數量的變化,如何將這套機制運用在 1- 多的實例擴縮場景中還面臨著一些挑戰。

  • 基於長短期直方圖的動態實例緩存。

直方圖策略通過生成函數請求到達間隔的分布來決定緩存實例的何時創建和緩存時長,然而,在初期歷史統計數據不足或者負載發生短期突變的場景下,得到的直方圖分布往往會不具有代表性,從而導致緩存策略的實際效果下降。為了解決該問題,INFless[22] 提出了一個長短期結合的混合直方圖策略來改善預測精度,通過分別統計長期的直方圖分布特徵和短期的直方圖分布特徵,來共同決定緩存實例的創建時間點和保活時長,從而改善緩存效率(冷啟動率 / 緩存資源成本)。

  • 基於優先級的可替換緩存策略。

無論是 Time-to-live 的 keepalive 還是基於直方圖的動態緩存方案,都是傾向於減少緩存資源的消耗,從而降低函數服務提供商的運營成本。然而,FaasCache[23] 的作者認為函數計算集群的內存資源與其與閒置,不如用來緩存更多的函數實例,從而最大程度地降低冷啟動調用發生率。為此,FaasCache 借鑑了 CPU 緩存的替換算法,通過函數的最近訪問時間,函數內存消耗以及冷啟動時長為每個實例定義優先級。請求執行結束後的函數實例都會被長期緩存在節點中,僅當節點無可用資源時才驅逐較低優先級的實例來緩存新的函數。此外,FaasCache 還設計了一個反饋控制機制來調整緩存容量的大小,通過權衡冷啟動率和緩存資源成本來實現較好的緩存效率。

面向異構集群的低成本緩存策略。

雲服務供應商通常會提供多種具有不同 CPU 型號的伺服器給租戶使用,這些 VM 的處理能力和價格有所差異。IceBreaker[24] 針對異構函數計算集群設計了一個成本優先的緩存策略,其核心思想是「可以使用價格更為便宜的低端伺服器緩存冷啟動開銷較低的函數,從而節省總體成本」。為了實現該目的,IceBreaker 基於傅立葉變化預測函數的負載到達率,並結合實例的使用率和節點加速前親和性來決定將函數緩存在高端伺服器,低端伺服器或者不進行緩存,從而以損失部分函數性能的代價降低整體緩存消耗的資源成本。

優化請求分發提高緩存命中率

此外,還有一些工作通過優化或重新設計 Serverless 平台的請求分發策略來改善函數實例的命中率,從而改善緩存效率。在 Serverless 平台內部,前端組件收到請求後,通常以 hash 或負載均衡的策略分發到後端節點進行處理。將同一函數的請求分發到相對固定的節點可以有效地提高節點內實例的使用率(即緩存命中率),這也稱為緩存的本地性原理。但是,由於函數負載中通常存在大量的熱點函數,當熱點函數聚集在後端節點時,則可能導致節點資源使負載壓力升高,從而引發性能下降。

因此,CH-RLU[25] 工作提出了一個負載感知的請求調度策略,作者基於一致性 Hash 的分發規則在調度過程中考慮後端節點的壓力,通過將高負載的函數分發到不同的節點來避免局部熱點, 從而緩解資源競爭導致的函數性能下降問題。可以看到,優化負載分發的研究工作可以同現有的緩存方案結合使用,通過協同設計可以進一步改善 Serverless 平台的緩存效率。

改善並發 / 實例共享或復用

  • 多函數共享 Sandbox。

SAND[26] 工作在函數工作流場景下提出了一種多函數共享實例 Sandbox 的方案,它允許同一個函數工作流內的不同函數共享同樣的 Sandbox 環境,從而減少請求執行時創建的函數實例數量,這將有助於減少請求調用的冷啟動發生率。然而,這在實際場景中也有很多局限性,例如租戶的多個函數可能由不同的語言運行時編寫,這些函數往往無法從實例共享中獲益。此外,多個函數共享 Sandbox 會增加實例的體積,而工作流中的函數可能被多條路徑所調用,在函數擴容時則會導致不必要的資源浪費。

  • 進 / 線程混合的函數編排。

傳統的函數實例以容器為單位,每個函數運行在一個單獨的容器實例內部,容器間的數據傳輸需要藉助網絡或第三方存儲實現,以 AWS S3 為例,通過 S3 進行函數間數據交換會導致較高時延。為了改善函數實例間的通信效率,Faastlane[27] 工作提出了一個新的函數編排組織方式,即將工作流中的不同函數以進程或線程的形式在容器實例中執行,同時採用 IPC 進程間通信來提高函數交互效率。對於包含敏感數據操作的函數工作流,Faastlane 使用英特爾內存保護密鑰 (MPK) 提供輕量級線程級隔離域。在 Apache OpenWhisk 上的評測結果表明,Faastlane 可以將函數工作流的處理時間降低 15 倍,並將函數間的交互延遲減少 99.95%。

  • 提高實例並發處理能力。

在 Serverless 平台中,函數實例通常被配置較少的資源容量,例如內存以 128MB 為單位遞增,而 CPU 的配額同內存大小成比例。當請求到達後,平台通常以「一對一」的請求 - 實例映射方式處理請求。低的實例並發處理能力可能導致 Serverless 平台在面臨突發負載時創建出大量的實例,不僅降低函數的服務性能,也會增加系統調度壓力。為了解決該問題,Fifer [12] 工作提出了一種支持多並發處理的函數實例運行方案,通過為實例分配多個獨立的 CPU 處理線程來提高實例的吞吐。同時,通過計算實例的排隊延遲,並發處理數和未來請求到達率來提前預置對應數量的實例,從而減少冷啟動調用的產生。

  • 允許租戶間實例搶占 / 復用。

通常 Serverless 平台中的租戶函數運行在單獨的實例中,不同函數間的實例有獨立的資源配置和運行環境。由於不同租戶的函數可能具有相同的運行時語言環境,而租戶的函數實例也不一定在同一時間都處於忙碌狀態,因此,Pagurus[28] 工作另闢蹊徑,設計了一個類似「寄居蟹」的租戶間實例復用機制,其核心思想是「當 A 租戶函數的冷啟動發生時,可以迅速搶占 B 租戶的空閒實例的運行時環境,從而減少冷啟動的時延」,通過實例搶占和復用,從而避免冷啟動發生時從零啟動的長時延問題。同時,可以看到該做法同 Pod 池特化技術有異曲同工之妙。

小結

可以看到,改善實例的並發能力或是通過實例共享 / 復用都是為了提高已有實例的利用效率,而緩存的方案則是儘可能利用少的資源來預置更多的實例,從而降低冷啟動調用的產生。上述這些方法從不同的角度緩解 Serverless 函數冷啟動的問題,可以結合使用來改善緩存效率。

在主動緩存的方案中,由於突發流量或者負載的無規律性,基於負載預測來進行緩存還存在較大難度。在實際場景中,通過主動預測 + 優先級緩存調整來實現緩存方案將更有潛力。受限於各家函數計算平台內部的架構,函數共享實例或者搶占復用的實施成本較高,因此開發人員通常會選擇更加易於實現的緩存方案例如預熱池來改善服務質量。

總 結

Serverless 的無狀態設計賦予了函數計算高度彈性化的擴展能力,然而也帶來了難以避免的冷啟動問題。消除 Serverless 函數的冷啟動開銷還是從降低函數冷啟動率和加速實例啟動過程兩個角度綜合入手。

對於冷啟動開銷比較大的函數,在函數計算框架的設計機制中進行優化,儘量避免冷啟動發生;當冷啟動發生時,採用一系列啟動加速技術來縮短整個過程進行補救。在 Serverless 平台的內部,冷啟動的管理在實踐中可以做進一步精細的劃分,例如針對 VIP 大客戶、針對有規律的負載,或是針對冷啟動開銷小的函數,通過分類做定製化、有目的的管理可以進一步改善系統效率。

在未來,基於 WASM+ 進程 fork 的技術可能會有助於徹底消除冷啟動問題,但是考慮到實際可用性和安全性等問題,短期內的結果可能也是 WASM 和 Container-based 函數並存的折中方案,互相取長補短,因此在當前階段研究冷啟動問題還是有較大價值的。

參考文獻

[1] Arjun Singhvi, Kevin Houck, Arjun Balasubramanian, Mohammed Danish Shaikh, Shivaram Venkataraman, Aditya Akella. Archipelago: A Scalable Low-Latency Serverless Platform. arXiv:1911.09849, 2019.

[2] Fastfreeze. https://github.com/twosigma/fastfreeze. 2023.

[3] 劉方明, 李林峰, 王磊. 華為 Serverless 核心技術與實踐 [M]. 北京: 電子工業出版社, 2021.11.

[4] Docker. https://www.docker.com/. 2023.

[5] Edward Oakes, Leon Yang, Dennis Zhou, Kevin Houck, Tyler Harter, Andrea C. Arpaci-Dusseau, Remzi H. Arpaci-Dusseau: SOCK: Rapid Task Provisioning with Serverless-Optimized Containers. USENIX Annual Technical Conference 2018: 57-70.

[6] Kata Containers. https://katacontainers.io/. 2023.

[7] Alexandru Agache, Marc Brooker, Alexandra Iordache, Anthony Liguori, Rolf Neugebauer, Phil Piwonka, Diana-Maria Popa: Firecracker: Lightweight Virtualization for Serverless Applications. NSDI 2020: 419-434.

[8] Open-sourcing gVisor, a sandboxed contaienr runtime. https://github.com/google/gvisor. 2023.

[9] Dong Du, Tianyi Yu, Yubin Xia, Binyu Zang, Guanglu Yan, Chenggang Qin, Qixuan Wu, Haibo Chen: Catalyzer: Sub-millisecond Startup for Serverless Computing with Initialization-less Booting. ASPLOS 2020: 467-481.

[10] Dmitrii Ustiugov, Plamen Petrov, Marios Kogias, Edouard Bugnion, Boris Grot: Benchmarking, analysis, and optimization of serverless function snapshots. ASPLOS 2021: 559-572.

[11] Xingda Wei, Fangming Lu, Tianxia Wang, Jinyu Gu, Yuhan Yang, Rong Chen, Haibo Chen. No Provisioned Concurrency: Fast RDMA-codesigned Remote Fork for Serverless Computing. OSDI 2023.

[12] Jashwant Raj Gunasekaran, Prashanth Thinakaran, Nachiappan Chidambaram Nachiappan, Mahmut Taylan Kandemir, Chita R. Das. Fifer: Tackling Resource Underutilization in the Serverless Era. Middleware 2020: 280-295.

[13] Xuanzhe Liu, Jinfeng Wen, Zhenpeng Chen, Ding Li, Junkai Chen, Yi Liu, Haoyu Wang, Xin Jin. FaaSLight: General Application-Level Cold-Start Latency Optimization for Function-as-a-Service in Serverless Computing. arXiv:2207.08175. 2022.

[14] WebAssembly. https://webassembly.org. 2023.

[15] Simon Shillaker, Peter R. Pietzuch: Faasm: Lightweight Isolation for Efficient Stateful Serverless Computing. USENIX Annual Technical Conference 2020: 419-433.

[16] Linux CRIU, stands for checkpoint and resotre in userspace. https://github.com/checkpoint-restore/criu. 2023.

[17] Anil Madhavapeddy, Richard Mortier, Charalampos Rotsos, David J. Scott, Balraj Singh, Thomas Gazagnaire, Steven Smith, Steven Hand, Jon Crowcroft: Unikernels: library operating systems for the cloud. ASPLOS 2013: 461-472.

[18] Robert N. M. Watson, Jonathan Woodruff, Peter G. Neumann, Simon W. Moore, Jonathan Anderson, David Chisnall, Nirav H. Dave, Brooks Davis, Khilan Gudka, Ben Laurie, Steven J. Murdoch, Robert M. Norton, Michael Roe, Stacey D. Son, Munraj Vadera: CHERI: A Hybrid Capability-System Architecture for Scalable Software Compartmentalization. IEEE Symposium on Security and Privacy 2015: 20-37.

[19] AWS Lambda. https://aws.amazon.com/lambda/. 2023.

[20] 華為雲 FunctionGraph. https://www.huaweicloud.com/product/functiongraph.html. 2023.

[21] Mohammad Shahrad, Rodrigo Fonseca, Iñigo Goiri, Gohar Chaudhry, Paul Batum, Jason Cooke, Eduardo Laureano, Colby Tresness, Mark Russinovich, Ricardo Bianchini: Serverless in the Wild: Characterizing and Optimizing the Serverless Workload at a Large Cloud Provider. USENIX Annual Technical Conference 2020: 205-218.

[22] Yanan Yang, Laiping Zhao, Yiming Li, Huanyu Zhang, Jie Li, Mingyang Zhao, Xingzhen Chen, Keqiu Li: INFless: a native serverless system for low-latency, high-throughput inference. ASPLOS 2022: 768-781.

[23] Alexander Fuerst, Prateek Sharma: FaasCache: keeping serverless computing alive with greedy-dual caching. ASPLOS 2021: 386-400.

[24] Rohan Basu Roy, Tirthak Patel, Devesh Tiwari: IceBreaker: warming serverless functions better with heterogeneity. ASPLOS 2022: 753-767.

[25]Alexander Fuerst, Prateek Sharma: Locality-aware Load-Balancing For Serverless Clusters. HPDC 2022: 227-239.

[26] Istemi Ekin Akkus, Ruichuan Chen, Ivica Rimac, Manuel Stein, Klaus Satzke, Andre Beck, Paarijaat Aditya, Volker Hilt: SAND: Towards High-Performance Serverless Computing. USENIX Annual Technical Conference 2018: 923-935.

[27] Swaroop Kotni, Ajay Nayak, Vinod Ganapathy, Arkaprava Basu: Faastlane: Accelerating Function-as-a-Service Workflows. USENIX Annual Technical Conference 2021: 805-820.

[28] Zijun Li, Quan Chen, Minyi Guo: Pagurus: Eliminating Cold Startup in Serverless Computing with Inter-Action Container Sharing. USENIX Annual Technical Conference 2022.

[29] Ao Wang, Shuai Chang, Huangshi Tian, Hongqi Wang, Haoran Yang, Huiba Li, Rui Du, Yue Cheng: FaaSNet: Scalable and Fast Provisioning of Custom Serverless Container Runtimes at Alibaba Cloud Function Compute. USENIX Annual Technical Conference 2021: 443-457.

[30] Marc Brooker, Mike Danilov, Chris Greenwood, Phil Piwonka: On-demand Container Loading in AWS Lambda. CoRR abs/2305.13162 (2023).

[31] Zijun Li, Linsong Guo, Jiagan Cheng, Quan Chen, Bingsheng He, Minyi Guo: The Serverless Computing Survey: A Technical Primer for Design Architecture. ACM Comput. Surv. 54(10s): 220:1-220:34 (2022).

點擊底部閱讀原文訪問 InfoQ 官網,獲取更多精彩內容!

今日好文推薦

OpenAI 遭遇離職潮:員工對 ChatGPT 進展緩慢失望,痛批 CEO 不務正業

阿里改革,P8 成為歷史;GPT-4 模型架構泄露;OpenAI 面臨最嚴調查,Altman 驚慌連發 3 推|Q 資訊

神器還是垃圾?那些用 AIGC 編程的人,實踐得怎麼樣了

甲骨文火上澆油、SUSE投入1000萬美元,多方「圍剿」紅帽:「紅帽負擔不起?那我們來!」

文章來源: https://twgreatdaily.com/zh-sg/0215e5e904380ceb928e53147ec5896f.html