經驗說丨華爲雲視頻Cloud Native架構下實踐

摘要:來自華爲雲直播的段亮詳細介紹華爲雲視頻在Cloud Native的轉型實踐中遇到的問題、挑戰以及解決之道。

隨着雲基礎設施服務以及邊緣計算技術的發展,Cloud Native,即雲原生,架構理念和研發也越來越普及。從傳統軟件架構,到雲原生軟件架構的轉變,還需要經歷一段時間才能逐漸走向成熟。今天華爲雲直播的段亮老師從經驗和教訓的角度,詳細介紹華爲雲視頻在Cloud Native的轉型實踐中遇到的問題、挑戰以及解決之道。

主題主要分爲三個部分:前兩個部分回顧關於Cloud Native本身具有哪些的特徵以及架構;第三部分是重點想分享的,即華爲雲視頻業務在探索和實踐Cloud Native的過程當中具體是怎麼做的,以及遇到了哪些問題,希望本次分享能夠對想要或者正在使用雲原生的小夥伴帶來幫助。

一、Cloud Native的前世今生

1. 業界對Cloud Native的描述

先來回顧一下,在2010年,Paul(Paul Fremantle)提出了雲原生的概念,起初只提出了關於彈性、分佈式、多租戶等基本特徵;隨着實踐和發展,Adrian(Adrian Cockcroft,2013)和Matt(Matt Stine,2015)相繼對關鍵特徵進行完善,逐漸提出了反脆弱性、DevOps、持續交付等更新的認識。這就是Cloud Native最初的發展。

從團隊來看,CNCF提出了Cloud Native的特徵和目標,Gartner也同樣做出了重要的規範。

2. 對雲原生的定義和要求

華爲公司早在2016、17年,就開始通過內部發文的方式,統一雲原生定義並規範語言,便於各部分和業務之間對齊語言,包括(微)服務化、彈性伸縮、分佈式等,同時對這些關鍵特徵的定義和範圍,也都做了非常詳細的規範。

3. Cloud Native定義及關鍵特徵

整個雲原生,我們認爲應該分成三大部分。基於康威定律,組織決定其所成就的業務。對實踐雲原生而言,組織的變化最能使我們感同身受,尤其是對每一個人的能力要求發生了非常明顯的變化。例如,對研發人員不再像以前傳統模式下的要求,即實現需求就可以;現在,從前端需求討論,到需求分析,再到開發、參與測試、參與灰度的過程,最後到上線以及線上運行的情況,包括監控、告警等,都需要端到端的關注。所以,對研發團隊人員技能的要求提高了。

今天,重點和大家分享的是關於雲原生的架構和工程方面。各個公司根據不同的業務,都會涉及到這兩個方面,所以更有參考價值。架構方面的核心是微服務架構,其後還有彈性伸縮和分佈式等特徵;工程能力有DevOps、持續交付、灰度上線等。最終的目標是讓雲應用能夠快速高效地部署和規模化,以及實現整個服務的高可用性。這是雲原生的整體概略,下面我將圍繞架構和工程兩個方面和大家展開分享。

二、Cloud Native的基本特徵和架構

1. 微服務架構的定義及優勢

雲原生的架構,最核心的部分是微服務的架構。微服務的首要特徵是高內聚、功能單一,最好的狀態是一個微服務只做一件事情,並且各微服務之間通過進程隔離、獨立代碼庫等,使得每個微服務都可以單獨測試、部署和升級。這樣,單個微服務規模較小,可以做到靈活使用且易於管理。實現微服務化後,整個雲原生的交付和小團隊溝通都能快速進行,因爲微服務之間使用API(應用程序編程接口)通信,沒有了開發語言的限制,小團隊溝通會更簡單、順暢。任何一個功能點或微服務出現問題,其故障影響範圍只存在於本服務器內部,這樣可以提升微服務整體的高可用性,且每個微服務都能單獨演化。

2. 傳統軟件架構與微服務架構對比

既然微服務如此重要,接下來就進一步對比微服務架構和傳統架構。傳統單體架構的軟件是按模塊劃分的,一個複雜的系統可能會劃分幾十個甚至更多的模塊,每個模塊完成一定的功能,模塊之間可能是內部代碼級的接口調用或本地API調用。可以看出,在架構簡單或系統功能單一的情況下,單體軟件在初始階段效率可能更高,因爲整個系統使用一套代碼,在部署和靜態檢查時更容易管理,且內存是共享的,可以調用,時延更低,這是它的好處。如果雲原生下的所有功能點全部通過微服務化的API調用,調用之間就會造成時延。

那麼微服務架構有什麼好處呢?進程隔離,代碼之間徹底解耦,即各微服務可以單獨演化和發展。對比傳統的單體架構,其在設計上肯定想要解耦使模塊功能獨立,但在架構演進的過程中,開發人員難免把控不力,導致耦合越來越不清晰,同時每個模塊的變動都會涉及到其他模塊的升級變更,甚至影響到技術棧發展。一個模塊的重構會對另一個模塊產生影響,導致整個系統的演進變得異常困難。但是,在服務化架構下,以上問題都能迎刃而解。每個服務之間通過API協作完成,更加靈活高效。隨着系統規模的擴大,效率也不會降低,可用性和開發效率等方面也能得到保證。

3. 充分利用雲基礎設施及平臺服務

在充分使用雲基礎設施及平臺服務方面,我們的架構師和設計人員的思路也發生了較大變化。雲原生軟件構建在整個雲的基礎上,雲包括計算資源、網絡資源、存儲資源、消息隊列等,優先使用雲服務上已有的資源,而這些資源通過編排的方式調用,便於實現整個系統的可用性。也就是說,每個服務、每個應用,僅需關注自己需要實現的部分,而不是實現每一個功能。在單體架構下,較常規的情況是:需要某一特性,就找到一個開源的代碼、軟件或模塊拿來使用,這種方式是不可取的。在雲原生下,通過調用其他服務來實現會更聚焦和高效。

4. 彈性伸縮

彈性伸縮也是雲原生的精髓,主要需要解決兩個問題:一是“伸”,二是“縮”。對於視頻業務而言,其規模往往是不可控制的。若主播在直播時產生一個爆點,大量用戶湧入,導致業務量陡增。這時,我們的服務需要能夠自動拓展資源,如果等到業務人員接收到高負荷提醒後,再主動升級變更擴展資源,可能會來不及。以上是彈性伸縮中“伸”的部分,而“縮”的必要性主要基於成本。我們知道,視頻每天都會有一個高峯期,比如,教育類的視頻服務會在早上上課的時間達到高峯期,而遊戲類的直播視頻在晚上8點到10點是高峯期。高峯期相對於低峯期,其業務規模相差十倍甚至百倍以上,若資源不會自動開放,在空閒期間就會造成資源浪費。“縮”就可把資源釋放出來,提供給其他服務使用。

5. 分佈式

分佈式是雲原生的一個核心理念,主要用於提高可用性。分佈式分爲三個部分:其一,應用分佈式,分佈在多AZ(可用區)和多Region(區域)上。如果出現一個故障,不至於影響到其他方面。例如,一個城市的電力系統故障,或者某條光纖被挖斷了,也不至於影響到整體服務的可用性。其二,數據分佈式。各城市之間,重要的數據需要做到跨Region和跨AZ的同步部署和存儲。其三,跨可用區的部署以及整體的調度。用我們今天的分享舉例,整個媒體處理分佈在各個不同的Region上,假設某個城市的光纖出了問題,也不會影響整個直播的過程和質量。這就是分佈式帶來的好處。

6. 高可用

在雲原生下,可用性和傳統模式有着本質的區別,在設計思路上就全然不同,雲原生是基於不可靠、可拋棄的資源設計反脆弱性的系統。舉例說明:在沙漠上建一座牢固的大樓,應該怎麼建?我們不能因爲沙地不穩固,在其上建造出的樓也不穩定。雲原生的系統設計,並沒有假設系統下的資源是穩定的,實際上所有資源都可能出故障。那麼,系統的反脆弱性具體應該怎麼設計?這纔是我們雲原生設計的精髓之一。

7. 認可失敗的設計

在傳統方式上,我們總是在安全、可用等方面下大功夫,希望把系統中的bug和故障全部清除掉,不留任何隱患,這種思路是沒有錯的。但是,隨着雲上系統規模越來越大,雲服務越來越多,想要清除所有的bug幾乎是不可能完成的任務。在設計上,我們應該承認失效是時常發生的。同時,需要考慮的是,如何在系統或者某個功能失效的前提下,業務還能正常運行。如,在某一微服務出現故障之後,如何快速發現並自我隔離,從而消除其對整個系統的影響;甚至,在整個可用區和核心服務出現故障時,怎樣對服務進行降級,而不是任由整個服務癱瘓。比如,系統中有10個業務,現在出現一個故障,導致3個業務不可用,那麼另外7個業務是否能繼續服務?這是在雲原生下設計系統的一個核心理念。

8. 自動化運維——基於數據分析的全方位故障監控

目前,雲原生下的微服務數量較多,大部分情況下,如果系統規模中等,微服務數量是幾十上百甚至更多,若採用人工運維的方式幾乎是不可能的。因爲每個微服務的運行狀態都是非常複雜的,且各服務之間也會產生各種複雜的關係。若僅從最上層的客戶黃金指標來判斷系統的運行狀況,那最終出現問題時,事態可能已經很嚴重了。所以從開發、部署、升級、問題定位等各方面來看,自動化運維都是雲原生下非常重要的一環。

9. 灰度發佈

灰度發佈也是整個雲原生核心的一部分。我們的系統一直處於開發當中,如果沒有灰度發佈,如何變更一直在開發中的系統?打個比方,一架飛機在高空飛行,不能等飛機落地之後再更換髮動機。同理,如果我是一名客戶,想讓系統停下再去變更,也是不可能執行的。那麼,如何在變更的同時保證所有的業務可用,並且保證系統能夠穩步向前發展,這其中有着非常大的挑戰。灰度發佈是目前應用較廣泛的方式,其他還有滾動發佈、藍綠髮布等方式,其中藍綠髮佈會造成資源浪費。灰度發佈是目前常用的一種方式,通過灰度升級,逐漸擴大灰度範圍,從而保證整個服務的可用性,中途若出現問題則快速回滾。

三、華爲雲視頻Cloud Native實踐

下面和大家分享我們的雲視頻業務在實踐雲原生的過程中的一些經驗和教訓。

1. Cloud Native架構能力

華爲雲不但統一了雲原生的定義和語言,同時還對多個雲原生項目進行了總結,包括內部的架構設計指南,即雲原生的架構具體應該如何設計,其中還包括一些優秀案例。對於不同的場景和模式,我們構建了架構模式庫,在設計過程中,可以直接參考模式庫,方便高效、高質地完成架構設計。對整個雲原生,我們也進行了全面、規範的體系建設,各服務間的Console、風格,包括如何鑑權、AKI網關如何對接、接口風格等,都有統一的規範。最後一點很關鍵,針對各業務的雲原生研發成熟度,在工具中設立雲原生架構評價標準,提供數值打分。這樣,包括雲視頻在內的每一個業務,都可以衡量其當前狀態與理想狀態之間的差距,並且知曉待改進的方面在哪裏。

雲原生是一系列雲上經驗的總結,在實施過程中,沒有把所有經驗全都實踐一遍的必要,只需引用業務所需的實踐即可。重要的是經驗的價值。

2. 架構-微服務架構

我們對微服務架構也做了總結,從服務發現、服務註冊、到服務劃分和部署等,各模式都有統一的要求。包括可用性、自動化運維等等,在這裏就不詳細展開了。

我們對比一下左右兩張圖。左圖是業務剛剛構建之初的微服務架構,當時對雲原生的瞭解並未深入,業務邏輯相對比較簡單。大概一年之後,我們發現以前的業務架構出現了問題。第一,開發效率越來越低,由於一個服務的開發經常會涉及到其他服務,並且需要頻繁變更,導致一個需求需要很長時間的開發才能上線,客戶響應時間明顯變低;第二,測試越來越困難,架構出現腐化,代碼出現壞味道。基於多種方式判斷,我們認爲需要重構架構。現在看向右圖,將之前的VodManager微服務拆分爲4、5個服務,每一個服務的功能邏輯都是相對獨立的,一個需求的開發只會落到一、兩個服務裏,測試變得簡單,開發也更加高效。我認爲,微服務劃分是動態的,沒有一個理想的架構和劃分方法,只有一些指導的原則,這些原則就是我們之前所講到的,這裏就不贅述了。需要根據任務場景、以及系統業務複雜度、用戶數量和具體要求等方面統一看待,有問題就進行重構,沒有問題就儘可能簡單化。這是我們在微服務架構重構方面的一些實踐。

再強調一點,這裏的微服務架構並不能一次性變更到位,而是一個逐漸演進的過程。可能本週拆分出一個微服務,下週又拆分出一個微服務;並不能提前限定時間進行拆分,然後一次性上線。我認爲原因主要是基於質量上的考慮,如果突然重構全部架構,可能會涉及幾十甚至更多代碼同時上線,質量是很難保證的。每次變更一個微服務,就會有一個灰度過程,從而保護客戶服務的可用性。目前,整個雲視頻業務,我們的服務個數大概有2百個,人均一個或一個多一點的規模,都有對外API接口,接口數量約2千個。並不是說越多越好,以上內容僅給大家做一個參考。

3. RTC用戶接入微服務容器化實踐

我們認爲在雲服務上必須要做容器化,因爲各微服務之間是相互獨立的,而且應該設計爲無狀態,隨時可以被銷燬。上圖是我們實時性視頻的一個微服務,目前已經商用了,其中一個案例可以和大家分享一下。所有微服務全部容器化,因爲任何一個實例都可以被銷燬,如果出現變更或是業務量上升,隨意拉起一個微服務,其他微服務仍能正常工作。在這裏重述一點,進行對外服務的微服務,我們建議首先通過域名調度,不要通過IP,因爲可能會有多Region的情況。大家都明白,如果一個Region出了問題,域名還能解析到另一個Region上去。對於對外呈現解析的IP,首先它應該是一個EIP,且需要有主備,不能是單一的IP。因爲EIP可以對應後面多個IP地址,可以保證任何一個IP或者主機出了問題,都不會都整體服務產生影響。這是對對外服務微服務的一個考慮。

另外,所有微服務之間都不能直接調用,都應該通過服務網格的方式調用。目前華爲雲上比較成熟的是CSE,該方式經過了大規模的考驗。比較新的方式有Istio,這兩年逐漸開始使用,服務線數量增加較快。我們的整個雲視頻板塊Docker(容器)的數量最高峯的時候達到了好幾千個。

4. 使用容器化的收益

這裏通過我們自己遇到的一些情況,特別講解一下容器化的好處。最開始我們並沒有採用容器化的方式,後來發現通過容器化,資源利用率明顯下降,因爲彈性伸縮做的比較容易;另一點是快速啓停,我們現在用容器基本可以達到秒級重啓,如果需要就可以秒級彈出、秒級部署,而且各個服務之間的遷移、依賴關係、解耦、服務打包等各方面操作都很迅速。我們現在代碼的升級、變更、流水線等等都是和容器化綁定的。以上是我們關於容器化的實踐。

5. 實時轉碼服務的彈性伸縮實踐

剛剛也提到,彈性伸縮在雲原生裏是很重要的一部分,因爲它切實影響到可用性和成本。視頻中的彈性伸縮主要考慮什麼問題呢?首先,"彈",我認爲是沒有問題的,上面的配置圖隱去了數據。使用起來很簡單,根據事件驅動,如內存、網絡、業務量等,當達到某一特定值時,相應地彈出多少個實例,彈出速度非常快,基本可達到秒級彈出。所以,“彈”的方面是沒有問題的。但是,對於視頻業務而言,“縮”也非常重要。

那麼,“縮”具體會遇到什麼問題呢?視頻包括直播、會議、RTC等業務,對實時性的要求非常高。比如,在某一個實例上,有1000個用戶同時在觀看,其中有800個已經下線,只有200個佔用了一個實例,此時應該怎麼辦呢?我們的做法有兩種,一種方式是,在新業務的調度上,基於部分指定的容器優先預調這些業務,尤其在業務規模的下降期,根據業務的情況,可能要留出半小時到一小時不等的時間進行收縮。對於實在很小的業務,怎樣把直播遷移到另一個容器當中去,而且對用戶的觀看體驗沒有任何影響。這纔是彈性伸縮實踐中,雲視頻業務做到“縮”的時候很重要的一點。

左下角的圖展示的是24小時內高峯期和低峯期的資源利用率。本來,高峯期和低峯期的峯值有10倍甚至百倍之差,但CPU資源的利用率還算平穩,並未出現大起大落。這就是彈性伸縮所需要做到的一個能力。

6. 雲視頻統一OPS平臺

雲服務上沒有OPS,相當於人沒有眼睛。操作每一塊業務,可視化每一項服務,出了問題之後快速定位,OPS都是核心能力。業務監控、配置、調用鏈、日誌規模分析等都能在OPS裏很好地體現。這一部分與業務相關性較強,所以只展示了雲視頻能力,包括故障的定位定界、運營、管理、配置等都是必須的。

7. 雲視頻監控運維繫統架構

OPS平臺依賴大量的數據,尤其是日誌的數據,因爲問題的定位定界、故障,告警等,全部分析都依賴於這些數據。在雲服務下,整個運維的架構非常重要。對於雲視頻板塊,我向大家展示一下我們的過程,供各位借鑑。

針對數據採集上報,需要考慮本地冗餘,不能直接上報,在失敗之後就丟掉。而且考慮成本,並不會預留很大的數據通道供使用,所以本地需要有緩存能力,以及上報失敗後重覆上報的能力。對於數據接入,我們採用Kafka對數據進行二次匯聚,因爲原始數據過大,對其分析、存儲、查詢等規模上都無法滿足。目前,每天的日誌量可達數百T,而且不能長久存儲。我認爲,運維架構可以不斷演進。我們的運維架構起初設計出來時,比現在的要簡單很多,而上圖的架構是我們研究至今的情況。大家在構建日誌系統或運維繫統時,需要着重考慮以下兩點:1、日誌上報實時性。日誌如同神經表現,快速獲得日誌,就能快速瞭解系統中存在的問題並解決。實時性是一個挑戰,當然這也和成本掛鉤。2、日誌實時數據。包括數據的匯聚、分析、展示。

8. 工程能力-服務自治

前面提到在微服務架構下,會存在很多個擁有單獨代碼庫的微服務,其相對單體軟件而言更加獨立,但隨之而來的問題是——管理。每一個微服務都需要人工部署,而且頻度很高,幾乎不可能實現。所以工程能力的工具化、自動化,且能夠實現服務自治是雲原生中非常重要的一部分,需要在最初時就開始構建。從開發人員寫完代碼到上線,需要經歷哪些步驟?從第一幅圖中可以看到,包括開發代碼、靜態檢查、合規掃描、Alpha測試、Gamma測試、自動部署、灰度發佈、在線測試等。雖然,開發一個功能可能只需要30-50行代碼,但一套流程全靠人工幾乎是不可能完成的。但是,在工具化之後,只需在本地開放代碼並測試後一鍵提交,整個過程只在部署環節需要人工確認,其他步驟可以全部通過工具化自動完成,從而實現一人運維多個微服務。目前,我們的團隊每月大約有500多次變更,一年達數千次變更。按照業務發展,並且視頻領域更加活躍,包括RTC等業務場景,明年的變更次數一定會更多,所以服務自治非常重要。

9. 功能能力-灰度發佈

灰度發佈也是雲服務核心的一部分,服務上線、開發過程質量的基本保障,目前主要使用灰度發佈。灰度方式可基於流量、內容、域名、特性等,與開發特性相關,在腳本里便捷地更改後就實現快速發佈。每種發佈都有驗證,驗證可以是自動的撥測用例、人工撥測,還能與客戶共同測試。

10. 架構-分佈式&高可用

前面所講內容,除了提升效率和降低成本之外,最核心的一點是雲服務的可用性。雲服務可用性是對客戶的服務承諾,出了問題,不僅是賠款,更嚴重的是影響品牌信譽。那麼如何做到可用性?總結如下:基於認可失敗的理念設計,能夠對失敗的業務進行降級;同時對於底層資源做到多AZ,這樣一個城市的機房出問題時,不會影響整體服務,多Region相互容災,最後實現整體的可用性。但是可用性只能做到儘可能高,不能做到百分之百,整個過程還需要大家共同探索。上圖展示了一個比較嚴重的事件:某個Region區底層的所有資源幾乎都不可用了,圖中紅線顯示的是我們的業務,幾乎沒有受到任何影響。在保證業務不受影響的前提下提高服務可用性,應該是我們共同的願望。

本文分享自華爲雲社區《Cloud Native雲視頻實踐》,原文作者:音視頻大管家。

 

點擊關注,第一時間瞭解華爲雲新鮮技術~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章