這篇文章是我在2018年PyBay大會上演講的版本。所以非常非常抱歉發這麼晚,你可以看這部分內容的視頻。所有的示例代碼都在附帶的Github倉庫裏面。
如果你聽說過Serverless的話,你可能會把它當做一種雲架構模式,可以將一個應用程序所需要的、長期維護的基礎設施數量降到比較低的水平。在某些場景下,這種方式可以節省很多成本。而且也確是是這樣的。但是在這篇文章裏面,我會在一個新的場景下,介紹相關的應用程序:高度並行的函數計算程序和生產環境下的機器學習系統。
如果你只是一個數據科學家的話,你可能不太瞭解什麼是serverless。我們將會以serverless最常用的應用場景—— Web 業務內容作爲開篇。不過值得注意的是,如果你受限於計算資源的話,serverless是一個輕量級的替代方案,可以幫助你搭建類似於Spark集羣一類的內容。在沒有運維團隊的幫助下,就可以很輕鬆的將你的簡單示例發佈到生產環境上面。
Serverless的爭議
大多數的數據科學家對運維都不是很感興趣,但這也是一個好的場景,能顯示出serverless的與衆不同,請耐心的聽我說。
人們普遍認爲計算機的這種理念並不是很好。
雲環境裏最棒的一件事情就是,你不需要關心硬件相關的問題。你只需要付費給微軟、谷歌、亞馬遜一類的雲平臺,讓他們幫助你來處理。他們在這方面做的真的很好,以至於讓你忘記還有硬件這件事。
但向雲端遷移會帶來成本的變化。最基本一項就是金錢。主要是因爲,儘管我們利用了雲環境的伸縮與拓展的能力,但我們還是不可避免地爲一些未被充分利用的雲資源,進行長期的付費。
雖然雲成功地將硬件抽象化,我們還是需要安裝、配置、安全認證,和維護操作系統或數據庫等等。對於我們中的許多人來說,這是一種恥辱,因爲這並不是我們想花費時間去做的事。對於大多數的僱主來說,他們並不能從中獲得收益,因爲他們主要還是通過部署業務邏輯來盈利。
那麼,怎麼樣既能擺脫物理設施的束縛,又能忽視下一層——例如操作系統或者容器相關的內容?如果能做到這一點的話,我們就可以全身心地專注於業務邏輯。
這就是serverless的目標。
什麼是serverless
我們來考慮部署一個簡單的Serverless程序,實現兩數相加的邏輯。首先,請求會訪問到某一個網關服務中。這個例子中的請求的內容爲2+2。實際上,網關會傳輸數據到某一臺機器,並把該應用部署到那臺機器上。新機器做出響應後返回結果,然後停止退出。
另一個請求(37+5)過來的時候,也會發生同樣的事情:網關會創建一個全新的機器(並不會複用使用上一個實例的機器),該機器會在運算後就停止退出。至關重要的是,兩數相加的應用程序,並沒有實際的基礎設備。
通常來說,你可以理解爲基礎設施的數量與利用率成線性關係,而且截距爲0(這有助你讓你理解爲什麼Serverless的這個很便宜)
這種描述有點與衆不同。的確也省略了一些工程上的細節內容,不過作爲Serverless的新用戶而言,很大程度上可以忽視掉這些內容。
順便提一下,“Serverless”這個單詞並不是一個很好地名稱,理論上你還是有服務器的。不過實際上,你的服務器數量是無窮多個(從某種意義上來說,有點像非參數統計,這裏非參數其實是指你有非常多的參數,並不是傳統意義上的“非”。不過實際上而言,你並沒有)。
用AWS Lambda和Zappa進行serverless部署
總的來說,爲了使Serveless的利益最大化(例如,讓別人來幫你進行運維的工作),你需要爲使用Serverless平臺支付給雲平臺一定的費用。你可以在AWS Lambda,Google Cloud Fuctions和Azure Functions裏進行選擇。這些服務會創建、銷燬並以其他方式來管理大型的短生命週期機器池(像以上我們用於計算2+2和35+7那樣)。
爲了演示在AWS Lambda上的部署,讓我們用一個簡單的Python Flask應用程序來顯示當前時間:
# app.py
import datetime
from flask import Flask
app = Flask(__name__)
@app.route("/time")
def time():
return str(datetime.datetime.now())
if __name__ == "__main__":
app.run()
如果你之前沒有了解過Flask,這裏有模板可供你參考,但重點是time函數(返回時間)以及它前面的裝飾器。如果有人訪問/time路徑,它會告訴Flask返回函數的結果。
你可以通過運行python app.py在本地“部署”這個應用:
$ python app.py
* Serving Flask app "app" (lazy loading)
* Environment: production
* Debug mode: off
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
當你訪問127.0.0.1:5000/time 的時候,你將看到當前時間:
$ curl 127.0.0.1:5000/time
2019-05-09 21:09:46.450550
如果筆記本電腦被合理地設置了防火牆,偶爾會進入睡眠狀態,那麼在本地長時間部署這個應用就不是很合適。現在我們把它部署到AWS Lambda上面。
這會涉及到大量的手動的工作,不過好消息是可以通過使用命令行工具來幫助我們完成任務。我推薦Zappa. 之所以喜歡它,是因爲它是用Python寫的,至少在原則上,它不會關注你往哪個serverless平臺上發佈。至於其它的工具,我瞭解的,是名字很容易混淆的Serverless和 AWS 的Chalice.
以下是如何使用Zappa發佈上面的time應用。首先你要創建並激活一個新的虛擬環境,然後在裏面安裝相關的依賴庫。像上面的例子,就需要安裝Flask和Zappa。 在相同的路徑下,複製上面的app.py文件,然後運行zappa init:
python -m venv venv
source venv/bin/activate
pip install flask zappa
zappa init
zappa init會快速引導你處理一些相關的問題。這個簡單的小例子中,你接受默認的設置就可以了。以下是生成的配置文件:
$ cat zappa_settings.json
{
"dev": {
"app_function": "app.app",
"aws_region": "us-east-1",
"profile_name": "default",
"project_name": "basic",
"runtime": "python3.6",
"s3_bucket": "zappa-ycr5dtiyk"
}
}
然後執行zappa deploy,這時Zappa的作用就顯現出來了:
$ zappa deploy
Calling deploy for stage dev..
Downloading and installing dependencies..
- sqlite==python36: Using precompiled lambda package
Packaging project as zip.
Uploading basic-dev-1534393616.zip (6.2MiB)..
100%|██████████████████████████████| 6.54M/6.54M [00:05<00:00, 902KB/s]
Scheduling..
Scheduled basic-dev-zappa-keep-warm-handler.keep_warm_callback with expression rate(4 minutes)!
Uploading basic-dev-template-1534393629.json (1.6KiB)..
100%|█████████████████████████████| 1.59K/1.59K [00:00<00:00, 3.29KB/s]
Waiting for stack basic-dev to create (this can take a bit)..
100%|███████████████████████████████████| 4/4 [00:09<00:00, 4.89s/res]
Deploying API Gateway..
Deployment complete!: https://ucyxlhvz7f.execute-api.us-east-1.amazonaws.com/dev
他幫助我們處理了很多複雜的內容。最值得注意的是,它創建了一個包含應用程序和其依賴項(默認情況下是根據虛擬環境的安裝內容來進行的)Zip文件,並將其複製到AWS上面。在輸出內容的最後,你會發現一個URL,你可以用它來替換之前使用的localhost。
該URL不會長期有效(因爲我運行了zappa undeploy),但請相信我,此刻的結果是這樣的:
$ curl https://ucyxlhvz7f.execute-api.us-east-1.amazonaws.com/dev/time
2019-05-10 04:30:59.270893
大體上,對URL進行請求和響應的全過程如下:
- 一個計算機憑空出現了。
- 跟Zappa一起被上傳的應用程序和依賴項會被部署到這臺新的計算機上。
- 新計算機接受請求。
- 計算並返回響應。
- 該計算機被毀掉。
每次訪問這個URL的時候都會發生同樣的事情。(實際上,AWS會對實例進行緩存,來保證請求可以正常響應。但從概念上說,每個請求都會創建新的實例,並在執行結束後銷燬。)
關鍵的一點是,這個相當複雜的過程意味着,你的應用程序正處於生產環境中,是可以公開訪問的,而且在不使用她的時候,你就不用支付任何費用。
我已經把這篇文章中所有的代碼都放在Github倉庫裏了。其中我也演示瞭如何升級已發佈的應用程序,傳遞時區作爲URL的參數。Zappa讓升級變得很容易(通過執行zappa update命令即可),並提供了很方便的zappa tail命令,在你的筆記本終端,從已發佈的應用程序組件中整合日誌和錯誤信息。如果你部署出現了問題或者正在運行的應用拋出異常(例如,用戶提供了無效參數),調試會更容易些。一般情況下,你甚至可以使用serverless(尤其是帶有AWS Lambda的Zappa)配置cron任務,使其在serverless執行器上運行。舉個例子,請看我的報告天氣的Twitter機器人。
Serverless的優勢與限制
serverless的普遍優點在於,它能讓你更專注於業務邏輯,並且在部署時有無限的可擴展性。另一方面,一些人認爲serverless與微服務架構(例如,複雜性方面)以及雲部署(例如,供應商對資源鎖定的風險)有着相同的缺點。個人工程師購買的範圍各異,當然這跟我們這篇文章中的數據科學部分(即將要討論的)並沒有太大的關係,所以不想在這做過多解釋。
對於數據科學用例來說,serverless最明顯的優勢就是成本:因爲我們只在代碼運行的時候付費,沒有未使用資源浪費的問題,支付的費用與使用量成正比,往往很便宜。比如說,Postlight的Readability API每個月在EC2上的費用是10000美元,轉移到AWS Lambda後,現在每月費用僅爲370美元。
但事實上,說serverless貴也是無可厚非的。考慮一下上面的圖(很簡略)。serverless的成本與利用率呈線性關係且截距爲0。通常情況下,這要比小型部署的其他方案便宜。而且對於計算使用量很大的情況,它可能更便宜。但如果每秒要處理數千個請求,那麼所需要的成本可能會在交叉點之後,這樣的話,非serverless所需的成本反而會更低一些。
可能serverless和傳統部署模式之間最根本的區別在於機器的性質,他們會隨時消失或者出現(與其說是缺點,不如說是serverless一系列固有的限制)。到目前爲止,我對他們也是一直很模糊。某種程度上,對他們工作方式的理解還是很有限的。但我要把我知道的都告訴你。
這些機器都是動力不足的。對於AWS Lambda,寫入時的RAM不足3GB,本地存儲也相對較小(75GB)。他們是靠借來的時間過活。函數必須在15分鐘內執行完畢。那些條件很隨意又多變(就在前不久,Lambda的限制變爲1.5GB、500MB和300秒!)
但不可避免的限制就是,這些段生命週期較爲短暫的機器是無狀態的,這是serverless的固定的前提條件,並且不會改變。之前的實例都是沒有歷史記錄的。他們甚至不能直接與其他運行在serverless上的實例進行通信。因此,除去發Twitter或寫入數據庫這類的消息之外,serverless的實例只支持能有輸入和返回值的純函數。沒有全局狀態。
說實話,這時候你可能會想:哇,serverless聽起來好可怕。繼續跟我往下看。
AWS Lambda和pywren的參數映射函數
因此,會有這樣的機器:
- 沒有內在狀態。
- 也不是很快。
但實際上,
- 這樣的機器有很多。
- 並且只需在使用時付費。
這大大提升了數據科學家對此感興趣的可能性!本文其餘部分會介紹這部分內容,以及名爲Phwren的概念驗證工具,最早是在“佔領雲:99%的分佈式計算”中被提及。儘管你之前可能沒讀過CS論文(或者讀過一點兒),不過我強烈推薦這篇文章(或者早報的評論)。
下面是一張數據科學的圖片,預示着我們即將進入本文的另一個新部分。
Pywren是一個以Lambda作爲計算後端,跨參數訪問函數的工具。在Python2中,大概是這樣:
>>> def square(x):
... return x * x
>>> args = [1, 2, 3, 4, 5, 36]
>>> map(square, args)
[1, 4, 9, 16, 25, 36]
map函數調用了另一個函數(該例子中爲square函數)以及函數所需要的參數,並返回這些程序的結果列表。在Python3中,由於map的計算速度比較慢(也就是,返回一個生成器,你可以立即使用,也可以稍後再用),這最終變得更加冗長。如果你沒遇到這個問題,那就不用擔心(其實我們還是需要擔心的是,2019年底,Python2將不再被支持使用)。
如果你是JS或Haskell以及其他語言的程序員的話,可能對map不陌生。但如果你是一個Python程序員,可能對map函數一無所知。在Python的世界裏面,更貼近的是list的結構內容,可以幫助你理解,表面看上去不一樣,但基本的思想都是相同的:
>>> [square(x) for x in args]
[1, 4, 9, 16, 25, 36]
Pywren爲Python的內置map函數提供了一個(幾乎)直接的替代,對每個應用函數的參數都使用了一個獨立的AWS Lambda實例,來替代本地機器。其語法如下:
>>> import pywren
>>> pwex = pywren.default_executor()
>>> futures = pwex.map(square, args)
>>> futures
[<pywren.future.ResponseFuture at 0x11422ffd0>,
<pywren.future.ResponseFuture at 0x11422f588>,
<pywren.future.ResponseFuture at 0x11422f358>,
<pywren.future.ResponseFuture at 0x11422f748>,
<pywren.future.ResponseFuture at 0x10bbfff98>,
<pywren.future.ResponseFuture at 0x11422f470>]
>>> futures[0].result()
0
>>> [f.result() for f in futures]
[1, 4, 9, 16, 25, 36]
其實,它也並不完全是map的直接替代品,因爲它返回的是futures對象列表,而不是結果。但或多或少,你也可以從中得到一些信息。
當我們使用Pywren的時候都發生了什麼?以下是我的理解:
- Pywren將函數進行序列化並放到S3上,並引入Lambda(上圖中的“host submit”)。
- Lambdas開始工作(上圖中的“task start”)。
- 他們需要做一些設置,包括從S3上提取和反序列化job,以及安裝Anaconda Python運行時機制(上圖中的“setup done”)。
- 計算結果並寫入S3(“task done”),等待我們調用result方法。
- 當我們調用這個方法時,會把下載的結果返回給客戶端(“result returned”)。
注意,順便說一下,X軸上的刻度。是的,我們並行做了很多事,但相對任務來說,開銷(約20秒!)是巨大的。我們回過頭再來討論這個問題。
高度並行計算和胡蘿蔔問題
由於高度並行計算問題,square函數只能作爲Pywren的候選方案。這是爲什麼呢?
想象一下有一片胡蘿蔔地。總共8行,每行10個。你有一臺收割機,每秒可以摘1根胡蘿蔔。那麼,收割所有的胡蘿蔔需要用80秒。
🥕🥕🥕🥕🥕🥕🥕🥕🥕🚜
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
如果有2臺收割機會怎麼樣呢?他們可以獨立工作,用一半的時間就可以收割這些胡蘿蔔。
🥕🥕🥕🥕🥕🥕🥕🥕🥕🚜
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
🥕🥕🥕🥕🥕🥕🥕🥕🥕🚜
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
🥕🥕🥕🥕🥕🥕🥕🥕🥕🥕
那麼,要是有8臺收割機,10秒就能收割整片地。
🥕🥕🥕🥕🥕🥕🥕🥕🥕🚜
🥕🥕🥕🥕🥕🥕🥕🥕🥕🚜
🥕🥕🥕🥕🥕🥕🥕🥕🥕🚜
🥕🥕🥕🥕🥕🥕🥕🥕🥕🚜
🥕🥕🥕🥕🥕🥕🥕🥕🥕🚜
🥕🥕🥕🥕🥕🥕🥕🥕🥕🚜
🥕🥕🥕🥕🥕🥕🥕🥕🥕🚜
🥕🥕🥕🥕🥕🥕🥕🥕🥕🚜
因爲拖拉機可以獨立工作,速度與工人數量成正比。這個過程與共同編寫一本書還是有差異的,因爲兩個作者需要經常交流,告訴對方各自到目前爲止都完成了什麼。但拖拉機是完全獨立的。沒有員工之間的交流。這就是並行。
在Python中,通常你會把它實現成列表的形式,就跟我們描述的典型問題一樣。for循環雖有副作用,但並不會引發高度並行問題。但如果把循環轉換成我們理解的那樣,那麼也會有高度並行問題。
高度並行的Pywren示例:
現在,將前6位數進行平方計算是一件很酷的事,真實的工作原理又是怎樣的呢?讓我們看以下幾個例子:
1. 網站檢索
我想從某個會議網站上搜集成千上萬的機器學習論文的摘要。因爲我是一次性把它們都抓取出來,這樣在我自己的電腦上會花費很長的時間。本來可以通過並行CPU上的任務來加快這個進程,但仍會受到網絡連接速度帶來的限制。
通過使用pywren,將此場景轉換爲lambda的話,就可以並行工作//RH:我能夠並行工作嗎?同時,也得益於AWS更快的網絡連接!代碼大致如下:
>>> def scrape_batch(batch):
... for paper in batch:
... paper["abstract"] = scrape_abstract_for_one_paper(paper)
... return batch
>>> batches = [[paper1, paper2, ...], [paper101, paper201, ...], ...]
>>> pywren.get_all_results(pwex.map(scrape_batch, batches))
這種情況下,將所有的論文列表都收集到一個論文上,並沒有通過方法進行映射。相反地,我可以通過函數進行映射,該函數將一批文件剪貼到一批文件的列表上。我這樣做是因爲,處理一篇論文的速度相對比較快。那麼如果每次處理一篇論文,這就意味着,主要的開銷轉嫁到設置Lambda的實例數量上面去了。不斷在增加論文的數量,直到20秒左右的執行時間即可,最大限度地提高了速度。
以上是僞代碼。如果感興趣的話,完整的代碼(以及生成的數據集)在GitHub上。
2. 布萊克-斯科爾斯方程
布萊克-斯科爾斯方程是描述股票期權演化的偏微分方程。布拉德福德·林奇解決數百萬種構型的問題。每個解都是一個相當複雜的數值計算,需要幾十秒。如果沒有並行化,這項任務將在一臺機器上執行3天的時間。在使用pywren的AWS lambda上,只需要16分鐘。
3. 視頻編碼
視頻編碼算法的某些部分是高度並行的方式,因爲它們一次只能執行一幀。“編碼,快和慢:使用數千個小線程的低延遲來進行視頻處理”一文中,描述了類似於Pywren的方法在這個問題上的應用。
比較有趣的是,因爲在視頻編碼中有一個非常重要的速度閾值:你能以每秒24(或60)幀的速度編碼嗎?除此之外,你還處於實時視頻編碼領域,這將打開新型的用例。這一點也很有趣,因爲與Pywren不同,這種方法並不會對單個批處理執行單個lambda提交;作者爲正在進行的視頻提供了一個長期存在的管道。Serverless數據工程!
4. 超參數優化
一般來說,機器學習算法很難並行化。例如,在開始討論分佈的系統問題之前,分佈式梯度下降就是一個著名的算法問題。
但是,ML工作流中的一部分,非常適合Pywren,即超參數優化。
假設我們有一些訓練數據,有兩個類(黃色和紫色)和兩個特性。我們可以使用scikit-learn在本地訓練此數據模型。這是用來說明這個想法的幼稚的假設。不要糾結在這個驗證的結果,想象一下這個場景背後的問題!
>>> from sklearn.neighbors import KNeighborsClassifier
>>> classifier = KNeighborsClassifier(n_neighbors=5)
>>> classifier.fit(Xtrain, ytrain)
>>> classifier.score(Xtest, ytest)
0.838
這裏,n_neighbors是一個“超參數”——ML算法需要一個神奇的數字,你必須根據當前的問題逐層分析。在這種情況下,我們需要選擇有多少的附近訓練樣本,來決定下一步的權重問題。
通常的方法是用一個簡單的搜索方式:嘗試所有可能的方法,並選擇一個給出最精確模型。這是典型的高度並行的例子,所以我們可以使用pywren!我們需要一個n_neighbors的值列表供我們測試,以及一個能返回經過訓練的模型並映射到列表上的函數:
>>> all_hyperparams
[{'n_neighbors': 1},
{'n_neighbors': 2},
{'n_neighbors': 3},
{'n_neighbors': 4},
{'n_neighbors': 5},
{'n_neighbors': 6},
{'n_neighbors': 7},
{'n_neighbors': 8}]
>>> def train_model(hyperparams):
... classifier = KNeighborsClassifier(**hyperparams)
... classifier.fit(Xtrain, ytrain)
... return classifier
現在,我們可以將這個內容發送到AWS lambda:
>>> futures = pwex.map(train_model, all_hyperparams)
>>> classifiers = pywren.get_all_results(futures)
>>> for hyperparams, classifier in zip(all_hyperparams, classifiers):
... print(hyperparams, classifier.score(Xtest, ytest))
{'n_neighbors': 1} 0.758
{'n_neighbors': 2} 0.782
{'n_neighbors': 3} 0.814
{'n_neighbors': 4} 0.82
{'n_neighbors': 5} 0.838
{'n_neighbors': 6} 0.838
{'n_neighbors': 7} 0.842
{'n_neighbors': 8} 0.828
值得注意的是,pywren不僅發送例如數字這種簡單的結果。它還可以返回具有屬性和方法的Python對象(在本例中,是經過訓練的SciKit學習分類器)。這使我們能夠使用本地測試集來計算每個模型的精度,並從筆記本電腦中,設置並選擇最好的一個。
serverless的機器學習活動
假設我們序列化最佳模型(顯然n_neighbors=7),並將其上傳到到公共的S3中。這樣我們就可以做最後的操作了!
還記得Zappa嗎,我在本文開頭演示的CLI,可以幫助我們部署flask的應用。如果使用zappa來部署這個Flask應用程序,那麼你在生產環境中,就可以進行機器學習了!
url = "https://s3.amazonaws.com/modelservingdemo/classifier.pkl"
r = requests.get(url)
classifier = pickle.loads(r.content)
@app.route("/predict")
def predict():
X = [[float(request.args['feature_1']),
float(request.args['feature_2'])]]
label = classifier.predict(X)
if label == 0:
return "purple blob"
else:
return "yellow blob"
如果你不相信我的話,請訪問已經部署的應用程序,更改URL參數嘗試一下。
有一個完整的創業公司的具體實踐,該方法通過serverless的基礎設施,將機器學習引入到生產環境。在這裏比上面的十幾行python代碼更加健壯和複雜。
更多的相關限制
文章開始的時候,我們談及對serverless(複雜性、鎖定、成本)的工程性評論及其侷限性(無狀態、有限的RAM和生存週期)。
在結束之前,我想在數據科學的討論內容中,添加一些內容。
首先,讓我們解決一些對lambda實例規範的基本限制。如果單個函數應用程序花費的時間超過900秒,那麼除非您將其分解爲較小的原子任務,否則AWS lambda將無法發揮其作用。這可能很棘手。Lambda實例沒有GPU,這限制了他們深度學習的效果。
其次,讓我們更深入地來討論一下算法。實際上Pywren只適合解決高度並行的問題。雖然MapReduce的工作是高度並行的,但他們大多數都會有重組的過程,這個過程裏面,結果會被聚合在一起並分發出去,方便進一步處理。Pywren團隊和其他人士已演示了將中間結果寫入S3的解決方案。但此時,pywren不再是python map函數的內置替代品。你需要更仔細地考慮將要並行化的算法結構。
幸運的是,在線性代數方面,Pywren團隊通過發佈numpywren,爲我們解決了一些問題。它聽起來就像:從用戶角度來看,一個與numpy非常相似的線性代數庫。後端使用AWS Lambda來進行計算,但通過處理業務流程和所需的通信,將最快的算法應用於serverless的線性代數上,這遠遠超越了Pywren。
結論
所以,你已經瞭解了serverless在網站部署和運行cron作業上的優點。最後你看到了,它在某一種計算上是很有優勢的,也就是高度並行化的東西。你甚至可以結合這些思想,想象一個工作流:使用pywren在AWS lambda上運行超參數優化,然後使用zappa將最佳模型部署到AWS lambda上。serverless在這些方面是很有優勢的,因爲它相對容易設置,並且使用起來很便宜。
它之所以便宜(不考慮本文中的高級原則),是因爲這些應用程序有着共同點:它們都是突發式數據。有的時候他們需要大量資源,在這種情況下,lambda可以通過擴展來容納這些資源。但有時候,它們幾乎或者完全不需要任何資源。你的web產品是新的,你的cron作業沒有啓動,或者你正在做交互式的工作,或者正在盯着筆記本,試圖找出這結果意味着什麼。這時如果你用了serverless,你就不必再爲這段時間花錢。
所以:serverless的優勢不在於你用它的時候它是多麼強大(儘管擴張能力很強),而是在你不用它的時候。
AWS不是爲你使用的東西付費,而是爲你忘記關掉的東西付費。-DeadProgrammer(@DeadProgrammer)2019年4月24日
還記得Pywren論文被稱爲“99%的分佈式計算”嗎?1%的數據科學在從事數據科學的組織中運作,其規模總是需要一些計算資源的,全球各地都在使用,所以幾部不存在不使用的情況,又或者是他們的使用量非常大,相比較而言,購買集羣機器更加合適(譯者注:前提提到的曲線交點,超過交點,使用Serverless反倒費錢)。假如數據科學家有數據工程學、工具和維護團隊,來處理這些長期使用的資源。本文中描述的serverless,並不是爲上述的這種數據科學家所準備的。
但是,如果你是獨立運營的,並且沒有資金和工程學支持的團隊,或對重量級解決方案沒有什麼興趣,那麼就瞭解一下Zappa、Pywren和serverless生態系統吧。
感謝大家來參加我的TED演講。