Netflix 微服務架構設計解析
1 概述
數年來,Netflix 一直是全球體驗最好的在線訂閱制視頻流媒體服務,其流量佔全球互聯網帶寬容量的 15%以上。 在過去的 2019 年,Netflix 已經有 1.67 億名訂閱用戶,平均每個季度新增 500 萬訂戶,服務覆蓋全球 200 多個國家 / 地區。
Netflix 用戶每天在 4000 多部電影和 47000 集電視劇上花費超過 1.65 億小時的時間。從工程角度看,這些統計數據向我們展示了 Netflix 的技術團隊設計出了多麼優秀的視頻流系統,而這套系統具有很高的可用性和可擴展性,能爲全球用戶提供服務。
實際上,Netflix 的技術團隊是花了超過 8 年時間方打造出今天這樣強大的 IT 系統。
實 Netflix 的基礎架構轉型始於 2008 年 8 月,那時這家公司的數據中心遇到了 Web 服務中斷的故障,導致整個 DVD 租賃服務關閉 3 天,損失較大。Netflix 的技術團隊如夢方醒,它需要一個沒有單點故障的更可靠的基礎架構。因此技術團隊管理層做出兩個重要決定,將 IT 基礎架構從自己的 IDC 遷移到公共雲上,通過改造成微服務架構,用較小的易管理軟件組件替換單體程序。
以上這兩個決定爲今天 Netflix 的成功打下了堅實基礎。
Netflix 之所以選擇 AWS 雲來遷移其 IT 基礎架構,是由於 AWS 可以在全球範圍內提供高度可靠的數據庫、大規模雲存儲和衆多數據中心。Netflix 利用了由 AWS 構建和維護的雲基礎架構,從而免去自建數據中心的繁重重複勞動,並將更多精力放在提供高質量視頻流體驗的核心業務上。儘管 Netflix 需要重構整個技術體系,以使其能在 AWS 雲上平穩運行,但作爲回報,系統的可擴展性和服務可用性得到明顯地提高。
Netflix 還是微服務架構背後的首批主要推動者之一。微服務鼓勵關注點分離來解決單體軟件設計存在的問題。在這種架構中,大型程序通過模塊化和獨立的數據封裝被分解爲許多較小的軟件組件。微服務還通過水平擴展和工作負載分區來提升可擴展性。採用微服務後,Netflix 工程師可以輕鬆更改任何服務,從而加快部署速度。更重要的是,他們能跟蹤每個服務的性能水平,並在其出現問題時與其他正在運行的服務快速隔離開來。
2 架構
Netflix 基於亞馬遜雲計算服務(AWS 雲),及公司內部的內容交付網絡:Open Connect 運營。兩套系統必須無縫協作才能在全球範圍內提供高質量的視頻流服務。
從軟件架構的角度來看,Netflix 包括三大部分:客戶端、後端和內容交付網絡(CDN)。
客戶端是用戶筆記本電腦或臺式機上所有受支持的瀏覽器,或者智能手機 / 智能電視上的 Netflix 應用。Netflix 開發了自己的 iOS 和 Android 應用,試圖爲每個客戶端和每臺設備都能提供最佳的觀看體驗。Netflix 可以通過其 SDK 控制自己的應用和其他設備,從而在某些場景下(例如網絡速度緩慢或服務器超載)透明地調整流服務。
後端包括完全在 AWS 雲上運行的服務、數據庫和存儲。後端基本上可以處理不涉及流視頻的所有內容。後端的某些組件及其對應的 AWS 服務列舉如下:
-
可擴展計算實例(AWS EC2)
-
可擴展存儲(AWS S3)
-
業務邏輯微服務(Netflix 專用框架)
-
可擴展的分佈式數據庫(AWS DynamoDB、Cassandra)
-
大數據處理和分析作業(AWS EMR、Hadoop、Spark、Flink、Kafka 和一些 Netflix 專用工具)
-
視頻處理和轉碼(Netflix 專用工具)
Open Connect CDN 是稱爲 Open Connect Appliances(OCAs)的服務器網絡,已針對存儲和流傳輸大尺寸視頻進行了優化。這些 OCA 服務器放置在世界各地的互聯網服務提供商(ISP)和互聯網交換位置(IXP)網絡內。OCA 負責將視頻直接流傳輸到客戶端。
2.1 Playback 架構
當訂閱者單擊應用或設備上的播放按鈕時,客戶端將與 AWS 上的後端和 Netflix CDN 上的 OCA 對話以流傳輸視頻。下圖說明了 playback 流程的工作機制:
用於流視頻的 playback 架構:
-
OCA 不斷將關於其負載狀態、可路由性和可用視頻的運行狀況報告發送到在 AWS EC2 中運行的緩存控制(Cache Control)服務上,以便 Playback 應用向客戶端更新最新的健康 OCA。
-
播放(Play)請求從客戶端設備發送到在 AWS EC2 上運行的 Netflix 播放應用服務,以獲取流視頻的 URL。
-
Playback 應用服務必須確定播放請求是有效的,才能觀看特定視頻。這裏的驗證流程將檢查用戶的訂閱計劃,以及在不同國家 / 地區的視頻許可等。
-
Playback 應用服務會與同在 AWS EC2 中運行的引導(Steering) 服務對話,以獲取所請求視頻的合適的 OCA 服務器列表。引導服務使用客戶端的 IP 地址和 ISP 信息來確定一組最適合該客戶端的 OCA。
-
客戶端從 Playback 應用服務返回的 10 個 OCA 服務器的列表中測試這些 OCA 的網絡連接質量,並選擇最快、最可靠的 OCA 來請求視頻文件,進行流傳輸。
-
選定的 OCA 服務器接受來自客戶端的請求並開始流傳輸視頻。
在上圖中,Playback 應用服務、引導服務和緩存控制服務完全在基於微服務架構的 AWS 雲中運行。在下一節中我將介紹 Netflix 後端微服務架構,該架構可提高當前服務的可用性和可擴展性。
2.2 後端架構
如前所述,後端要處理幾乎所有內容,從註冊、登錄、計費到更復雜的處理任務,如視頻轉碼和個性化推薦等無所不包。爲同時支持在同一底層基礎架構上運行的輕量與重量級負載,Netflix 爲其基於雲的系統選擇了微服務架構。圖 2 展示了 Netflix 可能使用的微服務架構,我從一些在線資源中總結出了這些架構形態:
-
客戶端向在 AWS 上運行的後端發送一個播放請求。該請求由 AWS 負載均衡器(ELB)處理。
-
AWS ELB 會將請求轉發到在 AWS EC2 實例上運行的 API 網關服務上。名爲 Zuul 的組件是由 Netflix 團隊構建的,提供動態路由、流量監控和安全性,以及對雲部署邊緣故障的恢復能力。該請求將應用在與業務邏輯對應的一些預定義過濾器上,然後轉發到應用程序(Application)API 做進一步處理。
-
應用程序 API 組件是 Netflix 運營背後的核心業務邏輯。有幾種類型的 API 對應不同的用戶活動,如註冊 API 和用於檢索視頻推薦的推薦 API 等。在這裏,來自 API 網關服務的轉發請求由播放 API 處理。
-
播放 API 將調用一個或一系列微服務來滿足請求。圖 1 中的播放應用服務、引導服務和緩存控制服務可以視爲微服務。
-
微服務主要是無狀態的小型程序,並且也可以相互調用。爲了控制其級聯故障並獲得彈性, Hystrix 將每個微服務與調用者進程隔離開來。其運行結果可以緩存在基於內存的緩存中,以更快地訪問那些關鍵的低延遲請求。
-
微服務能在流程中保存到數據存儲或從數據存儲中獲取數據。
-
微服務可以將用於跟蹤用戶活動或其他數據的事件發送到流處理管道(Stream Processing Pipeline),以實時處理個性化推薦任務,或批處理業務智能任務。
-
來自流處理管道的數據能持久存儲到其他數據存儲中,如 AWS S3、Hadoop HDFS 和 Cassandra 等。
上述架構可以幫助我們概括瞭解系統的各個部分如何組織和協同工作以流傳輸視頻。但要分析這一架構的可用性和可擴展性,我們需要深入研究每個重要組件,以瞭解其在不同負載下的性能表現。下一節將具體介紹這部分內容。
3 組件
本節會深入研究第 2 節中定義的組件,以分析其可用性和可擴展性。在介紹每個組件時,我還將說明它們是如何滿足這些設計目標的。在後面的章節中將對整個系統進行更深入的設計分析。
3.1 客戶端
Netflix 技術團隊投入了大量精力來開發能在筆記本、臺式機或移動設備上運行得更快、更智能的客戶端應用。即使在某些沒有專用 Netflix 客戶端的智能電視上,Netflix 仍然可以通過自己提供的 SDK 來控制設備的性能表現。實際上,任何設備環境都需要安裝 Netflix Ready Device Platform(NRDP),以實現最佳的觀看體驗。圖 3 展示了一個典型的客戶端結構組件。
-
客戶端應用(Client App)會將自己與後端的連接分爲 2 種類型,分別用於內容發現(Content discovery)和內容播放。客戶端對播放請求使用 NTBA 協議,以確保其 OCA 服務器位置具有更高的安全性,並消除了新連接的 SSL/TLS 握手引起的延遲。
-
在流傳輸視頻時,如果網絡連接過載或出現錯誤,客戶端應用會智能地降低視頻質量或切換到其他 OCA 服務器上。即使連接的 OCA 過載或出現故障,客戶端應用也可以輕鬆切換爲其他 OCA 服務器,以獲得更好的觀看體驗。之所以客戶端能實現所有這些目標,是因爲其上的 Netflix Platform SDK 一直在跟蹤從播放應用服務中檢索到的最新健康 OCA 列表。
3.2 後端
API 網關服務
API 網關服務(API Gateway Service)組件與 AWS 負載均衡器(Load Balancer)通信以解析來自客戶端的所有請求。該組件可以部署到位於不同區域的多個 AWS EC2 實例上,以提高 Netflix 服務的可用性。圖 4 展示了開源的 Zuul,這是 Netflix 團隊創建的 API 網關的實現。
-
入站過濾器(Inbound Filter)可用於身份驗證、路由和裝飾請求。
-
端點過濾器(Endpoint Filter)可用於返回靜態資源或將請求路由到適當的 Origin 或應用程序 API 做進一步處理。
-
出站過濾器(Outbound Filter)可用於跟蹤指標、裝飾對用戶的響應或添加自定義標頭。
-
Zuul 集成了服務發現組件 Eureka ,從而能夠發現新的應用程序 API。
-
Zuul 被廣泛用於各種用途的流量路由任務上,例如啓用新的應用程序 API、負載測試、在負載很大的情況下路由到不同的服務端點上,等等。
應用程序 API
應用程序 API 充當 Netflix 微服務的業務流程層(也稱編排層)。這種 API 提供了一種邏輯,按所需順序組裝對底層微服務的調用,並帶有來自其他數據存儲的額外數據以構造適當的響應。Netflix 團隊花了很多時間設計應用程序 API 組件,因爲它對應 Netflix 的核心業務功能。它還需要在高請求量下具有可擴展和高可用性。當前,應用程序 API 分爲三類:用於非會員請求(例如註冊、下單和免費試用等)的註冊(Signup)API,用於搜索和發現請求的發現(Discovery)API,以及用於流視頻和查看許可請求的播放 API。圖 5 提供了應用程序 API 的詳細結構組件圖。
播放和發現應用程序 API 的分離
-
在播放 API 實現的最新更新中,播放 API 和微服務之間的網絡協議是 gRPC/HTTP2,它 “允許通過協議緩衝區定義 RPC 方法和實體,並自動以多種語言生成客戶端庫 /SDK”。此項更改使應用程序 API 可以通過雙向通信與自動生成的客戶端進行適當集成,並 “儘可能減少跨服務邊界的代碼重用”。
-
應用程序 API 還提供了一種基於 Hystrix 命令的通用彈性機制,以保護其底層微服務。
由於應用程序 API 必須處理大量請求並構造適當的響應,因此其內部處理工作需要高度並行運行。Netflix 團隊發現正確的方法是同步執行和異步 I/O 相結合應用。
應用程序 API 的同步執行和異步 I/O
-
來自 API 網關服務的每個請求都將放入應用程序 API 的網絡事件循環(Network Event Loop)中處理;
-
每個請求將被一個專用的線程處理程序阻止,該處理程序將 Hystrix 命令(如 getCustomerInfo 和 getDeviceInfo 等)放入傳出事件循環(Outgoing Event Loop)中。傳出事件循環是針對每個客戶端設置的,並以非阻塞 I/O 運行。一旦調用的微服務完成或超時,上述專用線程將構造對應的響應。
微服務
按照 Martin Fowler 的定義,“微服務是一組小型服務,每個小服務都在自己的進程中運行,並使用輕量機制通信……”。這些小型程序可以獨立部署或升級,並具有自己的封裝數據。
Netflix 上的微服務組件實現如圖 7 所示。
-
微服務可以獨立工作,也能通過 REST 或 gRPC 調用其他微服務。
-
微服務的實現可以類似於圖 6 中描述的應用程序 API 的實現:請求將被放入網絡事件循環中,而來自其他被調用的微服務的結果將放入異步非阻塞 I/O 中的結果隊列。
-
每個微服務能擁有自己的數據存儲和一些存放近期結果的內存緩存存儲。EVCache 是 Netflix 微服務緩存的主要選擇。
數據存儲
Netflix 將其基礎架構遷移到 AWS 雲時,針對不同的用途使用了不同的數據存儲(圖 8),包括 SQL 和 NoSQL。
-
MySQL 數據庫用於電影標題管理和交易 / 下單目的。
-
Hadoop 用於基於用戶日誌的大數據處理。
-
ElasticSearch 爲 Netflix 應用提供了標題搜索能力。
-
Cassandra 是基於列的分佈式 NoSQL 數據存儲,可處理大量讀取請求,而沒有單點故障。爲了優化大規模寫請求的延遲,Netflix 使用了 Cassandra,因爲它具有最終的一致性能力。
流處理管道
流處理數據管道(Stream Processing Data Pipeline)已成爲 Netflix 業務分析和個性化推薦任務的數據骨幹。它負責實時生成、收集、處理和彙總所有微服務事件,並將其移動到其他數據處理器上。圖 9 展示了該平臺的各個部分。
-
這一流處理平臺每天處理數以萬億計的事件和 PB 級的數據。隨着訂戶數量的增加,它也會自動擴展。
-
路由(Router)模塊支持路由到不同的數據 sink 或應用程序上,而 Kafka 負責路由消息,併爲下游系統提供緩衝。
-
流處理即服務(SPaaS)使數據工程師可以構建和監視他們自定義的可管理流處理應用程序,而平臺將負責可擴展性和運維。
3.3 Open Connect
Open Connect 是一個全球內容交付網絡(CDN),負責存儲 Netflix 電視節目和電影並將其交付給全世界的訂戶。Netflix 爲了讓人們想要觀看的內容儘可能靠近他們想要觀看的位置,而構建和運營了 Open Connect 這一高效率的網絡。爲了將觀看 Netflix 視頻的流量導向到客戶的當地網絡中,Netflix 已與世界各地的互聯網服務提供商(ISP)和互聯網交換點(IX 或 IXP)合作,以在這些合作伙伴的網絡內部部署稱爲 Open Connect Appliances(OCA)的專用設備。
OCA 是經過優化的服務器,用於存儲來自 IX 或 ISP 站點的大型視頻文件,並直接流式傳輸到訂戶的家中。這些服務器會定期向 AWS 上的 Open Connect 控制平面(Control Plane)服務報告自己的運行狀況指標,包括它們從 IXP/ISP 網絡學到的最佳路徑,以及自己的 SSD 上都存儲了哪些視頻等信息。反過來,控制平面服務將根據這些數據中反映的文件可用性、服務器健康狀況以及與客戶端的網絡距離等指標,自動引導客戶端設備到最佳的 OCA 上。
控制平面服務還控制每晚在 OCA 上添加新文件或更新文件的填充(filling)行爲。填充行爲如圖 11 所示。
-
當新的視頻文件已成功轉碼並存儲在 AWS S3 上時,AWS 上的控制平面服務會將這些文件傳輸到 IXP 站點上的 OCA 服務器上。這些 OCA 服務器將應用緩存填充(cache fill),將這些文件傳輸到其子網下 ISP 站點上的 OCA 服務器上。
-
當 OCA 服務器成功存儲視頻文件後,它將能夠啓用對等填充(peer fill),以根據需要將這些文件複製到同一站點內的其他 OCA 服務器上。
-
在可以看到彼此 IP 地址的 2 個不同站點之間,OCA 可以應用層填充(tier fill)流程,而不是常規的緩存填充。
OCA 之間的填充模式
4 設計目標
在前面的章節中,我詳細介紹了爲 Netflix 視頻流業務提供支持的雲架構及其組件。在本節和後續章節中,我想更深入地分析這種設計架構。我會從最重要的設計目標列表開始,如下所示:
-
確保全球範圍內流服務的高可用性。
-
彈性處理網絡故障和系統中斷。
-
在各種網絡條件下,將每臺受支持設備的流傳輸延遲降至最低。
-
支持高請求量的可擴展性。
在下面的小節中,我將分析流服務的可用性及其對應的最佳延遲。第 6 節是關於彈性機制(例如混沌工程)的更深入分析,而第 7 節介紹了流服務的可擴展性。
4.1 高可用性
根據定義,系統的可用性是用一段時間內對請求的響應有多少次來衡量的,但不能保證響應包含了信息的最新版本。在我們的系統設計中,流服務的可用性是由後端服務和保存流視頻文件的 OCA 服務器的可用性共同決定的。
後端服務的目標是通過緩存或某些微服務的執行來獲取最接近特定客戶端的健康 OCA 列表。因此,其可用性取決於涉及播放請求的衆多組件:負載均衡器(AWS ELB)_ 代理服務器(API 網關服務)、播放 API、微服務的執行、緩存存儲(EVCache)和數據存儲(Cassandra):
-
負載均衡器可以將流量路由到不同的代理服務器上以幫助防止負載超載,從而提高可用性。
-
播放 API 通過 Hystrix 命令控制超時微服務的執行,從而防止級聯故障影響其他服務。
-
如果微服務對外部服務或數據存儲的調用所花費的時間超出預期,則它可以使用緩存中的數據響應播放 AI。
-
緩存會被複制以加快訪問速度。
當客戶端從後端接收到 OCA 服務器列表時會在網絡上探測這些 OCA,並選擇最佳的 OCA 進行連接。如果該 OCA 在流處理過程中超載或失敗,則客戶端將切換到另一個狀態良好的 OCA 上,否則 Platform SDK 將請求其他 OCA。因此,其可用性與 ISP 或 IXP 中所有可用 OCA 的可用性高度相關。
Netflix 流服務的高可用性是以複雜的多區域 AWS 運維和服務,以及 OCA 服務器的冗餘爲代價的。
4.2 低延遲
流服務的等待時間主要取決於播放 API 能多快地解析健康的 OCA 列表,以及客戶端與所選 OCA 服務器的連接健康水平。
正如我在應用程序 API 組件部分中所述,播放 API 不會永遠等待微服務的執行,因爲它使用 Hystrix 命令來控制獲取到結果之前要等待的時間,一旦超時就會從緩存獲取非最新數據。這樣做可以將延遲控制在可接受的水平上,還能避免級聯故障影響更多服務。
如果當前選定的 OCA 服務器出現網絡故障或超載,則客戶端將立即切換到其他具有最可靠網絡連接的 OCA 服務器上。如果發現網絡連接質量下降,它也可以降低視頻質量以使其與網絡質量相匹配。
5 權衡
經過認真考慮,在上述系統設計中已經做出了兩個重要的權衡:
-
用一致性換取低延遲
-
用一致性換取高可用性
該系統後端服務的架構設計選擇了用一致性來換取低延遲。播放 API 可以從 EVCache 存儲或最終一致的數據存儲(如 Cassandra)中獲取過時的數據。
類似地,所謂用一致性換取高可用性的權衡是說,系統希望以可接受的延遲發起響應,而不會對像 Cassandra 這樣的數據存儲中的最新數據執行微服務。
在可擴展性和性能之間還存在不完全相關的權衡。在這種權衡下,通過增加實例數量來處理更多負載來提高可擴展性,可能會導致系統達不到預期的性能提升水平。對於那些無法在可用 worker 之間很好地平衡負載的設計架構來說,這可能是個問題。但是,Netflix 通過 AWS 自動擴展解決了這一矛盾。我們將在第 7 節中具體討論這個解決方案。
6 彈性
從遷移到 AWS 雲的那一天起,設計一套能夠從故障或停機中自我恢復的雲系統就一直是 Netflix 的長期目標。該系統已解決的一些常見故障如下:
解析服務依賴項時失敗。
執行微服務時的失敗,導致級聯失敗影響其他服務。
由於過載導致無法連接到某個 API 上。
連接到實例或服務器(如 OCA)時失敗。
爲了檢測並解決這些故障,API 網關服務 Zuul 提供了一些內置功能,如自適應重試和限制對應用程序 API 的併發調用等。反過來說,應用程序 API 使用 Hystrix 命令來使對微服務的調用超時,以停止級聯故障並將故障點與其他服務隔離開來。
Netflix 技術團隊也以其在混沌工程上的實踐而聞名。這個想法是將僞隨機錯誤注入生產環境,並構建解決方案以自動檢測、隔離這類故障,並從中恢復。這些錯誤可能會增加執行微服務的響應的延遲、殺死服務、停止服務器或實例,甚至可能導致整個區域的基礎架構癱瘓。通過有目的地使用檢測和解決此類故障的工具,將現實的生產故障引入受監控的環境,Netflix 可以在這類缺陷造成較大問題之前提早發現它們。
7 可擴展性
在本節中,我將介紹水平擴展、並行執行和數據庫分區這些 Netflix 的流服務可擴展性要素。緩存和負載均衡等要素也有助於提高可擴展性,它們已在第 4 節中提到了。
首先,AWS 自動擴展(Auto Scaling)服務提供了 Netflix 上 EC2 實例的水平擴展能力。當請求量增加時,這個 AWS 服務將自動啓動更多彈性實例,並關閉未使用的實例。更具體地說,在成千上萬個此類實例的基礎上,Netflix 構建了一個開源容器管理平臺 Titus,其每週可運行約 300 萬個容器。同樣,圖 2 架構中的任何組件都可以部署在容器內。此外,Titus 允許容器運行在全球各大洲的多個區域內。
其次,第 3.2.2 節中應用程序 API 或微服務的實現還允許在網絡事件循環和異步傳出事件循環上並行執行任務,從而提高了可擴展性。
最後,寬列存儲(如 Cassandra)和鍵值對象存儲(如 ElasticSearch)還提供了高可用性和高可擴展性,同時沒有單點故障。
8 總結
本文研究描繪了 Netflix 流服務的整體雲架構圖景,另外還從可用性、延遲、可擴展性和對網絡故障或系統中斷的適應性方面分析了相應的設計目標。
總體來說,Netflix 的雲架構已經過了其生產系統的驗證,可以爲在數千個虛擬服務器上運行的數百萬個訂戶提供服務;該架構還通過與 AWS 雲服務的集成在全球範圍內提供了高可用性、最佳延遲、強大的可擴展性以及對網絡故障和系統故障的恢復能力。
本文提到的大多數架構和組件都是通過互聯網上的可信在線資源學習總結出來的。儘管網上沒有太多資源能直接介紹這些微服務的內部實現,以及監視其性能表現的工具和系統,但本文的研究成果可以作爲構建典型生產系統的參考實現。
作者:Cao Duc Nguyen
來源:https://medium.com/swlh/a-design-analysis-of-cloud-based-microservices-architecture-at
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/BkA2AfNlBil_sWjbj8Dlog