淘寶雙11促銷背後採用什麼架構技術來實現網站的負載均衡

時間真快,一晃眼,今年的雙十一又快要到了,下面我就結合淘寶目前的一些底層技術框架以及本身的一些感觸來講說如何構建一個可伸縮,高性能,高可用性的分佈式互聯網應用。

 

一 應用無狀態(淘寶session框架)web

俗話說,一個系 統的伸縮性的好壞取決於應用的狀態如何管理。爲何這麼說呢?我們試想一下,假如咱們在session中保存了大量與客戶端的狀態信 息的話,那麼當保存狀態信息的server宕機的時候,咱們怎麼辦?一般來講,咱們都是經過集羣來解決這個問題,而一般所說的集羣,不只有負載均衡,更重要的是要有失效恢復failover,好比tomcat採 用的集羣節點廣播複製,Jboss採 用的配對複製等session狀 態複製策略,可是集羣中的狀態恢復也有其缺點,那就是嚴重影響了系統的伸縮性,系統不能經過增長更多的機器來達到良好的水平伸縮,由於集羣節點間session的 通訊會隨着節點的增多而開銷增大,所以要想作到應用自己的伸縮性,咱們須要保證應用的無狀態性,這樣集羣中的各個節點來講都是相同的,從而是的系統更好的水平伸縮。數據庫

OK,上面說了無狀態的重要性,那麼具體如何實現無狀態呢?此時一個session框架就會發揮做用了。幸運的是淘 寶已經具備了此類框架。淘寶的session框架採用的是client cookie實現,主要將狀態保存到了cookie裏 面,這樣就使得應用節點自己不須要保存任何狀態信息,這樣在系統用戶變多的時候,就能夠經過增長更多的應用節點來達到水平擴展的目的.但 是採用客戶端cookie的 方式來保存狀態也會遇到限制,好比每一個cookie通常不能超過4K的大小,同時不少瀏覽器都限制一個站點最多保存20個cookie.淘 寶cookie框 架採用的是「多值cookie」, 就是一個組合鍵對應多個cookie的 值,這樣不只能夠防止cookie數 量超過20, 同時還節省了cookie存 儲有效信息的空間,由於默認每一個cookie都會有大約50個字節的元信息來描述cookie。apache

除了淘寶目前的session框 架的實現方式之外,其實集中式session管理來完成,說具體點就是多個無狀態的應用節點鏈接一個session 服 務器,session服 務器將session保 存到緩存中,session服 務器後端再配有底層持久性數據源,好比數據庫,文件系統等等。後端

二 有效使用緩存(Tair)瀏覽器

作互聯網應用的兄弟應該都清楚,緩存對於一個互聯網應用是多麼的重要,從瀏覽器緩存,反向代理緩存,頁面緩存,局部頁面緩存,對象緩存等等都是緩存應用的場景。緩存

一 般來講緩存根據與應用程序的遠近程度不一樣能夠分爲:local cache 和 remote cache。通常系統中要麼採用local cache,要麼採用remote cache,二者混合使用的話對於local cache和remote cache的數據一致性處理會變 大比較麻煩.tomcat

在大部分狀況下,我 們所說到的緩存都是讀緩存,緩存還有另一個類型:寫緩存. 對 於一些讀寫比不高,同時對數據安全性需求不高的數據,咱們能夠將其緩存起來從而減小對底層數據庫的訪問,好比 統計商品的訪問次數,統 計API的 調用量等等,可 以採用先寫內存緩存而後延遲持久化到數據庫,這樣能夠大大減小對數據庫的寫壓力。安全

OK,我以店鋪線的系統爲例,在用戶瀏覽店鋪的時候,好比店鋪介紹,店鋪交流區頁面,店鋪服務條款頁面,店鋪試衣間頁面,以及店鋪內搜索界面這些界面更新不是很是頻繁,所以適合放到緩存中,這樣能夠大大減低DB的負載。另外寶貝詳情頁面相對也更新比較 少,所以也適合放到緩存中來減低DB負載。cookie

三 應用拆分(HSF)網絡

首先,在說明應用拆分以前,咱們先來回顧一下一個系統從小變大的過程當中遇到的一些問題,經過這些問題咱們會發現拆分對於構建一個大型系統是如何的重要。

系統剛上線初期,用戶數並很少,全部的邏輯也許都是放在一個系統中的,全部邏輯跑到一個進程或者一個應用當中,這個時候由於比較用戶少,系統訪問量低,所以將所有的邏輯都放在一個應用何嘗不可。

可是,兄弟們都清楚,好景不長,隨着系統用戶的不斷增長,系統的訪問壓力愈來愈多,同時隨着系統發展,爲了知足用戶 的需求,原有的系統須要增長新的功能進來,系統變得愈來愈複雜的時候,咱們會發現系統變得愈來愈難維護,難擴展,同時系統伸縮性和可用性也會受到影響。

那麼這個時候咱們如何解決這些問題呢?明智的辦法就是拆分(這也算是一種解耦),咱們須要將原來的系統根據必定的標準,好比業務相關性等分爲不一樣的子系統, 不一樣的系統負責不一樣的功能,這樣切分之後,咱們能夠對單獨的子系統進行擴展和維護,從而提升系統的擴展性和可維護性,同時咱們系統的水平伸縮性scale out大 大的提高了,由於咱們能夠有針對性的對壓力大的子系統進行水平擴展而不會影響到其它的子系統,而不會像拆分之前,每次系統壓力變大的時候,咱們都須要對整個大系統進行伸縮,而這樣的成本是比較大的,另外通過切分,子系統與子系統之間的耦合減低了,當某個子系統暫時不可用的時候,總體系統仍是可用的,從而整 體系統的可用性也大大加強了。

所以一個大型的互聯網應用,確定是要通過拆分,由於只有拆分了,系統的擴展性,維護性,伸縮性,可用性纔會變的更好。可是拆分也給系統帶來了問題,就是子系統之間如何通訊的問題,而具體的通訊方式有哪些呢?通常有同步通訊和異步通訊,這裏咱們首先來講下同步通訊,下面的主題「消息系 統」會說到異步通訊。既然須要通訊,這個時候一個高性能的遠程調用框架就顯得很是總要啦,所以我們淘寶也有了本身的HSF框 架。

上 面所說的都是拆分的好處,可是拆分之後必然的也會帶來新的問題,除了剛纔說的子系統通訊問題外,最值得關注的問題就是系統之間的依賴關係,由於系統多了,系統的依賴關係就會變得複雜,此時就須要更好的去關注拆分標準,好比可否將一些有依賴的系統進行垂直化,使得這些系統的功能儘可能的垂直,這也是目前淘寶正 在作的系統垂直化,同時必定要注意系統之間的循環依賴,若是出現循環依賴必定要當心,由於這可能致使系統連鎖啓動失敗。

四 數據庫拆分(TDDL)

在前面「應用拆分」主題中,咱們提到了一個大型互聯網應用須要進行良好的拆分,而那裏咱們僅僅說了」應用級別」的拆 分,其實咱們的互聯網應用除了應用級別的拆分之外,還有另一個很重要的層面就是存儲如何拆分的。所以這個主題主要涉及到如何對存儲系統,一般就是所說的RDBMS進 行拆分。

好了,肯定了這個小節的主題以後,咱們回顧一下,一個互聯網應用從小變大的過程當中遇到的一些問題,經過遇到的問題來引出咱們拆分RDBMS的 重要性。

系 統剛開始的時候,由於系統剛上線,用戶很少,那個時候,全部的數據都放在了同一個數據庫中,這個時候由於用戶少壓力小,一個數據庫徹底能夠應付的了,可是隨着運營那些哥們辛苦的吶喊和拼命的推廣之後,忽然有一天發現,oh,god,用戶數量忽然變多了起來,隨之而 來的就是數據庫這哥們受不了,它終於在某一天你們都和愜意的時候掛掉啦。此時,我們搞技術的哥們,就去看看到底是啥緣由,咱們查了查之後,發現原來是數據庫讀取壓力太大了,此時我們都清楚是到了讀寫分離的時候,這個時候咱們會配置一個server爲master節 點,而後配幾個salve節 點,這樣以來經過讀寫分離,使得讀取數據的壓力分攤到了不一樣的salve節點上面,系統終於又恢復了正常,開始正常運行了。

可是好景仍是不長,有一天咱們發現master這哥們撐不住了,它負載老高了,汗 流浹背,隨時都有翹掉的風險,這個時候就須要我們垂直分區啦(也就是所謂的分庫),好比將商品信息,用戶信息,交易信息分別存儲到不一樣的數據庫中,同時還能夠針對商品信息的庫採用master,salve模式,OK, 經過分庫之後,各個按照功能拆分的數據庫寫壓力被分擔到了不一樣的server上面,這樣數據庫的壓力終於有恢復到正常狀態。

可是是否是這樣,咱們就能夠高枕無憂了呢?NO,這個NO, 不是我說的,是前輩們經過經驗總結出來的,隨着用戶量的不斷增長,你會發現系統中的某些表會變的異常龐大,好比好友關係表,店鋪的參數配置表等,這個時候不管是寫入仍是讀取這些表的數據,對數據庫來講都是一個很耗費精力的事情,所以此時就須要咱們進行「水平分區」了(這就是俗話說的分表,或者說sharding).

OK,上 面說了一大堆,無非就是告訴你們一個事實「數據庫是系統中最不容易scale out的一層」,一個大型的互聯網 應用必然會通過一個從單一DB server,到Master/salve(主/從),再到垂直分區(分庫),而後再到水平分區(分表,sharding)的過程,而在這個過程當中,Master/salve 以 及垂直分區相對比較容易,對應用的影響也不是很大,可是分表會引發一些棘手的問題,好比不能跨越多個分區join查 詢數據,如何平衡各個shards的 負載等等,這個時候就須要一個通用的DAL框架來屏蔽底層數據存儲對應用邏輯的影響,使得底層數據的訪問對應用透明化。

拿淘寶目前的狀況來講,淘寶目前也正在從昂貴的高端存儲(小型機+ORACLE)切換到MYSQL,切 換到MYSQL以 後,勢必會遇到垂直分區(分庫)以及水平分區(Sharding)的問題,所以目前淘寶根據自 己的業務特色也開發了本身的TDDL框架,此框架主要解決了分庫分表對應用的透明化以及異構數據庫之間的數據複製。

五 異步通訊(Notify)

在」遠 程調用框架」的 介紹中,我 們說了一個大型的系統爲了擴展性和伸縮性方面的需求,確定是要進行拆分,可是 拆分了之後,子 系統之間如何通訊就成了咱們首要的問題,在」遠程調用框架」小節 中,我 們說了同步通訊在一個大型分佈式系統中的應用,那麼這一小節咱們就來講說異步通訊.好了,既 然說到了異步通訊,那 麼」消 息中間件」就 要登場了,採 用異步通訊這其實也是關係到系統的伸縮性,以及最大化的對各個子系統進行解耦.

說 到異步通訊,咱們須要關注的一點是這裏的異步必定是根據業務特色來的,必定是針對業務的異步,一般適合異步的場合是一些鬆耦合的通訊場合,而對於自己業務上關聯度比較大的業務系統之間,咱們仍是要採用同步通訊比較靠譜。

OK,那 麼下一步咱們說說異步能給系統帶來什麼樣子的好處。首先咱們想一想,假如系統有A和B兩個 子系統構成,假如A和B是 同步通訊的話,那麼要想使得系統總體伸縮性提升必須同時對A和B進行 伸縮,這就影響了對整個系統進行scale out.其次,同步調用還會影響到可用性,從數學推理的角度來講,A同 步調用B, 若是A可 用,那麼B可 用,逆否命題就是若是B不 可用,那麼A也 不可用,這將大大影響到系統可用性,再次,系統之間異步通訊之後能夠大大提升系統的響應時間,使得每一個請求的響應時間變短,從而提升用戶體驗,所以異步在提升了系統的伸縮性以及可用性的同時,也大大的加強了請求的響應時間(固然了,請求的整體處理時間也許不會變少)。

下面咱們就以淘寶的業務來看看異步在淘寶的具體應用。交易系統會與不少其它的業務系統交互,若是在一次交易過程當中採用同步調用的話,這就要求要向交易成功,必須依賴的全部系統均可用,而若是採用異步通訊之後,交易系 統藉助於消息中間件Notify和 其它的系統進行了解耦,這樣以來當其它的系統不可用的時候,也不會影響到某此交易,從而提升了系統的可用性。

最後,關於異步方面的討論,我能夠 推薦你們一些資源:

1 . J2EE meets web2.0

2. Ebay架構特色(HPTS 2009)

六 非結構化數據存儲 ( TFS,NOSQL)

在 一個大型的互聯網應用當中,咱們會發現並非全部的數據都是結構化的,好比一些配置文件,一個用戶對應的動態,以及一次交易的快照等信息,這些信息通常不適合保存到RDBMS中, 它們更符合一種Key-value的 結構,另外還有一類數據,數據量很是的大,可是實時性要求不高,此時這些數據也須要經過另外的一種存儲方式進行存儲,另一些靜態文件,好比各個商品的圖片,商品描述等信息,這些信息由於比較大,放入RDBMS會引發讀取性能問題,從而影響到其它 的數據讀取性能,所以這些信息也須要和其它信息分開存儲,而通常的互聯網應用系統都會選擇把這些信息保存到分佈式文件系統中,所以淘寶目前也開發了本身的分佈式文件系統TFS,TFS目 前限制了文件大小爲2M, 適合於一些小於2M數 據的存放。

隨 着互聯網的發展,業界從08年 下半年開始逐漸流行了一個概念就是NOSQL。咱們都知道根據CAP理論,一致性,可用性和分區容錯性3者 不能同時知足,最多隻能同時知足兩個,咱們傳統的關係數據採用了ACID的事務策略,而ACID的 事務策略更加講究的是一種高一致性而下降了可用性的需求,可是互聯網應用每每對可用性的要求要略高於一致性的需求。

這個時候咱們就須要避免採用數據的ACID事 務策略,轉而採用BASE事 務策略,BASE事 務策略是基本可用性,事務軟狀態以及最終一致性的縮寫,經過BASE事務策略,咱們能夠經過最終一致性來提高系統的可用性。

這也是目前不少NOSQL產品所採用的策略,包括facebook 的cassandra,apache hbase,google bigtable等,這些產品很是適合一些非結構化的數據,好比key-value形 式的數據存儲,而且這些產品有個很好的優勢就是水平伸縮性。目前淘寶也在研究和使用一些成熟的NOSQL產品。

七 監控、預警系統

對於大型的系統 來講,惟一可靠的就是系統的各個部分是不可靠。

因 爲一個大型的分佈式系統中勢必會涉及到各類各樣的設備,好比網絡交換機,普通PC機,各類型號的網卡,硬盤,內存等等,而這些東東都在數量很是多的時候,出現錯誤的機率也會變大,所以咱們須要時時刻刻監控系統的狀態,而監控也有粒度的粗細之分,粒度粗一點的話,咱們須要對整個 應用系統進行監控,好比目前的系統網絡流量是多少,內存利用率是多少,IO,CPU的 負載是多少,服務的訪問壓力是多少,服務的響應時間是多少等這一系列的監控,而細粒度一點的話,咱們就需對好比應用中的某個功能,某個URL的 訪問量是多,每一個頁面的PV是 多少,頁面天天佔用的帶寬是多少,頁面渲染時間是多少,靜態資源好比圖片天天佔用的帶寬是多少等等進行進一步細粒度的監控。所以一個監控系統就變得必不可少了。

前 面說了一個監控系統的重要性,有了監控系統之後,更重要的是要和預警系統結合起來,好比當某個頁面訪問量增多的時候,系統能自動預警,某臺Server的CPU和 內存佔用率忽然變大的時候,系統也能自動預警,當併發請求丟失嚴重的時候,系統也能自動預警等等,這樣以來經過監控系統和預警系統的結合可使得咱們能快速響應系統出現的問題,提升系統的穩定性和可用性。

八 配置統一管理

一個大型的分佈 式應用,通常都是有不少節點構成的,若是每次一個新的節點加入都要更改其它節點的配置,或者每次刪除一個節點也要更改配置的話,這樣不只不利於系統的維護和管理,同時也更加容易引入錯誤。另外不少時候集羣中的不少系統的配置都是同樣的,若是不進行統一的配置管理,就須要再全部的系統上維護一份配置,這樣會 形成配置的管理維護很麻煩,而經過一個統一的配置管理可使得這些問題獲得很好的解決,當有新的節點加入或者刪除的時候,配置管理系統能夠通知各個節點更新配置,從而達到全部節點的配置一致性,這樣既方便也不會出錯。

感謝你看完個人長篇大論,若是你以爲這篇文章對你有幫助的話,能夠幫我點個推薦。

或者也能夠關注個人公衆號【Java技術zhai】,不按期的技術乾貨內容分享,帶你從新定義架構的魅力!

相關文章
相關標籤/搜索