天天看點

Serverless架構實作CDN預熱實踐分析

直達最佳實踐:【 Serverless架構實作CDN預熱最佳實踐

最佳實踐頻道:【

最佳實踐頻道 這裡有豐富的企業上雲最佳實踐,從典型場景入門,提供一系列項目實踐方案,降低企業上雲門檻的同時滿足您的需求!

為什麼要預熱

首先,什麼是CDN預熱呢?

CDN預熱是指源站主動将對應的資源緩存到CDN節點,當您首次請求資源時,即可直接從CDN節點擷取到最新的資源,無需再回源站擷取,進而降低通路延時,提升通路體驗。例如,在遊戲行業中,某個熱門遊戲首發時,會有大量玩家等待開服,第一時間下載下傳用戶端。通常遊戲用戶端都比較大,如果沒有預熱,最先體驗遊戲的玩家下載下傳時,CDN中還沒有緩存,就會先回源到源站擷取遊戲用戶端,這樣下載下傳速度往往會很慢,而且源站的主機CPU和帶寬在短時間内被大量使用者通路,也會占用大量資源,通常源站的帶寬成本比CDN要高,不但影響使用者體驗也增加帶寬成本。如果有了CDN預熱,在遊戲開服前把遊戲安裝包提前通過預熱的方式推送到各個CDN節點,最先開始下載下傳的玩家都能直接從CDN緩存中快速擷取安裝包,大大提升下載下傳體驗。

舉個“栗”子

接下來以一個山東遊戲使用者為例(以下資料為構造資料),在無CDN加速的情況下,直接通路源站,大概耗時50ms。在使用CDN,但CDN未命中的情況下,通過通路山東L1到北京L2到上海機房,整體延時大約40ms,比直接通路減少10ms。再看下,如果直接命中CDN緩存,則隻需要5ms,大大降低了通路延時,同時直接命中CDN緩存通路鍊路也極大縮短了,鍊路的通路品質顯著提升。可見如果能快速命中緩存,對使用者體驗的提升非常明顯,而CDN預熱是一種非常有效的手段。

Serverless架構實作CDN預熱實踐分析

Serverless架構有什麼好處

  • 按照CNCF對Serverless計算的定義,Serverless架構是指采用FaaS(函數即服務)和BaaS(後端服務)服務來解決問題的一種設計。這個架構免去了伺服器運維,具有更高擴充性和安全性,成本也更低。
  • 在CDN預熱方面,我們使用serverless架構,實作CDN預熱的自動化和智能化,原先需要開發大量的代碼、部署多個服務來實作CDN預熱,現在完全無需管理伺服器,比如作業系統的安全更新檔、故障更新和高可用都無需使用者考慮了。這種架構下資源變成了彈性擴充,不需做容量規劃,按需付費也降低使用成本。在安全性方面,使用者看不到伺服器,也不需要通過SSH登入,DDoS攻擊也交給雲廠商解決了。
  • 在架構方面變得更簡單了,使用者自動化送出預熱腳本後,在MNS裡面形成消息隊列,消息隊列自動化觸發函數計算,對需要預熱的資源進行預熱,整個過程完全以運維自動化的方式執行。
Serverless架構實作CDN預熱實踐分析

Serverless實作CDN預熱的思路

  • 首先,我們要尋找什麼适合預熱,前面介紹過熱點資源大檔案需要預熱,另外如果是小檔案,通路熱度非常高的内容,一出來就會被通路,而且回源時間也很短,這種資源往往本身命中就很高了,是以不需要預熱。另一類非常冷的資源,基本沒有使用者通路,從節約成本的角度,這種資源做預熱收益率太低也可以不考慮。是以通路熱度介于兩者之間的,或者有區域性質的内容,比如短視訊平台的本地視訊、新聞内容APP的本地新聞,直播平台的附近直播,這些資源傳播需要一定時間,可以通過預熱提前推送到CDN L2節點,加速資源通路效率。是以在函數計算中,我們可以編寫函數通過函數工作流定時排程執性函數去找出這樣的資源,添加到預熱URL清單中。
  • 其次,還要尋找什麼時間适合預熱,我們需要分析CDN的計費模式,如大客戶一般采用95峰值計費的方式,即以5分鐘記錄一個帶寬點,全月的值從大到小排列,去除前5%的峰值,取第95%的這個點作為實際計費帶寬。為了更好利用帶寬,預熱的時間最好選擇在波谷位置,這樣做到削峰填谷,降低帶寬使用成本。在Serverless架構下,我們使用函數計算編寫業務邏輯,可以有效控制預熱時間。
  • 當我們對預熱的内容和時間有了精準的控制後,自動化執行腳本,把需要預熱的URL推送到MNS作為緩存隊列,這樣也避免了預熱URL過多的情況下,分批送出導緻預熱效率過低的問題。消息隊列自動化觸發函數計算執行預熱任務。函數計算中的執行代碼參考如下:
from aliyunsdkcore.acs_exception.exceptions import ClientException
from aliyunsdkcore.acs_exception.exceptions import ServerException
from aliyunsdkcdn.request.v20180510.RefreshObjectCachesRequest import RefreshObjectCachesRequest
from aliyunsdkcdn.request.v20180510.PushObjectCacheRequest import PushObjectCacheRequest
from aliyunsdkcdn.request.v20180510.DescribeRefreshTasksRequest import DescribeRefreshTasksRequest
from aliyunsdkcdn.request.v20180510.DescribeRefreshQuotaRequest import DescribeRefreshQuotaRequest
def handler(event, context):
  id = 'LTA*********nRkRaYb7'
  secret = 'YJuNY*************rdeKLnl'
  client = AcsClient(id, secret, 'cn-shenzhen')
  obj = json.loads(event)
  doRefresh(obj['urls'], obj['type'], obj['objectType'], obj['area'], client)
  return 'hello world'
def doRefresh(lists,types,objectType,area,client):
    try:
      if types == 'clear':
        taskID = 'RefreshTaskId'
        request = RefreshObjectCachesRequest()
        if objectType:
          request.set_ObjectType(objectType)
      elif types == 'push':
        taskID = 'PushTaskId'
        request = PushObjectCacheRequest()
        if area:
          request.set_Area(area)
      taskreq = DescribeRefreshTasksRequest()
      request.set_accept_format('json')
      request.set_ObjectPath(lists)
      response = json.loads(client.do_action_with_exception(request))
      print(response)
    
      while True:
        count = 0
        taskreq.set_accept_format('json')
        taskreq.set_TaskId(int(response[taskID]))
        taskresp = json.loads(client.do_action_with_exception(taskreq))
        print("[" + response[taskID] + "]" + "is doing... ...")
        for t in taskresp['Tasks']['CDNTask']:
          if t['Status'] != 'Complete':
            count += 1
        if count == 0:
          break
        else:
          continue
        time.sleep(5)
    except Exception as e:
      sys.exit("[Error]" + str(e))           

總結

CDN預熱場景非常适合Serverless架構實作,比如内容和預熱時間選擇的自動化、消息隊列的緩存及監聽、自動化觸發函數執行URL預熱等有效幫助客戶業務提升緩存命中率、提高運維效率、降低帶寬使用成本,提升使用者體驗。

本文篇幅有限,更多的具體實作及實操參考最佳實踐:

Serverless架構實作CDN預熱
Serverless架構實作CDN預熱實踐分析