Serverless(baas & faas)無服務器計算

  自從2014年AWS推出Lambda服務後,Serverless一詞愈來愈熱,已經成爲一種新型的軟件設計架構,即Serverless Architecture。做爲一種原生於公共雲的架構,Serverless有什麼優缺點?是否能應用於傳統企業程序?是否適合私有云場景?是否像不少文章宣稱的同樣,會成爲將來改變雲計算的中堅力量?做爲一名雲計算行業的老兵,做者想在此文中分享一些本身的觀點。數據庫

  什麼是Serverless小程序

  Serverless並不神祕,用一個簡單的例子就可講明。咱們設計了一個AI應用,能夠識別出圖片中人物的人種,咱們把它做爲一種SaaS服務架設在公共雲上提供給客戶使用,其典型的後端架構設計以下:後端

  

  在該架構中,咱們購買的雲主機上運行了Tomcat Web Server,用於承載Java編寫的AI應用。用戶經過API上傳圖片。受限於雲主機的本地存儲空間,爲了知足大量客戶同時上傳圖片,AI應用實現了一個存儲網關將圖片導入公共雲的對象存儲。圖片導入完成後,AI應用從對象存儲讀入圖片進行識別,並將結果存入公共雲的數據庫中(例如RDS),用戶使用API查詢結果。安全

  AI應用上線一段時間後受到了用戶的歡迎,愈來愈多的公司開始使用該服務。根據統計數據,大多數公司在上午9點~11點、下午2點~5點集中上傳圖片,爲了知足該時間段的突發訪問量,咱們設置了公共雲的Auto-Scaling策略,在訪問增長時動態建立更多的雲主機來響應客戶。AI應用的架構演化成:網絡

  

  在這個架構中,咱們須要作以下事情:數據結構

  1. 管理雲主機。咱們要關心CPU數量、內存大小、IP地址等等系統級的配置。同時還要關心雲主機的操做系統,爲部署AI應用擬定策略。操做系統和Tomcat的安全補丁也不能忽視,不然競爭對手可能僱傭黑客來攻擊咱們的系統。架構

  2. 配置公共雲的Auto-Scaling的策略,應對高峯期突發訪問量。併發

  3. 使用公共雲的對象存儲和數據庫。框架

  4. 編寫AI應用。less

  要完成這些工做,咱們既要開發AI應用,又要營運支撐業務(例如管理雲主機生命週期、管理操做系統)。這是當前架構的現實:爲20%的核心業務營運80%的支撐業務。

  下面用Serverless架構改寫AI應用:

  

  使用公共雲提供的Serverless框架(例如AWS的Lambda)改寫應用後,咱們再也不須要雲主機和Tomcat了。用戶也能夠直接將圖片上傳到對象存儲,AI應用註冊了對象存儲的一組事件,當圖片上傳完成後,代碼會被觸發運行在一個全新的進程內,對圖像識別並將結果存入數據庫。圖片識別完後,AI應用退出,運行代碼的進程也隨之銷燬。當有多個用戶上傳圖片時,其架構變爲:

  

  多個運行AI應用代碼的進程被啓動,併發處理用戶上傳的圖片。

  在Serverless架構的AI應用中,咱們只須要作兩件事情:

  1. 使用公共雲的對象存儲和數據庫。

  2. 用公共雲的Serverless框架編寫AI應用。

  與以前的架構相比,咱們再也不營運雲主機、操做系統、Tomcat,同時也不須要配置Auto-Scaling Group,公共雲的Serverless框架會在每一個圖片上傳完成後啓動一個進程運行AI應用,自動實現水平擴展。咱們終於只須要關心核心業務了,用Serverless框架支持的語言(例如AWS Lambda就支持Java, Python和JVM系語言)編寫AI應用,一切非核心業務都外包給了公共雲營運商。

  咱們的Serverless AI應用用到了兩種技術。首先使用了公共雲提供的對象存儲和數據庫服務,統稱爲BaaS(Backend as a Service,後端即服務)。其次用了Lambda框架,稱爲FaaS(Functions as a Service,函數即服務)。

  使用BaaS和FaaS是Serverless應用的基本特徵,符合這兩個基本特徵的應用可稱爲Serverless應用。

  是BaaS,不是PaaS

  AI應用用到了對象存儲和數據庫,未來或許還會用到消息隊列。直觀感受是在使用PaaS,爲何還要造一個新詞BaaS?技術圈有太多使人混淆的術語了。

  BaaS並不是PaaS,它們的區別在於:PaaS須要參與應用的生命週期管理,BaaS則僅僅提供應用依賴的第三方服務。典型的PaaS平臺須要提供手段讓開發者部署和配置應用,例如自動將應用部署到Tomcat容器中,並管理應用的生命週期。BaaS不包含這些內容,BaaS只以API的方式提供應用依賴的後端服務,例如數據庫和對象存儲。BaaS能夠是公共雲服務商提供的,也能夠是第三方廠商提供的,例如Facebook收購的Parse就是著名的MBaaS提供商(Mobile Backend as a Service)。從功能上講,BaaS能夠看做PaaS的一個子集,即提供第三方依賴組件的部分。

  FaaS是Serverless的核心

  AI應用最初是一個典型Java程序,它可能使用Spring這樣的技術,由於咱們須要一個框架確保程序的各個組件可以被正確加載,須要MVC來保證REST API被正確的Controller處理。AI應用部署在Tomcat容器中,運行在雲主機上,7 x 24小時運行,咱們提供不間斷的服務。在夜裏12點到早晨8點,幾乎沒有用戶使用,但咱們還得讓它待在那裏,防止深夜偶爾使用的用戶獲得一個503錯誤而誤會AI服務不穩定。咱們爲購買的雲主機付錢,儘管一半的時間它的CPU使用率幾乎爲0,但沒有公共雲是按CPU使用率計費的,不工做的時間也得付錢。咱們必須關心Auto-Scaling Group的配置,如何準確的配置Auto-Scaling策略是一個技術活,須要長期的經驗積累,在早期咱們不得很少部署一些空閒的雲主機以保證服務不會因Auto-Scaling的配置不當而擁塞。

  用Serverless架構改寫了AI應用後,這些痛苦就統統消失了。Spring框架和Tomcat去掉了,用Lambda的Java SDK,只須要實現一個Function Handler處理圖片上傳完成這個事件,這跟寫一個Callback同樣簡單。在Function Handler中調用圖片識別的相關邏輯,而後調用數據庫的REST API存儲結果。也不用構建MVC,不用配置Tomcat的XML文件,咱們將存儲網關這個功能徹底去除掉了,由於用戶能夠直接上傳圖片到對象存儲。

  AI應用不用7 x 24小時運行了,沒有用戶上傳圖片時它只是一份編譯好的代碼。當用戶圖片上傳完成時,FaaS會爲AI應用啓動一個新的進程執行代碼。該進程在代碼執行完成後自動銷燬。咱們只需爲代碼執行的這幾十秒鐘付錢,節省了不少開支。

  最後咱們無需操心Auto-Scaling的問題,FaaS會在須要的時候自動擴展。

  這些就是FaaS的核心,從上面的例子裏面能夠概括出它的特色:

  1. FaaS運行的是後端代碼而不是整個後端程序。例如AI應用僅僅包含處理圖片上傳完成這個事件的邏輯,並非一個完整的後端程序,而是一段後端代碼。

  2. 代碼經過事件觸發。因爲再也不有一個長期運行的進程等待或輪詢用戶請求,代碼只能經過特殊的事件觸發。這些事件由FaaS框架定義,例如上傳文件到對象存儲、消息隊列收到一條新的消息、API Gateway收到一個新的API請求等。

  3. 代碼的生命週期很短。例如咱們的AI應用,從收到事件後Function Handler被調用開始,到調用返回結束,不會有常駐內存的進程運行。此外公共雲提供商還會限制代碼執行的時間,超出時間後執行代碼的進程會被強行銷燬。例如AWS的Lambda可執行的最長時間爲5分鐘。

  4. 代碼必須作到完全無狀態,兩次調用間不能共享內存狀態。咱們的AI應用最先使用了一個全局變量統計處理的圖片數,每處理完一張圖片該計數器就加一。使用FaaS後咱們不能再用任何全局變量或內存數據結構(例如Hashmap)在調用間共享數據,由於代碼運行在獨立的進程中,沒法訪問對方的內存地址空間。因而咱們對代碼進行了改造,將全局計數器放到了公共雲的Redis服務中,這爲代碼增長了額外的複雜性。

  5. 水平擴展再也不是須要擔憂的問題,FaaS會爲每一個事件和請求運行一份新的代碼。

  6. 應用的部署方式從上傳、配置整個程序變成上傳一份打包代碼的文件(例如Jar文件或一個Zip文件)。

  Serverless爲咱們帶來了什麼

  對比傳統架構,用Serverless架構改寫的AI應用具備顯著的優點。咱們再也不運維任何雲主機和操做系統,甚至再也不運維Tomcat這樣的Web容器,只須要專一於代碼自己,全部配置、應用生命週期管理的工做都由FaaS框架負責。公共雲的出現讓咱們從物理硬件管理中解放出來,Serverless架構讓咱們進一步從操做系統管理中解放出來,第一次真正專一於核心業務。

  業務也變得更加敏捷了。咱們只須要編寫核心業務相關的代碼,例如AI應用中圖像識別的部分。無需編寫任何加載、部署、配置應用的代碼,例如再也不須要配置systemd在系統啓動時加載應用。

  水平擴展也不是問題。正如前面反覆說起的,FaaS框架會爲每個事件、每個API請求都啓動一份新的進程執行代碼。這跟傳統應用的線程池方式相似,每一個請求都在一個單獨的線程中執行,區別在於線程之間共享同一內存地址空間,FaaS的進程間不共享任何內存。與線程池有最大線程數限制相似,FaaS框架一般也限制了最大進程數,例如AWS Lambda在一個Region默認能執行的最大併發調用是600,也就是說咱們的AI應用最多能在600個進程中同時執行。

  最後,也是最重要的,Serverless架構爲咱們節省了大量開支。咱們只需爲AI應用運行的時間付錢,無需爲應用等待請求的時間付錢。水平擴展的粒度從原來的雲主機細化到進程,節省了額外的開支,不用再購買閒置的雲主機來抵消Auto-Scaling的配置不精確帶來的影響。業務的敏捷性提升也下降了營運成本,咱們再也不須要精通操做系統配置和管理的營運人員,不只節省了人力成本,也節省了應用從開發到上線的時間。

  Serverless不是銀子彈,是後端小程序的將來

  Serverless架構在某些應用場景的優點如此明顯,有些支持者已經開始炒做它會成爲顛覆性的雲計算新架構了。技術圈向來如此,一些人總在孜孜不倦的尋找包治百病的靈藥,和解決一切問題的銀子彈。「All design is about tradeoff」,Serverless也不是銀子彈,它有獨特的優點,而這些優點也帶來了不可避免的侷限。

  爲每一個事件/請求啓動一個全新的進程運行代碼是FaaS的核心,進程的啓動延時是Serverless面臨的第一個問題。取決於編寫應用的語言,啓動延時能夠是10毫秒(如簡單的Python應用),也能夠是1分鐘(複雜的Java應用)。這樣的延時對於realtime的程序是難以接受的。目前Serverless應用一般運行在公共雲的多租戶環境中,啓動延時還受系統負載影響,很難保證應用在規定時間內被運行。公共雲提供商目前沒有對Serverless提供相應的SLA保證,筆者寫這篇文章的時候,AWS Lambda尚未相關的SLA條款。

  Serverless沒法用於高併發應用,爲每一個請求啓動一個進程開銷過高。例如雙十一支付寶高峯期每秒處理的交易數爲8.59萬筆,若是使用Serverless架構,意味着咱們的系統內每秒有8.59萬個進程被建立又被銷燬,這是難以負擔的開銷。

  Serverless應用沒法常駐內存,運行的時間是受限的。若是你的應用沒法在數分鐘內完成的工做,那Serverless不是你的選擇,例如AWS Lambda給予進程的最長運行時間是5分鐘,超時後進程將被強制終止。這對程序設計提出了挑戰,例如咱們的AI應用必須優化到在5分鐘內完成複雜圖像的識別。咱們也不能編寫執行長時間IO操做的應用,例如對對象存儲中1T的數據進行復雜編碼。

  Serverless調用之間不能共享狀態讓編寫複雜程序變得極度困難。無狀態是互連網應用追求的目標,例如知足「12要素」的應用。但Serverless將無狀態進行的更加完全,在不一樣的調用之間沒法共享內存狀態,例如使用hashmap。咱們的AI應用中統計已處理圖片總數的全局計數器在傳統架構中只是一個全局變量,但在Serverless架構中它變成存儲在內存數據庫(Redis)中的一條記錄,更新成本、保證原子性等因素讓咱們的編碼變得數倍複雜。對於大多雲原生的互聯網應用來講,這種完全的無狀態架構是一個巨大的挑戰,而對於動輒有幾十萬、上百萬行代碼的、充滿了狀態的企業應用來講,Serverless的無狀態改造幾乎是一個沒法完成的任務。

  熟練的微服務的架構師,對將業務拆分紅一個個單獨的服務很是熟悉,也有很多的經典書籍(例如《Building Microservices: Designing Fine-Grained Systems》)指導咱們如何作。但即便是他們,在面對Serverless架構時也會感到頭痛,如何將業務拆分紅成百上千個運行在獨立進程、運行時間受限的函數是巨大的挑戰。而是否須要如此細粒度的拆分是須要回答的第一個問題。有些問題或許變成無解難題又或成本極高,例如分佈式數據庫事務。

  上面都是Serverless架構的一些固有侷限,它們源於Serverless架構的特色,很難隨着時間的推移、技術的完善而解決。除此以外,做爲一個新的技術,Serverless還面臨着集成測試困難、Vendor Lock-in、調試監控困難、版本控制等諸多不足,每一項都會成爲採用Serverless架構的阻礙。

  因爲這些侷限性,Serverless架構不會成爲複雜應用的架構首選,相反,它應該是後端小程序的將來。

  雲端的應用有大量的小程序場景,例如識別一張圖片、對一段音頻/視頻進行編解碼、對IOT設備的請求返回一小段數據、將客戶提交的工單經過郵件通知客服人員等等。這些基於事件觸發的小程序在傳統架構中實現起來是相對複雜的,你每每須要爲20%的核心業務運營80%的支撐業務。Serverless完美的解決了這些問題,它能夠成爲複雜應用的一種補充架構。咱們能夠將無狀態的、事件觸發的業務拆分紅Serverless應用,讓整個架構變得更加的簡潔和高效。

  Serverless也在不斷演變,例如AWS最近引入的Step Functions就嘗試解決調用間共享狀態的問題,其效果有待觀察。

  Serverless不是傳統的PaaS

  Serverless跟PaaS之間的界線比較模糊,不少人認爲Serverless是PaaS的一種,筆者也傾向於認爲Serverless是特殊的PaaS形態。

  Serverless由BaaS和FaaS兩部分構成,BaaS負責提供業務的依賴服務,FaaS負責業務的部署和生命週期管理,從這個意義上來看,Serverless的角色跟PaaS同樣。與傳統PaaS的區別在於,傳統PaaS是以程序爲粒度管理應用的生命週期,而Serverless是以函數粒度管理應用生命週期。傳統PaaS中的應用爲常駐內存的進程,而Serverless應用運行完即銷燬。此外,使用傳統PaaS,用戶仍須要關心水平擴展,例如如何配置Auto-Scaling Group,但Serverless沒有這個問題,水平擴展是架構自然自帶的功能。

  Serverless和微服務

  Serverless和微服務沒有直接關係,但二者有類似之處,例如都須要作業務拆分、強調無狀態、具備敏捷特性等。Serverless在不少方面比微服務粒度更細,要求也更嚴格。例如微服務以服務爲邊界拆分業務,Serverless以函數爲邊界拆分業務;微服務能夠有跨調用的內存狀態共享,Serverless要求調用完全無狀態。此外,Serverless依賴BaaS提供第三方依賴,而微服務能夠自由選擇第三方依賴來源,例如使用本地搭建的傳統中間件棧(如本地MySql和消息總線)。

  Serverless和容器

  Serverless和容器是蘋果和桔子的比較,不在一個平面上。Serverless是一種軟件設計架構,容器是軟件架構的承載者。雖然沒有公開資料,但咱們能夠推測相似於AWS Lambda這樣的Serverless框架使用了某種程度的容器技術,否者難以實現語言無關和毫秒級的啓動。儘管已經有一些開源項目使用Docker實現Serverless中的FaaS部分,筆者不認爲AWS Lambda這樣的公共Serverless框架直接使用了Docker,必定是一種更爲輕量級、體積更小的容器技術,咱們或許能夠將它稱爲Nano-Container。

  Serverless對私有云有意義嗎?

  對於私有云來講,如今將業務遷往Serverless架構還爲時過早。首先Serverless是從公共雲中演化出來的新型架構,適用於運行在公共雲上的小程序。而私有云更多承載的是老而笨重的傳統業務,難以用Serverless架構改造。其次Serverless依賴BaaS,在私有云中搭建和運維BaaS成本都不低,使用公共BaaS服務又受限於網絡帶寬和延時,容易致使系統不穩定。

  隨着企業應用的進一步雲化、開源Serverless框架的成熟,私有云的Devops場景也能夠採用Serverless做CI/CD,例如目前Jenkins承擔的大部分工做均可以用Serverless替代,如用FaaS框架對應Jenkins自己,上傳的代碼對應Jenkins Job中的Bash腳本,將原來的Jenkins API觸發Job改成觸發FaaS中的代碼。

  總結

  Serverless做爲一種全新的架構,是雲計算髮展演化的必然結果。追求更細粒度的計費單元,更加專一於核心業務、將支撐業務外包給基礎設施提供商是雲計算的趨勢。Serverless架構的特色,讓編寫事件觸發的後端小程序變得更加容易。同時它也有自身內在的侷限性,並不適合複雜的應用架構。從目前的狀況看,部分採用Serverless的混合架構對公共雲應用是個不錯的選擇,私有應用採用Serverless還爲時過早。雲計算技術正在飛速發展,將來還有無限可能。

轉載自:http://blog.csdn.net/chenhaifeng2016/article/details/71425173

做者:張鑫

相關文章
相關標籤/搜索