Serverless 的資源評估與成本探索

Serverless 佈道師在講解 Serverless 架構和雲主機等區別的時候,總會有類似的描述:

傳統業務開發完成想要上線,需要評估資源使用。根據評估結果,購買雲主機,並且需要根據業務的發展不斷對主機等資源進行升級維。而 Serverless 架構,則不需要這樣複雜的流程,只需要將函數部署到線上,一切後端服務交給運營商來處理。即使是瞬時高併發,也有云廠商為您自動擴縮。

但是在實際生產中,Serverless 真的無需評估資源麼?還是說在 Serverless 架構下,資源評估的內容、對象發生了變化,或者簡化呢?

在 騰訊云云函數 中,我們創建一個雲函數之後,有這麼幾個設置項:

Serverless 的資源評估與成本探索

內存設置範圍為 64~1536M,超時時間範圍為 1~900s。這些設置項其實已經涉及到了資源評估。

超時時間

先說超時時間,一個項目或者一個函數,一個 Action 都是有執行時間的。如果超過某個時間沒執行完,就可以評估其為發生了「意外」,可以被「幹掉」了,這個就是超時時間。

例如一個獲取用戶信息的簡單請求,假設 10s 內沒有返回,證明已經不滿足業務需求,此時就可以將超時設置為 10s。如果有另一個業務,運行速度比較慢,至少要 50s 才能執行完,那麼這個值的設置就要大於 50,否則程序可能因為超時被強行停止。

內存

內存是一個有趣的東西,可能衍生兩個關聯點。

關聯點 1:

程序本身需要一定的內存,這個內存要大於程序本身的內存。

以 Python 語言為例:

<code># encoding=utf-8
import jieba
def main_handler(event, context):

jieba.load_userdict("./jieba/dict.txt")
seg_list = jieba.cut("我來到北京清華大學", cut_all=True)
print("Full Mode: " + "/ ".join(seg_list)) # 全模式

seg_list = jieba.cut("我來到北京清華大學", cut_all=False)
print("Default Mode: " + "/ ".join(seg_list)) # 精確模式

seg_list = jieba.cut("他來到了網易杭研大廈") # 默認是精確模式
print(", ".join(seg_list))

seg_list = jieba.cut_for_search("小明碩士畢業於中國科學院計算所,後在日本京都大學深造") # 搜索引擎模式
print(", ".join(seg_list))/<code>

注:為了讓結果更直觀,差距更加大,這裡每次都重新導入了自帶了 dict,該操作本身就是相對浪費時間和內存的。在實際使用中 jieba 自帶緩存,並且無需手動導入本身的 dict。

當導入一個自定義的 dict 到 jieba 中,如果此時用默認設置:128M 內存限制 + 3s 超時限制,就會這樣:

Serverless 的資源評估與成本探索

可以看到,在導入自定義 dict 的時候,內存消耗過大, 默認值 128M 不能滿足需求,此時將其修改成最大:

Serverless 的資源評估與成本探索

系統提醒時間超時,因此還需要再修改超時時間為適當的數值(此處設定為10s):

Serverless 的資源評估與成本探索

因此,在關注程序本身的前提下,內存需要設置到一個合理範圍內。這個範圍是 >= 程序本身需要的內存數值。

關聯點 2:計費相關。

在雲函數的 計費文檔 中,有如下描述:

雲函數 SCF 按照實際使用付費,採用後付費小時結,以為單位進行結算。 SCF 賬單由以下三部分組成,每部分根據自身統計結果和計算方式進行費用計算,結果以為單位,並保留小數點後兩位。

資源使用費用調用次數費用外網出流量費用

調用次數和出網流量這部分,都是程序或者使用相關了,而資源使用費用則有一些注意點:

資源使用量 = 函數配置內存 × 運行時長 用戶資源使用量,由函數配置內存,乘以函數運行時的計費時長得出。其中配置內存轉換為 GB 單位,計費時長由毫秒 (ms) 轉換為秒 (s) 單位,因此,資源使用量的計算單位為

GBs(GB-秒)。 例如,配置為 256MB 的函數,單次運行了 1760 ms,計費時長為 1760 ms,則單次運行的資源使用量為(256/1024)×(1760/1000) = 0.44 GBs。 針對函數的每次運行,均會計算資源使用量,並按小時彙總求和,作為該小時的資源使用量。

這裡有一個非常重要的公式,那就是函數配置內存運行時長。

函數配置內存就是剛才所講:我們為程序選擇的內存大小。運行時長,就是我們運行程序之後得到的結果:

Serverless 的資源評估與成本探索

以該程序為例,用的是1536MB,則使用量為 (1536/1024) * (3200/1000) = 4.8 GBs

當然,250MB 的情況下,程序也可以運行:

Serverless 的資源評估與成本探索

此時的資源使用量為 (256/1024) * (3400/1000) = 0.85GBs

相對比上一次,程序執行時間增加了 0.2s,但是資源使用量降低了將近 6 倍!

儘管 GBs 的單價很低,但是當業務量上來之後,也不能忽略。剛才的只是一個單次請求,如果每天有 1000 此次請求,那:

  • 1536 MB: 4.810000.00011108 = 0.5 元
  • 25 MB:0.8510000.00011108 = 0.09442 元

僅計算資源使用量費用,而不計算調用次數/外網流量)

如果是一萬次調用,那就是 50 元和 9 元的區別。隨著流量越大,差距越大。

當然很多時候函數執行時間不會這麼久,以個人的某函數為例:

Serverless 的資源評估與成本探索

計費時間均是 100ms,每日調用量在 6000 次左右:

Serverless 的資源評估與成本探索

按照 64M 內存來看,單資源費用只要 76 元一年,如果內存都設置稱為 1536,則一年要 1824 元!這個費用相當於:

Serverless 的資源評估與成本探索

所以說,「超時時間」的設置需要評估代碼和業務場景,它關係到程序運行的穩定性和功能完整性。同時,「內存」也不僅僅影響程序的使用層面,還關乎費用成本。那麼,既然資源評估如此重要,如何評估呢?

還是以上述代碼為例,在本地進行簡單的腳本編寫:

<code>from tencentcloud.common import credential
from tencentcloud.common.profile.client_profile import ClientProfile
from tencentcloud.common.profile.http_profile import HttpProfile
from tencentcloud.common.exception.tencent_cloud_sdk_exception import TencentCloudSDKException
from tencentcloud.scf.v20180416 import scf_client, models

import json
import numpy
import matplotlib.pyplot as plt

try:
cred = credential.Credential("", "")
httpProfile = HttpProfile()
httpProfile.endpoint = "scf.tencentcloudapi.com"

clientProfile = ClientProfile()
clientProfile.httpProfile = httpProfile
client = scf_client.ScfClient(cred, "ap-shanghai", clientProfile)

req = models.InvokeRequest()
params = '{"FunctionName":"hello_world_2"}'
req.from_json_string(params)

billTimeList = []
timeList = []
for i in range(1,50):
print("times: ", i)
resp = json.loads(client.Invoke(req).to_json_string())
billTimeList.append(resp['Result']['BillDuration'])
timeList.append(resp['Result']['Duration'])

print("計費最大時間", int(max(billTimeList)))
print("計費最小時間", int(min(billTimeList)))

print("計費平均時間", int(numpy.mean(billTimeList)))

print("運行最大時間", int(max(timeList)))
print("運行最小時間", int(min(timeList)))
print("運行平均時間", int(numpy.mean(timeList)))

plt.figure()
plt.subplot(4, 1, 1)
x_data = range(0, len(billTimeList))
plt.plot(x_data, billTimeList)
plt.subplot(4, 1, 2)
plt.hist(billTimeList, bins=20)
plt.subplot(4, 1, 3)
x_data = range(0, len(timeList))
plt.plot(x_data, timeList)
plt.subplot(4, 1, 4)
plt.hist(timeList, bins=20)
plt.show()

except TencentCloudSDKException as err:
print(err)/<code>

執行代碼會得到這麼一張圖:

Serverless 的資源評估與成本探索

從上到下分別是不同次數計費時間圖、計費時間分佈圖、不同次數運行時間圖和運行時間分佈圖。通過對 256M 起步,1536M 終止,步長 128M,每個內存大小串行靠用 50 次,統計表:

Serverless 的資源評估與成本探索

注:為了讓統計結果更加清晰,差異性更大,在程序代碼中進行了部分無用操作用來增加程序執行時間。正常使用 jieba 基本都是毫秒級的。

Serverless 的資源評估與成本探索

通過表統計可以看到,在滿足程序內存消耗的前提下,內存大小對程序執行時間的影響並不是很大,反而對計費影響很大。

函數併發量

除了超時時間和運行內存,用戶還需要評估一個參數:函數併發量。在項目上線之後,需要對項目的併發量進行評估。當併發量超過默認值,要及時聯繫售後同學或者提交工單進行最大併發量的提升。

小結

綜上,Serverless 架構也是需要資源評估的,而且資源評估同樣和成本是直接掛鉤。只不過這個資源評估的對象逐漸發生了變化,相對之前的評估維度、難度而言,都是大幅度縮小或者降低的。


分享到:


相關文章: