The Art of Readable Code && High Performance Comments

Lambda Container Reuse

前陣子受 Pahud 大大對 Lambda 的心得啟發,做了一些小測試以理解其特性,也希望能更加善用 Lambda。底下測試使用 Python / NodeJS (0.10 and 4.3),歡迎喜愛 Java 的大大補完。

AWS 會在 Server Pool 上散佈 Lambda Funcion 程式碼,並以 Container 一類的方式運行。Manual 裡提到應將 handler function 作為程式的主要進入點,並避免使用 handler function 外的變數 (Global),這立刻讓我懷疑 Lambda 可能透過 event loop 或是多執行緒,使多組 handler 在同一個環境下並行;然而實測後並非如此。

Lambda Container Reuse

參考 Understanding Container Reuse in AWS Lambda,Lambda Host 在運行 Function 時,會重覆利用 Container;Container 若正常結束,Lambda 會保存當下狀態 (freeze) 備日後復用。當該 Function 再次被調用時,若該 Frozen Container 仍然可用,Lambda 會重新啟動 (thaw) 並調用 handler,無需再次初始化。多次(不並行)執行下列 Function 就能體驗此狀況:

由於 Container Reuse, myId 會在首次執行時被定義,後面幾次則不刷新。

更多事實

handler() 不並行

修改範例使它需要兩秒執行時間,並且改用命令列調用,立即會發現執行時間重疊的 Invocation,拿到的 myId 也不一樣。因此可以推論出 AWS 目前未實現 runtime 層級的復用,開發者因而先不用擔心 thread safe 的問題。

復用排程邏輯

若在刷出兩線 container 後恢復單線調用,則回應的 myId 又都是同一個;可以推論出 AWS 選擇排程的算法偏好最近用過 (thaw / freeze) 的 Container。

Timeout & Error

在程式發生各種錯誤後,AWS Lambda 會丟棄該 Container,以免錯誤的資料影響下次執行結果。

在 Lambda Node (0.10)/ 4.3 呼叫 context.done() 時,Lambda 會以類似 setTimeout 的方式排程,以 freeze 該 container。若當時有其它任務已在 event loop 中,Lambda 下次復用該 container 時 (透過 thaw), 這些任務會一併被運行。

執行結果如下,id 相同代表 container 被復用;第二次執行時可以看到第一次留下的任務。由於 container 在調用 context.done() 後即結束,Lambda 的執行時間(用於計費)也只計算到此。

4.3 提供的 callback() 行為則略有不同,它似乎只負責回傳資料,不介入控制程序;Lambda 會持續執行,直到 event loop 清空或 timeout。

Prewarm ?

這有點尷尬,但我覺得如果 Lambda Function 需要預熱,應該已經落入了 Lambda 的 anti-pattern。常見的原因有功能太過龐大、Eager initialization 等等。

若是無法避免,在 Lambda concurrency 足夠的前提下,定期大量並行某些 lambda function,確實會減低用戶執行時碰到新 container,執行(自己寫的)初使化的等待。

1 Comment

  1. 2016 年 09 月 09 日    

    Lambda/Python 使用 multiprocessing.Process 則略有不同;只要 handler 正確 return,函式便不會 timeout,從而觸發 Container freeze/thaw cycle。其它 process 執行的事務會被暫停,在該 container 運行時 (thaw) 繼續,freeze 後又停止。因此若背景 process 調用 sleep(5),而每次執行 Function 時,前景執行時間都是剛好一秒,則在運行五次後 (總 cpu time 5s),第一次執行的 backend process 的 sleep(5) 會 return。

發表迴響

分類

%d 位部落客按了讚: