在設定 AWS Lambda Memory 上限時,是否只考慮實際應用所需呢?這裡有一個陷阱,AWS Lambda Memory 大小和執行實體的 Performance 有關!
AWS Lambda 的計價方式是以每 1 毫秒執行時間為基準,依照 Memory 大小進行階梯定價。因此,Memory 越大的實體,性能越高,執行時間越短,反而可能比 Memory 低的實體更有成本效益!
本篇文章分享實例數據,透過圖表分析思考過程,並提供一些策略給大家參考。
目錄
AWS Lambda 的定價方式
AWS Lambda 是 AWS 推出的 Serverless 服務,從官方網頁得知,除了用 實體大小與執行時間
作計費外,還有 暫時性儲存
與 資料傳輸
等等計費。本文僅討論不同 Memory 大小對於執行時間的影響,以及費用的變化。其他的費用在此沒有列入考慮。
直觀想像,開較小的 Memory,總費用會越低。但這個假設是建立在以下兩個條件之上:
- 執行同樣的程式碼所需的時間是相同的
- 傳輸相同資料所需的時間也是相同的
但是,如果上述兩者都不同呢?或是使用相同的邏輯,相同的記憶體大小,但使用不同的程式語言呢?接下來,我們將透過實驗來回答上述問題。
不同 Memory 大小對執行時間與費用的影響
實驗方式,取用我現成專案的 Lambda 作實驗
- Lambda 以 Python 實現
- 外界呼叫 API 打入 AWS API Gateway,調用 Lambda
- 透過 Lambda 內部邏輯向 Google Sheet 取資料,運算後回傳
- 每次測試資料皆相同,因此傳輸與計算量固定,僅有 Lambda 運算和網路效能會影響總執行時間
- 以 Browser 的
Waiting for server response
為計時方法,因此時間包含- 打 Google Sheet Api 時間(網路效能)
- Lambda Python 處理時間(運算效能)
- Response 回傳的 latency (網路效能,佔比極小,且幾乎固定,可忽略)
- 每調整一次 Memory 大小,先打一次 API 並紀錄時間為 With Cold Start(因第一次執行時間會包含 cold start time,需剔除所以獨立紀錄),後續再打三次並依序紀錄後取平均值
我們來看看實測數據:
Memory (MB) | With Cold Start (s) | 1st (s) | 2nd (s) | 3rd (s) | Execution Time (s) | Execution Cost (USD) |
---|---|---|---|---|---|---|
128 | 5.16 | 4.5 | 4.39 | 4.84 | 4.58 | 0.000009611 |
256 | 3.23 | 2.78 | 2.66 | 2.84 | 2.76 | 0.000011592 |
512 | 2.07 | 1.84 | 1.76 | 1.84 | 1.81 | 0.00001505066667 |
1024 | 1.49 | 1.4 | 1.36 | 1.31 | 1.36 | 0.00002265633333 |
1536 | 1.4 | 1.2 | 1.23 | 1.21 | 1.21 | 0.00003033333333 |
3072 | 1.25 | 1.25 | 1.18 | 1.21 | 1.21 | 0.00006066666667 |
繪製成圖表,我們觀察到
- 從 128MB 提升到 256 MB,Execution Time 大幅下降。但後續提高 Memory 大小,Time 下降幅度也隨之變少
- 提升 Memory 前段 Execution Cost 上升緩慢,後段 1536MB → 3072MB Cost 提升大幅增加
想更進一步知道 Cost 上升的同時,Lambda Performance 上升的狀況
,於是將 Execution Time 取倒數後再畫一次圖。
觀察結果:
- Performance 幾乎隨 Memory 成線性增長,但在 1536MB → 3072MB 發生停滯,兩者效能一樣
- 1536 MB 和 3072MB 效能一樣的情況下,3072MB 相對需要付出更多的成本
- Cost 初期增長比 Performance 慢,後期逐漸加速,成指數成長
有了此發現,我想找出 最高 C/P 值
的甜蜜點,也就是比較 單位美金下可以買到的 Performance
。於是將 Performance 除以 Cost 後,並重新對 Memory 大小作圖。
由圖發現,最高 C/P 值落在 Memory 等於 512 MB 的時候,第二順位為 1024 MB。
如何選擇 Lambda 實體大小
依照以上的實驗結果,提供一些選擇的建議與方向
- 確認 Lambda 執行時所需最小 Memory 大小,剔除掉小與此值的選擇
- 嘗試不同 Memory 大小,測量數據並繪製 Performance 除以 Cost 的曲線
- 依 C/P 值排出 Memory 大小備選
- 照排出的順序,依序考量每一個 Memory 大小的 Execution Time 和 Cost,選擇可以接受的選項
以我們討論的 Case,將實驗結果以 C/P 值重新排序如下表:
Sequence | Memory (MB) | Execution Time (s) | Execution Cost (USD) |
---|---|---|---|
1 | 512 | 1.81 | 0.00001505066667 |
2 | 1024 | 1.36 | 0.00002265633333 |
3 | 256 | 2.76 | 0.000011592 |
4 | 1536 | 1.21 | 0.00003033333333 |
5 | 128 | 4.58 | 0.000009611 |
6 | 3072 | 1.21 | 0.00006066666667 |
選擇策略是
- 若想省錢,選 512 MB
- 若想強化效能,可能優先選擇 1024 MB,而不是 1535 MB
因為相對 512 MB,1024 MB 減少了 450 ms ,多 50% 成本,而 1536 MB 只比 1024 MB 再快 150 ms,卻比 512 MB 多 101% 的成本。
另外需要提醒,雖然這篇文章的結果也認為 512 MB 是最佳選擇,但我覺得並不是所有 Case 都一樣結果,會因 Lambda 內部邏輯設計而有差異,建議實際測量一次最準確。
不同程式語言對 Lambda Cold Start 時間的影響
這邊直接引用 AWS Lambda: Cold Start Duration per Language 的結果
大部分語言的 Cold Start 落在 400 ms 內 ,通常 700 ms 內會結束。熱門的 Javascript 和 Python 最快,而讓我訝異的是 Go 竟然還比較慢。C# 則敬陪末座,落在 400ms ~ 900 ms。
雖語言會影響 Cold Start 時間,進而影響 Cost,但相對於 Memory 大小所造成的 Cost 差異,可以說是微乎極微。建議還是選用習慣的語言開發,節省的人力成本可能更高。
影響 Cold Start 時間還有其他因素,如 Memory Size(特定語言)、Lambda Package Size 等等,這已超出本文想討論的範圍,有興趣可以參考 Cold Starts in AWS Lambda。
結論
在本篇文章中,我們透過實驗發現,AWS Lambda Memory 大小和執行實體的 Performance 是有關聯的,當 Memory 大小從 128MB 提升到 256 MB 時,可以大幅減少執行時間,不過增加 Memory 大小對於減少執行時間的效果後續會越來越小。所以,在決定 Memory 大小時,我們應該考慮應用所需的 Memory 大小及費用效益,以確保能獲得最佳的結果。
AWS Lambda Memory 大小與 Performance、Cost 的討論就到這裡,希望能幫助到你!
延伸閱讀
使用 AWS lambda 做免錢的 Cloudflare cache preload
使用 AWS Parameter Store 實現 Config 和 Credentials 外置
參考文章
AWS Lambda Performance Tuning & Best Practices
Cold Starts in AWS Lambda
AWS Lambda: Cold Start Duration per Language
Optimizing your AWS Lambda costs – Part 1