當前位置:
首頁 > 科技 > 今日頭條架構演進之路,高壓下的架構演進專題

今日頭條架構演進之路,高壓下的架構演進專題

架構壓力主要來源

從架構的角度,技術團隊應對的壓力最主要來自三方面:

服務穩定性。介面的穩定性,讓服務更可靠;

迭代速度。迭代速度對於大公司來講相對沒那麼重要,規模比較大,生存壓力相對小一點,但相對中型小型公司來講,迭代速度是必須要保證的,時間窗也是一個決定能否成功的重要因素;

服務質量。主要關注用戶滿意度,它也是一個特別重要的 topic。

今日頭條發展特別快,只有 4 年的歷史,從人員數量和規模增長來看非常快,在穩定性可用性方面壓力比較大,一方面需要快速把業務實現,但在另外一方面,類似這些高可用的問題會經常騷擾工程師:上線就掛、運營活動量大服務崩潰、單機性能頂不住、一個小服務上線把核心服務搞掛了……類似這些問題,技術團隊需要如何更好的去應對?

先補充下我對架構演進的理解,在不同階段的公司都會面臨各種壓力。小公司壓力可能是業務沒起來,QPS 很低,要做優化也沒有環境及條件;當公司大了,伺服器可能已經不是問題,但你要不斷考慮調優及應對訪問壓力,改善基礎設施以提供更穩定的開發環境。所以說架構演進是持續一個過程,沒有終點。

為什麼今日頭條有這麼大的壓力?今日頭條增長速度是比較快的,從上圖可以看出,現在公司已有 4 年,2014 到 2016 年每年都是 DAU 翻番。這對業務挑戰是非常大,規模上來以後,我們原有的架構難以做到線性擴展,部分能線性擴展的服務,問題也比較多,業務增長太快,後端壓力比較大。

頭條架構發展簡史:三個歷史階段

今日頭條的架構是怎麼發展過來的?

從來沒有一個完美的架構能夠一直支撐下去,架構是動態系統、實時變化的,因為量變而發生質的變化,不同的階段需要不同的架構

什麼時候需要做架構上的改造呢?當突然發現系統問題越來越多,經常出現事故或者報警特別多,溝通的效率降低等問題,很有可能你的架構出現問題了。

軟體架構有一個問題,它改動的周期相對比較長。架構的模式思路定下來,隨著業務的增長,包袱越來越大。做過基礎設施的人都有這樣的體驗:有一個好的想法很容易,但做一個好用軟體就有很多的困難。技術改造是漫長的,以年為單位。所以這個時候只能讓架構迭代更快一點。最後,不要企圖做特別完美的架構,我們只要保持敏捷演進就好了。

架構不可避免會劣化。

頭條第一階段:三層結構

今日頭條剛開始做的時候,就是一個簡單 Web 應用,搭個資料庫,把業務實現就行了。頭條最開始的優勢是推薦引擎,還有另外一套數據挖掘和離線計算。在線的服務在前端相對來講模式還是比較清晰的,三層就搞定了。業務剛開始起來的時候,沒什麼問題,訪問增大水平擴展一下就可以解決。

頭條第二階段:拆分

跟大部分公司的架構演進歷史非常相似,當上個版本遇到一些性能問題後,最簡單就做一些拆分。優化的過程中,那一塊太重了就從代碼上進行拆分。上圖中,A、B 和 C 是不同的業務,剛開始代碼是一起的,演進的過程中,迭代一年或者兩年的產品,異構去拆其實挺痛苦。

前面時代的架構,基本上沒考慮太多的人員或者規模上的發展,剛開始也沒有專門的人做架構優化,很多人都撲在業務上,把功能點加上。比如推薦的效果不好,就加強推薦,每塊都沒有專門的的人去考慮整體架構去怎麼組織規劃。

到了去年,每個季度做的預算,到第二個月機器都用完了。高峰的時候有 60% 到 70% 的壓力,這裡涉及有兩個問題:第一個問題,有些地方是性能衰減的問題;另外一個,業務壓力太大。

架構團隊需要想辦法變得更快,即使出現訪問問題,壓力大,機器不夠,也要讓我們的服務有所保證。業務一直在快速前進,包袱是比較沉重,改造的成本比較高。基於這些問題,談下我們下一階段的思路,做微服務。

頭條第三階段:微服務

目前我們的思路是通過微服務方式做新架構。通過拆分成子系統,大的應用拆成小應用,抽象通用層做代碼復用。

系統的分層比較典型。我們重點在基礎設施,希望通過基礎設施提高快速迭代、容災和一系列的工作,希望各個業務團隊能更快做業務上的迭代以及架構上的調整。

微服務架構

微服務我們認為最關鍵的三點

解耦,一個服務會依賴另外一個服務、模塊或子服務的概念。

輕量,減輕維護人員的成本。

易管理。

現實中微服務的關鍵是自治。雖然微服務是自治自包含,但也需要有一個層級。比如你提供的服務是外面公司提供的,微博提供的服務,你不能夠要求微博為你得服務去做更改。微服務要有界限,在公司層面,不能讓它過於獨立,過於獨立會增加溝通上的成本。基礎設施和規範最好能復用。

現實中的微服務是什麼樣的?

架構必須要落地成具象的東西。微服務有一個開發框架,做業務的同學根本不需要關心容災,也不需要重複做這樣一套東西,這個東西怎麼部署,他們也不用關心;

需要有一個流程規範性去約束。有規範就可以做全局優化;

微服務的表現形式是提供一個平台或者一些工具。

頭條服務化的現在及未來

最後再給大家介紹前面服務化的思路在今日頭條是怎麼執行的?怎麼給各個業務團隊開發者提供服務?

頭條的主要服務化思路如下

立規範。規範怎麼做?部署 RPC,一個服務調另外一個服務是怎麼做的?創新我覺得沒有問題,但你得考慮給其他人帶來成本,這個規範還是需要有的,這樣可以做全局控制。服務化的穩定和統一,你要考慮它帶來真正的優勢,性能高是一個點,但是本地優先會好一些;

打基礎。有了規範以後,開始真正落地的服務。比如說基礎庫,把Ngnix、Redis、MySQL這些庫封裝起來,統一起來做一些事情。開發框架,你不用關注數據去優化;

漸進。先拆離再迭代,把服務優化進來;

一切都是服務,第四點是和其他公司或團隊稍不一樣的地方,我們的想法是一切都是服務,每個節點都是抽象歸屬於某一個具體的服務。存儲的確是一個服務,但它不只是提供 API 或者提供功能的東西,還需要包括服務質量,需要別人用起來是比較簡單的;

平台化。最後的落地是平台化的東西。我們框架是怎麼設計,和服務怎麼結合?

首要規範:一切都是服務

資源是有限的:按需申請,需申請和授權;

簡單的使用方式:開發者只需要關注業務;

有唯一定位的方式:用全局資源定位;

最後,每個服務都有擁有者(owner),偏工程架構方面的東西,我的規範必須可執行的。

我們的規範

必須要有全局的中心,服務統一註冊到 consul 中;

服務有唯一的標示、命名范:.. P.S.M,公司有很多部門,我們不希望部門之間溝通起來有差異,所以需要有全局規划去追溯它;

業務服務使用 Thrift 描述介面、必須傳遞標準參數。如果用弱的描述數據,沒有強約束,在客戶端的數據可能會出現類型錯誤;

RPC 使用統一收斂的庫;

Nginx、Redis、MC、MySQL、etc 都是服務

服務註冊

我們服務統一使用 loader 或 wrapper 腳本啟動,具體啟動由業務決定。

服務啟動會有一個名字,把 app 註冊到服務裡面,看起來有一些約束,資料庫MySQL 可以啟動嗎?Redis 可以嗎?

啟動的時候,服務方式不用去管,就用同一個框架,一個新的規範,容易把已有的服務遷移上來,但這不是個特彆強的規範,考慮遷移成本。輕規範,易遷移。

服務中心

服務中心有服務信息,會同時帶上是什麼樣的服務,其他人比較簡單的調這個服務就 OK 了。這個服務到底提供什麼樣的服務質量,擁有者可以管理這個信息。Redis去服務,負載均衡,服務一個項目,把服務接上去。

服務關係與授權

服務之間有個關鍵的概念:服務授權。一般我們起一個服務,通過 IP 就可以連上它了。資料庫有用戶名認證,也可以對 IP 授權。不過內網很多服務限制比較少,不是所有服務都有授權認證。我們希望把服務之間的關聯關係,全局拓撲關係記錄下來並且可執行。

一個服務提供介面,我們可以由 owner 來做授權,其他服務授權後才可以訪問它。

描述信息:這個服務是什麼樣子?最大的 QPS 是多少?通過描述信息發現問題,用戶信息服務托不住了,就拒了,把資源分到其它服務上面,就可以做更多的東西。還有機房信息可以放在這裡面。

服務授權認證思路:

基於服務標示,重要服務增加更多認證方式;

協同認證,客戶端自身協助認證。

舉一個 Thrift 的例子。這兩邊有兩個虛線,服務中心水平擴展能力很強,向它要基本授權的信息,我可不可以調這個服務?默認是可以,就是一個 Thrift 包,我知道你是誰,自己做策略,服務包帶過來。請求帶上來,分析調用是不是有問題,這也是規範的一部分。開發的同學是不用關心框架這邊如何做的。

另外一種向服務中心調用服務,把你拒了。QPS 壓力大,已經支持不了你。一個好處是可以避免浪費資源;另外,虛擬化 Docker 的環節。以前的思路按 IP 授權,每一個 IP 做控制,提供類似於匿名服務,根據節點所屬 IP 去做。現在用 Docker 拿一個標識不太好做,在網路層也不太好做,在內網環境下有一定的可信,我自覺告訴你,我是誰,然後調用。

MySQL 目前正在做的一個方案見下圖,不像 Redis 要求帶上你是誰,調用 MySQL 需要把調用方是誰帶上來。一個重要資料庫,肯定做安全授權,我剛只是說常規情況下。這幾種方式疊加起來做,把原信息帶過來,Redis 帶過來,做加權校驗。

Redis 在協議層做不了,而 MySQL 在調用中增加上述信息不會影響語義。我們伺服器提供 HTTP 介面就可以在 HTTP 頭提供這個信息做授權認證。

有授權關係,所有的服務構成完整服務的拓撲關係。一個服務預先授權才能調它。如果有線上真實的拓撲關係,就可以做報警優化。Redis 報警了,MySQL 報警了,有這樣的拓撲,會提升問題追查的速度。

我們有了這樣的拓撲信息,知道服務的全局元信息,我們就可以更好的做服務變更的影響評估和報警等等的優化。

RPC 開發框架

我們自己開發了一個 RPC 框架。開發框架會幫助我們開發代碼,這個事情很多人都在做。它的主要特性包括:

快速開發:代碼生成;

服務發現:理解服務化;

可觀測性(Observability):logid, pprof, admin 埠;

容災降級:業務降級開關;

過載保護:斷路器,頻率控制;

多語言支持:Python/Go

比如可觀測性是說所有的服務都能暴露內部的狀態,這有非常好的優勢,服務上來以後,默認剖析內部的埠或者服務埠,服務上線與平台。根據拓撲關係自動分析出來服務狀態,甚至做性能剖析,開發者可以不用關心這些事情,天然獲得這些能力。

還有容災降級,還有過載保護,我們還有一個平台管理關聯關係和降級,你可以更多關注業務。

下面是大概模塊的示意圖,通過模塊化的方式,而不是嵌入到框架裡面,使我們的維護成本更低。

前面服務是自治的體現,跟 Docker 比較像,我們也會做容器化的開發。只是把服務跑在容器內還遠遠不夠,把服務化體系打通,我們思路實現開放,實現我們「有態度」的私有雲,把基礎設施這一塊讓我們平台做,業務部門只關心業務。

我們目前到這個環節,做一個服務的重構,我們的私有雲構建。前面的框架,

不斷去迭代。

最後我們和虛擬化 PaaS 平台怎麼規劃?

我們通過三層實現,通過 PaaS 平台統一管理。提供通用 SaaS 服務,同時提供通用的 App 執行引擎。最底層是 IaaS 層。

IaaS 管理所有的機器,把公有雲整合起來,頭條有一些熱點事件會全國推廣推送,對網路帶寬比較高,我們藉助公有雲,需要哪一種類型計算資源,統一抽象起來。基礎設施結合服務化的思路,比如日誌,監控等等功能,業務不需要關注細節就可以享受到基礎設施提供的能力。

Q&A

轉自:高可用架構

微服務

從已放棄到再入門

極客時間推出熱門微服務課程,幫你從0開始構建微服務知識體系。微服務不再是大企業的奢侈品,而是每個企業的必需品。

微博技術專家帶你深入微服務技術,跨越從程序員到架構師的分水嶺。幫助學習者循序漸進的掌握微服務知識。限時優惠分享返現

溫馨提示:

求知若渴, 虛心若愚


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 架構師技術聯盟 的精彩文章:

DDN欲完成「連連購」,你看好Lustre還是Tintri?
針對靜默數據錯誤,如何採用DIX和DIF保證數據一致性?

TAG:架構師技術聯盟 |