- Serverless從入門到進階:架構、原理與實踐
- 方坤丁 孫遠高
- 6101字
- 2021-06-24 11:19:10
4.2 Serverless和存儲
本節主要介紹存儲服務的基本概念、分類以及和FaaS聯動的應用場景。存儲服務是BaaS服務中重要的組成部分,FaaS和存儲服務相結合,可以在Serverless架構下實現文件存儲、緩存共享、文件上傳等多個常用場景,進一步完善了Serverless架構所需的數據存儲和數據共享能力。
4.2.1 基本概念
如圖4-3所示,存儲主要分為塊存儲、文件存儲和對象存儲三個類型。塊存儲需要把云盤掛載到主機上,在格式化安裝文件系統后才能使用,支持高性能隨機讀寫,但是共享困難,需要分區管理,主要用于數據庫、OLTP(On-Line Transaction Processing,聯機事務處理過程)等場景。文件存儲可以掛載多個客戶端環境,無須格式化,可共享存儲,方便訪問,主要用于文件共享,流媒體處理等場景。對象存儲則將非結構化的數據(視頻、鏡像、軟件等)當作完整的對象進行存取,無須掛載,通過HTTP協議可直接發起對象讀寫,支持大規模并發,但不支持隨機寫,主要用于視頻、文件和應用的存儲、備份歸檔等場景。下文將從和Serverless結合的角度出發,對對象存儲和文件存儲進行進步說明。

圖4-3 存儲產品橫向對比
表4-1展示了不同存儲類型的功能對比,其中塊存儲是高度結構化的,因為每個數據塊都排列在結構化的固定塊中,便于搜索和索引。而文件存儲是通過分層的方式被索引和結構化。對象存儲則是非結構化的,因為沒有用于數據存儲的格式或者結構,只是簡單的對象列表。
表4-1 不同存儲類型功能對比

4.2.2 對象存儲
在云計算時代,對于數據高效存儲、遷移的需求越來越大,以AWS S3為標準的對象存儲服務因其平滑擴展、無縫接入的能力受到廣泛的歡迎,成為業界規范。其他云廠商也相繼推出了無目錄層次結構、無數據格式的限制、支持HTTP/HTTPS訪問的分布式存儲服務——對象存儲。綜合業界較為主流的對象存儲服務,可以總結出該服務具有如下特性。
- 存儲可靠:多副本冗余存儲,可達12個9(即9999999999.99%)的數據持久性,保障數據耐久性。
- 高可用:提供特定SLA(如99.95%)的高可用性,支持異地容災、跨域復制等特性。
- 開放兼容:支持SDK、API、命令行、GUI等工具,提供批量操作、遷移等能力,讓使用和接入更為簡單方便。
- 數據安全:提供防盜鏈能力,支持多租戶隔離、HTTPS加密傳輸及數據加密等功能。
- 高并發:可支持上萬QPS的請求,保障高并發下的業務穩定。
- 多種規格:根據業務場景訪問頻度的高低,提供標準、低頻和歸檔存儲等多種類型。提供更具性價比的解決方案。例如低頻存儲適用于較低訪問頻率的場景,可用于網盤、大數據分析等場景;歸檔存儲適用于檔案、醫療影像、科學資料等適合長期保存,但需要較長解凍時間的數據。
除此之外,對象存儲聯動其他云上服務,可以支持更多場景,有很大的想象空間,這里簡單介紹幾個典型的應用場景供讀者參考。
1. 數據處理
對于用戶傳入對象存儲的數據,可結合多種數據處理類服務進行編輯、處理和審核,如圖4-4所示。針對圖片數據,用戶可結合數據萬象進行裁剪、縮放、轉碼、銳化、添加水印等操作,還可以進行鑒黃、鑒政、鑒暴恐等內容審核。針對視頻數據,用戶可進行轉碼、水印、截幀等處理。針對文檔數據,用戶可利用第三方服務生成文檔的圖片或HTML預覽,并對預覽圖添加水印。

圖4-4 數據處理
2. 內容分發
網站服務通常會在動態網頁中根據一定的規則,區分開經常變動和長期不變的資源,靜態資源是指長期不變的非結構化數據資源,如圖4-5所示。對象存儲提供了靜態資源的存儲和分發能力,減輕資源服務器的壓力,并利用無限容量、高頻讀寫的特性,為靜態資源提供可擴展能力和可靠的存儲。用戶可以將網站中的靜態內容(包括音視頻、圖片等文件)全部托管在標準存儲中,并利用內容分發網絡(CDN)分發。利用CDN全球加速節點的能力,可以將熱點文件提前下發至邊緣節點,降低訪問延遲。

圖4-5 內容分發
3. 大數據分析
無論用戶存儲的是醫療或財務方面的數據還是照片和音視頻之類的多媒體文件,對象存儲都可以作為數據源進行大數據分析,如圖4-6所示。對象存儲支持存儲EB級別的非結構化數據,具備高可用、高可靠、高安全和可擴展性,結合大數據服務,可以快速構建和部署分析應用程序。在實現高性能計算需求后,可以將數據轉換為歸檔存儲,降低服務使用成本,以便長期存儲數據。

圖4-6 大數據分析
4.2.3 文件存儲
隨著業務的蓬勃發展,對于數據存儲和管理的需求越來越明顯。企業主要面臨著存儲容量不足、資源配置復雜、采購運營成本高、利用率低及不能滿足大數據分析需求等幾大挑戰。而NAS(Network Attached Storage)存儲以其靈活擴展、高性能、易用等優勢,廣泛應用在多個行業中。文件存儲作為云上NAS存儲的代表服務,和各個計算服務如云服務器、容器和FaaS函數等搭配使用,可以為多個計算節點提供容量和性能可彈性擴展的高性能共享存儲。當前NAS文件存儲服務普遍支持下列功能和特性。
- 支持多種協議:支持NFSv3.0/NFSv4.0、SMB協議,支持POSIX訪問語義,兼容POSIX接口,可跨平臺訪問,保證文件數據的一致性。
- 共享訪問:多臺主機或容器服務可以共享同一個文件系統,運行在不同可用區的計算節點也可以通過VPC網絡使用同一個文件系統,實現多計算節點的協同工作及數據共享。
- 彈性掛載/卸載:支持上萬節點并發掛載,文件系統性能會隨存儲容量線性增長,用戶可以靈活掛載或卸載文件系統。
- 彈性擴容:單文件系統支持PB級存儲,文件系統容量可隨用戶使用而彈性擴容,無須提前分配資源。
- 安全控制:具有極高的可用性和持久性,支持細粒度權限控制,支持VPC網絡及基礎網絡的網絡隔離及來訪用戶白名單訪問控制。
- 傳輸加密:支持在掛載文件系統時啟用傳輸層安全性(TLS),實現數據傳輸加密。
- 數據備份及冗余:數據3份冗余,具備高可靠、高可用的特性;提供數據備份的能力,用戶可以根據業務需求定期進行數據備份。
NAS文件系統結合其他服務,可以支持以下常用的應用場景。
1. 企業文件共享
企業員工辦公時通常需要共享和訪問相同的數據集,管理員可以通過對文件系統進行管理和設置,授獲組織中的個人訪問有關資源,還可以在文件系統中對特定的用戶組統一設置權限,如圖4-7所示。

圖4-7 企業文件共享
2. 流媒體處理
文件存儲支持CIFS/SMB協議,兼容Windows 7、Windows Server 2008/2012等多種操作系統,支持數萬客戶端并發訪問,提供高吞吐量、毫秒級響應等特性,為吞吐量及延遲要求高的視頻、圖像渲染場景提供保障,如圖4-8所示。

圖4-8 流媒體處理
3. 大數據分析
文件存儲支持數萬客戶端并發訪問,具備超大容量、高吞吐、NFS協議的文件鎖特性,為數據讀寫一致性需求強的大數據分析場景提供了保障,如圖4-9所示。

圖4-9 大數據分析
4. Web服務及內容管理
文件存儲作為一種持久性強、吞吐量高的文件系統,可用于各種內容管理場景,例如為網站、在線發行、存檔等各種應用服務提供數據源文件,如圖4-10所示。

圖4-10 Web服務及內容管理
4.2.4 存儲和FaaS的聯動
1. 對象存儲
對象存儲和云上多服務聯動能夠提供豐富的場景支持,云函數也是其中之一。對象存儲支持以觸發器的方式,通過JSON事件和函數進行交互,觸發函數并支持用戶自定義觸發事件和處理邏輯。例如可以通過定義對象存儲中的文件上傳或刪除等操作觸發函數,并增加條件進行過濾。函數被觸發后,也可以在代碼中自定義處理邏輯。
在指定的COS Bucket發生對象創建或對象刪除事件時,會將JSON格式的事件數據發送給綁定的FaaS函數,如代碼清單4-2所示。
代碼清單4-2 對象存儲觸發FaaS的事件消息結構
{ "Records": [{ "cos": { "cosSchemaVersion": "1.0", "cosObject": { "url": "http://testpic-1253970026.cos.ap-chengdu.myqcloud.com/testfile", "meta": { "x-cos-request-id": "NWMxOWY4MGFfMjViMjU4NjRfMTUyMVxxxxxxxxx=", "Content-Type": "", "x-cos-meta-mykey": "myvalue" }, "vid": "", "key": "/1253970026/testpic/testfile", "size": 1029 }, "cosBucket": { "region": "cd", "name": "testpic", "appid": "1253970026" }, "cosNotificationId": "unkown" }, "event": { "eventName": "cos:ObjectCreated:*", "eventVersion": "1.0", "eventTime": 1545205770, "eventSource": "qcs::cos", "requestParameters": { "requestSourceIP": "192.168.15.101", "requestHeaders": { "Authorization": "q-sign-algorithm=sha1&q-ak=xxxxxxxxxxxxxx&q-sign-time=1545205709;1545215769&q-key-time=1545205709;1545215769&q-header-list=host;x-cos-storage-class&q-url-param-list=&q-signature=xxxxxxxxxxxxxxx" } }, "eventQueue": "qcs:0:scf:cd:appid/1253970026:default.printevent. $LATEST", "reservedInfo": "", "reqid": 179398952 } }] }
通過FaaS和對象存儲產品進行聯動,可以快速部署輕量級的業務處理邏輯,實現自動化處理,整個聯動流程如圖4-11所示。通過一鍵配置對象存儲作為事件的監聽器,并在FaaS函數中基于不同的編程語言和第三方庫自定義處理邏輯,可以實現業務的自動化處理。通過FaaS平臺的彈性伸縮能力,完美應對流量負載的波峰、波谷。

圖4-11 FaaS函數和對象存儲結合場景
圖4-12所示是對象存儲觸發FaaS的一些典型場景,如音視頻轉碼回傳。

圖4-12 FaaS函數和對象存儲結合場景
某家用攝像頭提供商基于Serverless架構,實現了攝像頭視頻回傳→處理(拼接、轉碼)→存儲方案。結合對象存儲+云函數+ Serverless DB,首先將回傳的視頻存儲到COS,然后自動觸發函數做拼接處理,最后通知DB做數據寫入。整個流程支持毫秒級彈性伸縮,即使遇到流量洪峰,也能完美承載。后來業務不斷發展(C端售賣量上升),整套方案無須二次開發,幾乎無容量上限,而Serverless按需付費的能力也極大地節約了機器資源和運維成本。
和用戶自建方案進行對比,在開發流程方面,云函數FaaS更加簡單高效,云函數自帶能力較完善;在運維方面,云函數更加易用和省心,降低了運維成本;在費用方面,云函數相比自建服務可節省30%以上的費用。總體而言,使用Serverless云函數實現音視頻轉碼服務的優勢有下列幾點。
- FaaS函數提供了標準的運行環境,并保障資源的高可用和彈性伸縮,無須專人維護。
- FaaS函數根據實際業務消耗收費,不存在資源浪費。
- FaaS函數的開發調試流程更加高效,依賴和業務解耦,可以單獨更新,支持實時熱更新。
- 運行環境隔離,單次請求失敗不影響正常執行其他請求。
2. 文件存儲
基于FaaS平臺“無狀態性”的運行原理,各云廠商FaaS的運行環境都有較為嚴格的限制。一般臨時緩存空間為512MB,并且只能存到/tmp目錄中。在這種情況下,隨著函數實例的銷毀(一般FaaS平臺的實例回收時間為30分鐘),這部分緩存也會被銷毀。為了確保這些數據能夠持久存儲,一般會引入對象存儲或數據庫將數據落盤。但在這種解決方案中,對象存儲主要用來存儲靜態資源。此外,文件存儲的讀寫速度不夠快,延遲較高。因此,在多函數之間的文件共享、大文件處理和緩存等場景中,需要引入CFS文件系統的掛載。當前各云廠商的解決方案是,支持在FaaS函數中配置對應的文件系統進行掛載,實現多函數對文件的共享存儲和訪問。
文件系統聯動FaaS的常用場景有機器學習、音視頻文件處理、數據共享、內容管理系統等。
(1)機器學習
機器學習場景需要大量的數據存儲和較大的依賴庫,因為FaaS平臺的限制,所以這種場景難以在單個云函數中實現(由上文可知,平臺對單個函數的限制一般為500 MB,而機器學習的依賴庫常達到GB級別)。但引入了文件存儲做BaaS服務后,可以通過文件存儲承載較大的依賴庫,例如TensorFlow等,從而讓函數可以執行機器學習模型。當然,這種情況也需要考慮因過大的依賴包引入冷啟動的問題,預置并發實例是當前比較好的一種解決方案。FaaS函數結合文件存儲的架構如圖4-13所示。

圖4-13 FaaS函數和文件存儲結合場景:大體積依賴或代碼包
(2)音視頻文件處理
在音視頻文件的處理場景中,主要基于FFmpeg等通用開源庫對視頻文件進行轉碼等處理,通過Serverless實現該場景可以達到降低成本、彈性擴縮容的效果。通過將視頻源文件存放在文件存儲中,配合視頻切片,可以對大文件進行處理。函數平臺可以直接掛載文件存儲,對其中的文件進行處理,如圖4-14所示。

圖4-14 FaaS函數和文件存儲結合場景:音視頻文件處理
(3)數據共享場景
由于文件存儲支持多計算資源共享訪問,對應FaaS平臺,不同的函數可以以不同的權限訪問不同的文件存儲路徑。FaaS結合文件存儲能夠支持一些涉及共享數據的場景,例如需要持久化的用戶登錄session信息的存儲和共享,或者多個函數獲取不同的測試數據,進行黑盒測試后,將結果寫入回文件,文件存儲則可以根據對應的結果進行模型調整和結果分析。
3. Serverless結合存儲實現文件上傳
文件上傳和下載是網頁端網站建設和開發中十分典型的場景,在圖片識別、視頻上傳等業務場景中有廣泛的應用。在不同的語言環境中,處理HTTP上傳、下載的方法有很多,結合Serverless架構進行實現時,根據不同的場景和成本預估,能夠選擇不同的解決方案。由于各個云廠商對HTTP請求和響應的內容限制為6MB,因此對于大小不同的文件大小,也有不同的實現方式。
- 文件小于6MB:結合API網關做Base64解碼。
- 文件大于6MB:由于FaaS函數本身無法對文件做持久化,函數實例生命周期結束后會被回收和銷毀,因此需要結合存儲服務實現文件上傳能力。這種情況下又有以下三種實現方式。
-
- 分片上傳,將大文件切分成小塊,完成上傳后再拼接起來。
- 借助COS對象存儲功能,先將文件上傳至COS,調用函數從COS下載文件,處理完之后進行回傳。
- 借助CFS文件存儲功能,將大文件存放在CFS盤中,通過函數掛在CFS,可以像讀寫普通文件系統一樣訪問CFS盤中的文件。
接下來,分別介紹上述上傳方案,詳解其實現方式、適用場景和優缺點。
(1)文件小于6MB
在本地開發時,如果要實現文件上傳功能,我們通常會用content-type:multipart/form-data類型作為請求頭實現HTTP文件上傳,或者將文件進行base64編碼之后再上傳。在文件不超過FaaS平臺限制的情況下,這種思路依然可以通過網關結合函數實現,即將小文件通過網關傳到FaaS函數平臺,并由函數將結果在對象存儲COS中做持久化。但這種實現方式也有諸多弊端。一方面,將文件直接從網關傳給函數時,需要用戶將文件轉換為base64編碼后再傳輸。函數通過網關收到數據后,再將base64編碼的文件進行解碼,之后進行持久化存儲。這一過程依賴用戶對代碼進行額外改造。此外,由于FaaS平臺的接入層,也就是API網關的數據包有6MB的限制,超過限制的文件會被裁剪或攔截。最后,通過API網關進行文件傳輸,需要較高的API網關和對象存儲COS的流量費,因此,傳輸大文件時,不建議直接通過網關,可以結合函數及存儲服務,對文件進行持久化處理。
(2)文件大于6MB
在文件大于6MB的情況下,需要結合FaaS函數和存儲服務進行文件持久化。其中最直觀的一種方式是直接傳輸文件到對象存儲中。在這個方案里,客戶端需要分別發起請求,獲得臨時上傳的地址,將文件上傳到COS,獲取處理結果。這種方式在二進制上傳、文件大小及成本控制方面都能提供更好的支持。以OCR文字識別為例,用戶上傳圖片,調用OCR接口將圖片轉換為文字并展示。這種場景更適合直接將文件上傳到COS對象存儲中,如代碼清單4-3所示。
代碼清單4-3 結合COS直傳文件
/** index.js * get cos temporary credential for uploading picture to cos * @param {string} uuid uuid */ async getCosTmpCredential(uuid) { const { Response } = await this.capi.request( { Action: 'GetFederationToken', Version: '2018-08-13', Name: uuid, // 上傳策略 Policy: JSON.stringify({ version: '2.0', statement: [ { effect: 'allow', action: [ 'name/cos:PutObject', ], resource: [ 'qcs::cos:${this.REGION}:uid/${this.TENCENT_APP_ID}:prefix//${this.TENCENT_APP_ID}/${this.BUCKET}/*', ], }, ], }), DurationSeconds: 7200, }, { host: 'sts.tencentcloudapi.com', }, ); Response.StartTime = Math.round(Date.now() / 1000); Response.Region = this.REGION; Response.BucketName = '${this.BUCKET}-${this.TENCENT_APP_ID}'; return Response; } /** * 獲取OCR結果 * @param {string} imgUrl image url * @param {string} lang language, default zh */ async getOCRResult(imgUrl, lang = 'zh') { const { Response } = await this.capi.request( { Action: 'GeneralBasicOCR', Version: '2018-11-19', ImageUrl: imgUrl, LanguageType: lang, }, { host: 'ocr.tencentcloudapi.com', }, ); return Response; } } module.exports = CloudApi; /*sls.js*/ app.post('/token', async (req, res, next) => { const uuid = req.body.uuid; const result = await apis.getCosTmpCredential(uuid); if (result.Error) { res.send({ code: 1, error: result.Error, }); } else { res.send({ code: 0, data: result, }); } }); app.post('/ocr', async (req, res, next) => { const imgUrl = req.body.imgUrl; const result = await apis.getOCRResult(imgUrl); if (result.Error) { res.send({ code: 1, error: result.Error, }); } else { res.send({ code: 0, data: result.TextDetections, }); } });
可以看到,通過/PutBucket方法將圖片直接上傳到COS桶中,之后通過getOCRResult獲取imgUrl,即文件地址,將其作為輸入進行OCR識別,即可解決該場景下大文件上傳的問題,并且傳輸速度更加穩定、成本也更低廉。
使用對象存儲做文件上傳,需要額外注意下面兩點。
- Web服務可能存在跨域問題,因此需要對COS桶進行跨域設置,即開啟CORS的支持。
- 因為客戶端直接將文件上傳到對象存儲中可能有較大的安全風險,所以可以考慮在服務端做簽名,通過客戶端獲取簽名結果,上傳文件到對象存儲的指定位置。
該項目的完整代碼地址為https://github.com/serverless-components/tencent-ocr。
另外一種方式是借助CFS文件存儲功能,對文件進行持久化,這種方式支持多個函數共享訪問。在這種實現方式中,COS通過HTTP進行上傳、下載,而CFS則需要FaaS函數進行內網(VPC私有網絡)配置,并掛載對應的文件盤,之后才能將文件寫入對應的路徑,如代碼清單4-4所示。
代碼清單4-4 結合CFS文件存儲實現文件上傳
/* index.js */ 'use strict'; var fs = requiret('fs'); exports.main_handler = async (event, context) => { await fs.promises.writeFile('/mnt/myfolder/filel.txt', JSON.stringify(event)); return event; };
由上述方案可知,當前在Serverless架構下,對于大文件的上傳依然需要做代碼改造或適配,才是較為理想且安全的方案。因此,Serverless架構下的持久化和文件上傳特性也需要持續優化,相信未來會出現更多適配Serverless架構的存儲方案。