導讀:邊緣計算是在靠近物或資料源頭的一側,就近提供計算服務。其應用程式在邊緣側發起,產生更快的網路服務響應,滿足行業在實時業務、應用智慧、安全與隱私保護等方面的基本需求。本文作者介紹了在CDN節點上做實時資料處理的一些方式,值得架構師學習。
CDN-Content Delivery Network
我們先來定義下什麼是CDN。內容分髮網路(CDN)是一種由分散式伺服器構成的系統,它會根據使用者所處的地理位置,資料內容(通常是網頁)的來源,來向用戶分髮網頁內容。但目前這個網際網路發達的時代,CDN已經不僅僅用來分髮網頁內容。
以Cloudflare Workers【1】為例,除了利用它的網路來分發內容,你甚至還可以在它的邊緣節點上部署執行你的程式碼。“可以部署或執行Javascript程式碼,這能夠幫助你將程式碼與使用者終端裝置解耦合,比如支援透過程式設計實現路由、過濾等功能”。
在當前這個爆炸式發展的網際網路時代,高可擴充套件性是至關重要的能力。CDN和邊緣計算(Edge Computing)將會進一步融合式發展。
實時資料的獲取——推、拉
目前很多強調實時性的應用需要推送和拉取的資料。被動推送和主動拉取都是非常常見及簡單的工程問題,比如應用初始化的過程中可以從CDN拉取歷史資料,然後再由其他服務來推送更新資料。
但是,我們想一想能否將這兩種機制組合在一起呢?
透過代理來連線Fastly和Fanout
Fastly是一個邊緣計算平臺(Edge Cloud Platform),它可以使應用在網路的邊緣節點執行和提供服務。 本質上,它提供的是高度可擴充套件的“資料拉取-響應”服務,可以實時監聽和響應使用者的請求。 相比傳統的CDN,Fastly也可以快取靜態內容,同時可以部署和執行應用邏輯。
另一方面,Fanout則是具備高度可擴充套件性的資料推送服務,比如用作高效能的反向代理服務,透過長連結為客戶端實時推送資料。
Fastly和Fanout可以組合使用。它們作為一個整體可以當作源伺服器的反向代理,透過Fastly來代理到Fanout的流量,這樣客戶端就不用直接請求你的源伺服器。這會帶來一些好處:
-
高可用和高可擴充套件性,這點毋庸置疑
-
快取初始資料
-
快取Fanout的指令,這點需要特別說明:Fanout的一些行為是透過指令來配置的。比如傳輸樣式,訂閱的channel等等。通常,這些指令是透過源伺服器的response來獲取(一類特殊的essay-header,被稱為Grip)。Fastly可以在獲取一次response後快取這些指令。
對映網路流
透過組合使用Fanout和Fastly,我們就可以重構這個“推-拉”模型中的網路資料流,下麵我們來仔細看看它們是如何工作的:
假設我們有一個HTTP Endpoint是 /stream,它會傳回一些初始資料,並且在有新資料產生後推送給連線的客戶端。配合Fanout,我們可以讓這個Endpoint傳回帶有instruction的response:(以response essay-header為例)
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 29
Grip-Hold: stream
Grip-Channel: updates
{"data": "current value"}
當Fanout從源伺服器收到這樣的response,會將它轉換成HTTP streaming的response:
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: Transfer-Encoding
{"data": "current value"}
這樣,Fanout到源伺服器的請求就完成了,但是客戶端到Fanout的請求(連線)仍然是open的狀態,用這樣的時序圖來表示:
因為Fanout到源伺服器是短連結的請求/響應樣式,可以透過Fastly來轉換成長連線:
這樣當再有客戶端請求/stream這個endpoint時,源伺服器就完全不會參與進來:
換句話說,Fastly會給Fanout傳回相同的response,帶著特殊的essay-headers已經那些初始資料,Fanout到客戶端則維護streaming連線。
上述過程,我們只解決了“拉”的過程,還需要實現新資料被實時“推送”給Fanout(客戶端)。
清除fastly的快取
當源伺服器的資料改變時我們需要清除掉fastly上的快取來更新它。
還是上文的例子,假如/stream endpoint的資料產生變化,我們就需要清除fastly的快取並同時將新資料廣播給fanout。
下麵這個時序圖描述了一個更複雜的場景,已有的客戶端將被推送新的資料,之後再來一個新客戶端連線:
高效的實現流控
在這種混合架構下,為了提高效率,理想的資料讀寫模型是:
-
資料訪問:每秒若干新的讀
-
資料更新:每分鐘若干寫
-
資料分發:毫秒級投遞
如果你的資料每秒都會產生變化,那最好是不要每次資料變更都清除快取。(容忍一定程度的資料不一致性)
例如在高峰時期,我們可以限制清除的頻率,大部分讀請求還是由快取資料來響應,稍候再更新資料。
Demo
這裡提供了託管在GitHub上的demo應用原始碼,它利用fastly和fanout提供一個live
counter服務。
請求會先到fanout,然後到fastly,最終傳遞到一個由Django實現的backend server。這個服務實現了簡單的計數器邏輯,當計數器的值更新了,fastly的快取會被清除掉,同時再透過fanout發送出去。清除和更新的過程都由流控來限制,以盡可能提高快取的效率。
腦洞一下
我們可以設計一個訊息內容分髮網路,它由完全是地理位置分佈的若干組server構成,可以提供近實時的動態內容和靜態內容分發。
這種新型別的CDN網路可以使得資料處理延伸到網路邊緣,不用管應用本身的源服務位於哪裡。這將為移動應用和IoT應用形態帶來巨大的想象空間。
英文原文:
https://hackernoon.com/powering-your-app-with-a-realtime-messaging-cdn-13d92a6df5f3
相關閱讀:
本文作者Justin Baker,由魏佳翻譯,轉載本文請註明出處,技術原創及架構實踐文章,歡迎透過公眾號選單「聯絡我們」進行投稿。
高可用架構
改變網際網路的構建方式
長按二維碼 關註「高可用架構」公眾號