【转】无服务计算(Serverless Computing)核心知识
Serverless Computing概念
????云原生計算基金會CNCF(Cloud Native Computing Foundation, CNCF)Serverless Whitepaper v1.0對無服務器計算作了如下定義:
Serverless computing refers to the concept of building and running applications that do not require server management. It describes a finer-grained deployment model where applications, bundled as one or more functions, are uploaded to a platform and then executed, scaled, and billed in response to the exact demand needed at the moment.
????無服務器計算(Serverless Computing)是指在構建和運行應用時無需管理服務器等基礎設施。它描述了一個更細粒度的部署模型,在該模型中,應用被拆解為一個或多個細粒度的函數被上傳到一個平臺,然后根據當前所需執行、擴展和計費。
????無服務器計算并不意味著我們不再使用服務器來承載和運行代碼,也不意味著不再需要運維工程師。而是指無服務器計算的消費者不再需要花費時間和資源在服務器配置、維護、更新、擴展和容量規劃上。所有這些任務和功能都由無服務器平臺處理,并且完全從開發人員和IT/操作團隊中抽象出來。因此,開發人員專注于編寫應用程序的業務邏輯。運營工程師能夠將他們的重點提升到更關鍵的業務任務上。?
?
FaaS & BaaS
無服務器計算平臺可以提供以下一種或兩種服務:
1. FaaS(Functions-as-a-Service-函數即服務),通常提供事件驅動(event-driving)的計算。開發人員使用由事件(event)或HTTP請求觸發的函數運行和管理應用程序代碼。開發人員將小的代碼單元部署到FaaS,FaaS按需執行和擴展,開發人員無需管理服務器或任何其他底層基礎設施。
2. Baas(Backend-as-a-Service后端即服務),是第三方基于API的服務,用于替換自有應用程序中的功能子集。因為這些API是作為一個自動擴縮容和透明操作的服務提供的,所以開發人員認為這(BaaS)是無服務器的 ,如:OSS
?
Pros & Cons
無服務器計算(Serverless Computing)應用利弊大致如下:
Pros:
1. 0服務器操作。無服務器通過消除維護服務器資源所涉及的開銷,極大地改變了運行軟件應用程序的成本模型。
2. 沒有配置、更新和管理服務器基礎結構。
3. 彈性伸縮:無服務器FaaS或BaaS產品可以立即精確地伸縮以處理每個單獨的傳入請求。對于開發人員來說,無服務器平臺沒有“預先計劃的容量”的概念,也不需要配置“自動伸縮”觸發器或規則。在沒有開發人員干預的情況下,自動進行縮放。在完成請求處理后,無服務器FaaS會自動縮小計算資源的規模,以確保永遠沒有空閑的容量。
4. 低成本。無服務器計算服務對空閑的虛擬機或容器不收費;也就是說當代碼沒有運行或沒有進行有意義的工作時,不收費。?
Cons:
1. 作為一種新興的計算模型、缺乏標準化和生態系統成熟度。
2. 由于運行時更具動態性,與iaas和paas相比,調試可能更具挑戰性。
3. 由于按需結構,如果運行時在空閑時刪除函數的所有實例,則某些無服務器運行時的“冷啟動”方面可能是性能問題。
4. 在更復雜的情況下(例如,觸發其他功能的功能),對于相同數量的邏輯,可以有更多的操作表面積。
?
Serverless處理模型(Serverless Processing Model)
CNCF白皮書對于無服務器框架中的函數用法,函數約束、生命周期、調用類型和所需的抽象等定義了規范,以便同一個函數可以一次性編碼,并在不同的無服務器框架中使用。?
?
FaaS解決方案概括為具有以下圖中所示的幾個關鍵元素:
1. 事件源(Event sources)-觸發器或流事件到一個或多個函數實例中
2. 函數實例(Function instances)-單個函數/微服務,可根據需求進行擴展
3. FaaS控制器(FaaS Controller)-部署、控制和監視函數實例及其源
4. 平臺服務(Platform services?)-FaaS解決方案使用的通用集群或云服務(有時稱為后端即服務-BaaS)
?
CNCF函數相關規范
函數定義(Function Definition)
無服務器函數定義可以包含以下規范和元數據,函數定義是特定于版本的:
1. 唯一ID
2. 名字
3. 描述
4. 標簽
5. 版本ID(和/或版本別名)
6. 版本創建時間
7. 上次修改時間(函數定義的)
8. 函數處理程序
9. 運行時語言
10. 代碼+依賴項或代碼路徑和憑據
11. 環境變量
12. 執行角色和密鑰
13. 資源(所需的CPU、內存)
14. 執行超時時間
15. 日志失敗(死信隊列)
16. 網絡策略/vpc
17. 數據綁定(Metadata Binding)
元數據詳細信息(Metadata details)
1. 版本(Version)-每個函數版本都應該有一個唯一的標識符,此外,可以使用一個或多個別名(例如“最新”、“生產”、“測試版”)標記版本。API網關和事件源將流量/事件路由到特定的函數版本。
2. 環境變量(Environment Variables)-用戶可以指定將在運行時提供給函數的環境變量。環境變量也可以從機密和加密內容派生,或者從平臺變量派生(例如,kubernetes envvar定義)。環境變量使開發人員能夠控制函數行為和參數,而無需修改代碼和/或重建函數,從而獲得更好的開發人員體驗和函數重用。
3. 執行角色(Execution Role)-該函數應在特定的用戶或角色標識下運行,該標識授予并審核其對平臺資源的訪問權限。
4. 資源(Resources)-定義功能所需的或最大的硬件資源,如內存和CPU。
5. 超時(Timeout)-指定函數調用在被平臺終止之前可以運行的最長時間。
6. 失敗日志(死信隊列)(Failure Log (Dead Letter Queue))-隊列或流的路徑,用于存儲失敗的函數執行列表,并提供適當的詳細信息。
7. 網絡策略(Network Policy)-分配給功能的網絡域和策略(用于與外部服務/資源通信的功能)。
8. 執行語義(Execution Semantics)-指定應如何執行函數(例如,每個事件至少執行一次、至多執行一次、完全執行一次)。
數據綁定(Data Bindings)
????一些無服務器框架允許用戶指定函數使用的輸入/輸出數據資源,這使開發人員能夠簡化、提高性能(在執行之間保留數據連接,可以預取數據等)和更好的安全性(數據資源憑據是上下文的一部分,而不是代碼)。
????綁定數據可以是文件、對象、記錄、消息等形式,函數規范可以包括一組數據綁定定義,每個定義指定數據資源、其憑證和使用參數。數據綁定可以引用事件數據(例如,db鍵是從事件“用戶名”字段派生的),示例:https://docs.microsoft.com/azure/azure-functions/functions-triggers-bindings
?
函數約束(Function Requirements)
函數和無服務器運行時應該滿足的通用需求:
1. 函數必須與不同事件類的基礎實現分離
2. 可以從多個事件源調用函數
3. 每個調用方法不需要不同的函數
4. 事件源可以調用多個函數
5. 函數可能需要與底層平臺服務進行持久綁定的機制,這可能是跨函數調用。函數可能是短暫的,但如果需要在每次調用(例如在日志記錄、連接和裝載外部數據源的情況下)上都進行引導,則引導可能會很昂貴。
6. 每個函數可以用不同于同一應用程序中使用的其他函數的代碼語言編寫。
7. 函數運行時應盡可能減少事件序列化和反序列化開銷(例如,使用本機語言結構或有效的編碼方案)
?
函數調用類型(Function Invocation Types)
根據不同的用例,可以從不同的事件源調用函數,例如:
1. 同步請求(Synchronous Request (Req/Rep)),例如http請求、grpc調用
????- 客戶機發出請求并等待立即響應。這是一個阻塞呼叫。
2. 異步消息隊列請求(pub/sub)(Asynchronous Message Queue Request),例如RabbitMQ, AWS SNS, MQTT, Email, Object (S3) change、計劃事件(如cron作業)
????- 消息發布到交換并分發到訂閱服務器
? ? - 沒有嚴格的消息順序, 可一次處理
3. 消息/記錄流(Message/Record Streams):Kafka, AWS Kinesis, AWS DynamoDB Streams, Database CDC
? ? - 一組有序的消息/記錄(必須按順序處理)
? ? - 通常,一個流被分割到多個分區/碎片(partitions/shards?),每個碎片有一個worker(碎片使用者)
? ? - 流可以從消息、數據庫更新(日志)或文件(例如csv、json、parquet)生成。
? ? - 事件可以推送到函數運行時,也可以由函數運行時拉取。
4. 批處理作業(Batch Jobs),例如ETL作業、分布式深度學習、HPC模擬
? ? - 作業(Jobs)被調度或提交到隊列,并在運行時使用多個并行函數實例進行處理,每個實例處理工作集(任務)的一個或多個部分。
? ? - 當所有并行工作人員成功完成所有計算任務時,作業完成。
?
?
函數生命周期(Function LifeCycle)
函數部署管道(Function Deployment Pipeline)
?
函數生命周期:
1. 編寫代碼、提供規范和元數據
2. 獲取代碼和規范,編譯并將其轉化為一個工件(二進制代碼、包或容器鏡像)
3. 工件部署到一個集群上,控制器實體負責根據事件流量和/或實例上的負載調整函數實例的數量。
?
函數操作(Function Operations)
無服務器框架可能允許以下操作和方法定義和控制功能生命周期:
1. 創建(Create)-創建一個新函數,包括其規范和代碼
2. 發布(Publish)-創建可部署在群集上的函數的新版本
3. 更新別名/標簽(Update Alias/Label [of a version])-更新版本別名
4. 執行/調用(Execute/Invoke)-不通過事件源調用特定版本
5. 事件源關聯(Event Source association?)-將函數的特定版本連接到事件源
6. 獲取(Get)-返回函數元數據和規范
7. 更新(Update)-修改函數的最新版本
8. 刪除(Delete)-刪除一個函數,可以刪除一個特定的版本或函數的所有版本
9. 清單(List)-顯示函數及其元數據的列表
10. 狀態獲取(get stats)-返回有關函數運行時使用情況的統計信息
11. 日志獲取(get logs)-返回函數生成的日志
?
關鍵步驟說明:
1. Create:在創建函數時,提供其元數據(稍后在函數規范中描述)作為函數創建的一部分,將對其進行編譯并可能發布。稍后可以啟動、禁用和啟用功能。功能部署需要能夠支持以下用例:
????- 事件流(Event streaming),在這種情況下,隊列中可能總是有事件,但是可能需要通過顯式請求暫停/恢復處理。
? ? - 熱啟動(Warm startup)-在任何時候具有最少實例數的函數,例如,接收到的“第一個”事件具有熱啟動,因為該函數已經部署并準備好服務于該事件(而不是在“傳入”事件第一次調用時部署該函數的冷啟動)。
2. Publish:用戶可以發布一個函數,這將創建一個新版本(最新版本的副本),發布的版本可能會被標記/標記或有別名,請參閱下面的詳細信息。
3. 用戶可能希望為調試和開發過程直接執行/調用函數(繞過事件源或API網關)。用戶可以指定調用參數,如所需版本、同步/異步操作、詳細級別等。
4. 用戶可能希望獲得函數統計信息(例如調用次數、平均運行時間、平均延遲、失敗、重試次數等),統計信息可以是當前度量值或一系列值(例如存儲在Prometheus或云提供程序設施(如AWS Cloud Watch))。
5. 用戶可能希望檢索函數日志數據。這可以根據嚴重性級別和/或時間范圍和/或內容進行篩選。日志數據是每個函數的,它包括諸如函數創建和刪除、顯式錯誤、警告或調試消息等事件,還可以選擇函數的stdout或stderr。每次調用最好有一個日志條目,或者一種將日志條目與特定調用關聯的方法(以便更簡單地跟蹤函數執行流)。
?
事件源(Event Source)
不同類型的事件源包括:
1. 事件和消息服務,例如:?RabbitMQ, MQTT, SES, SNS, Google Pub/Sub
2. 存儲服務,例如:S3, DynamoDB, Kinesis, Cognito, Google Cloud Storage, Azure Blob, iguazio V3IO (object/stream/DB)
3. 端點服務,例如:物聯網(IoT)、HTTP網關(HTTP Gateway)、移動設備、Alexa、Google Cloud Endpoints
4. 配置存儲庫,例如:Git, CodeCommit
5. 使用特定于語言的sdk的用戶應用程序
6. 定時事件-允許定期調用函數。
?
事件源到函數的關聯(Event Source to Function Association)
函數是由事件源觸發的事件調用的。函數和事件源之間有一個n:m映射。每個事件源可以用來調用多個函數,一個函數可以由多個事件源觸發。事件源可以映射到函數的特定版本或函數的別名,后者提供了更改函數的方法,并部署了一個新版本,而不需要更改事件關聯。事件源也可以定義為使用同一函數的不同版本,定義應為每個函數分配多少流量。
在創建了一個函數之后,或者在以后的某個時間點,需要將事件源關聯起來,該事件源應該作為該事件的結果觸發函數調用。這需要一組操作和方法,例如:
1. 創建事件源關聯
2. 更新事件源關聯
3. 列出事件源關聯
?
函數輸入(Function Input)
函數輸入包括事件數據(event data)和元數據(metadata),并且可以包括一個上下文對象(context object)。
?
事件數據和元數據(Event data and metadata)
事件詳細信息應傳遞給函數處理程序,不同的事件可能具有不同的元數據,因此函數需要能夠確定事件的類型并輕松解析通用和特定于事件的元數據。
將事件類與實現分離是可取的,例如:處理消息流的函數將工作相同,而不管流存儲是Kafka還是Kinesis。在這兩種情況下,它都將接收消息體和事件元數據,消息可以在不同的框架之間路由。
事件可以包括單個記錄(例如,在請求/響應模型中),或者接受多個記錄或微批(例如,在流模式中)。
FaaS解決方案使用的常見事件數據和元數據示例:
- 事件類別
-?版本
-?事件ID
-?事件來源/來源
-?源識別
-?內容類型
-?消息體
-?時間戳
事件/記錄特定元數據的示例:
-?HTTP: 路徑、方法、頭、查詢參數
-?Message Queue:消息隊列:主題,標題
-?記錄流(Record Stream):表、鍵、op、修改時間、舊字段、新字段
事件源結構示例:
-?AWS Lambda:http://docs.aws.amazon.com/lambda/latest/dg/eventsources.html
-?Microsoft Azure?Functions:https://docs.microsoft.com/azure/azure-functions/functions-triggers-bindings
-?Google?Cloud Functions:https://cloud.google.com/functions/docs/concepts/events-triggers
有些實現將JSON作為向函數傳遞事件信息的機制來關注。這可能會增加高速函數(例如流處理)或低能耗設備(IOT)的大量序列化/反序列化開銷。在這些情況下,將本機語言結構或其他序列化機制視為選項可能是值得的。
?
函數上下文(Function Context)
當調用函數時,框架可能希望提供對跨多個函數調用的平臺資源或常規屬性的訪問,而不是將所有靜態數據放在事件中,或強制函數在每次調用時初始化平臺服務。
上下文作為一組輸入屬性、環境變量或全局變量傳遞。有些實現使用這三種方法的組合。
上下文示例:
-?函數名、版本、ARN
-?存儲限制(Memory Limit)
-?請求ID(Request ID)
-?云區(Cloud Region)
-?環境變量(Environment Variables)
-?安全密鑰/令牌(Security keys/tokens)
-?運行時/bin路徑(Runtime/Bin paths)
-?日志(Log )
-?數據綁定(Data binding)
一些實現使用日志對象初始化日志對象(例如,作為AWS中的全局變量或Azure中的部分上下文),用戶可以使用集成平臺工具跟蹤函數執行。除了傳統的日志記錄之外,未來的實現可能會將計數器/監視和跟蹤活動抽象為平臺上下文的一部分,以進一步提高功能的可用性。
數據綁定作為函數上下文的一部分,平臺根據用戶配置啟動到外部數據資源的連接,這些連接可以在多個函數調用中重用。
?
函數輸出(Function Output)
當函數退出時,它可以:
-?向調用者返回一個值(例如,在HTTP請求/響應示例中)
-?將結果傳遞到工作流中的下一個執行階段
-?將輸出寫入日志
應該有一種確定的方法來知道函數是否通過返回的錯誤值或退出代碼成功或失敗。
函數輸出可以是結構化的(如HTTP響應對象)或非結構化的(如某些輸出字符串)。
?
無服務器函數工作流(Serverless Function Workflow)
在無服務器域中,用例(Use Case)屬于以下類別之一:
-?一個事件觸發一個函數
-?事件的和/或組合觸發一個函數
-?一個事件觸發順序或并行執行的多個函數
-?函數的結果可能是另一個函數的觸發器
-?n個事件(i n和/或)觸發m個函數,即事件函數交錯的工作流,如事件1觸發函數1,完成函數1和事件2以及事件3觸發函數2,然后函數2的不同結果觸發分支到函數3或函數4。
用戶需要一種方法來指定他們的無服務器用例或工作流。例如,一個用例可以是“在照片上傳到云存儲時在照片上進行人臉識別(發生照片存儲事件)。”另一個物聯網用例可以是“在接收到運動檢測事件時進行運動分析”,然后根據分析功能的結果,或者“觸發房屋警報并調用e警察部門“或只是”將運動圖像發送給房主。“有關詳細信息,請參閱用例部分。
AWS提供“步驟函數”(step function),供用戶指定其工作流,但步驟函數不允許指定觸發工作流中哪些函數的事件/事件。
下圖是涉及事件和函數的用戶工作流的示例。使用這種函數圖,用戶可以輕松地指定事件和函數之間的交互,以及如何在工作流中的函數之間傳遞信息。
?
?功能圖狀態包括:
- Event State(事件狀態):此狀態允許等待來自事件源的事件,然后觸發函數運行或多個函數按順序、并行或在分支中運行。
- Operation/Task State(操作/任務狀態):此狀態允許按順序或并行運行一個或多個函數,而不等待任何事件。
-?Switch/Choice State(切換/選擇狀態):此狀態允許轉換到多個其他狀態(例如,前一個函數結果觸發分支/轉換到不同的下一個狀態)。
-?End/Stop State(結束/停止狀態):此狀態以失敗/成功終止工作流。
-?Pass State(通過狀態):此狀態在兩個狀態之間插入事件數據。
-?Delay/Wait State(延遲/等待狀態):此狀態導致工作流執行延遲指定的持續時間或直到指定的時間/日期。
狀態和相關信息需要保存在一些持久存儲中,以便進行故障恢復。在某些用例中,用戶可能希望將來自一個狀態的信息傳遞到下一個狀態。這些信息可以是函數執行結果的一部分,也可以是與事件觸發器關聯的輸入數據的一部分。需要在每個狀態定義一個信息過濾器,以過濾出需要在狀態之間傳遞的信息。
?
參考
-?CNCF Serverless Whitepaper v1.0?
-?CNCF Serverless WG
-?An I&O Leader’s Guide to Serverless Computing
-?Guide to Serverless Technologies
作者:杰客大叔
鏈接:https://www.jianshu.com/p/aa07e656b83d
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
總結
以上是生活随笔為你收集整理的【转】无服务计算(Serverless Computing)核心知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 几月份买银行理财划算?年底理财产品会涨吗
- 下一篇: 【转】.net框架读书笔记---CLR内