中午吃飯刷着刷着微博發現微博忽然掛了。我一開始覺得是家裏網很差,後來換了流量刷仍是刷不出內容,而且報error,我就知道微博應該是掛了。往朋友圈一看,原來是鹿晗和關曉彤微博互圈「宣佈戀情」了。要不是之前看過《好先生》這部劇沒準我還真不認識關曉彤。陸地cp前幾天不是還在炒着嗎?怎麼這麼忽然?誒..貴圈賊亂啊。程序員
做爲一名程序員,我更感興趣的是微博如何應對瞬時涌來的高併發大流量。從好久好久之前文章馬伊琍的「週一見」,到後來「出軌隊」、「吸毒隊」的爭相奪分,再到前段時間的郭敬明事件、薛之謙事件,再到今天的鹿晗宣佈戀情......微博看似每次都在掛,一直都沒有進步,你們每次遇到熱點事件刷不出內容的時候都會吐槽微博的應用平臺很辣雞。可是呢,微博的後臺系統確定一直在重構升級優化,我以爲可以作到今天這種水平已經很不錯了。算法
從用戶的角度(主要是個人角度hhhhh)來看數據庫
遇到熱點事件的時候微博大機率在短期內(大約10~15)可能會徹底刷不出內容,過了一段時間以後(大約半小時)進行間隔刷新(間隔10秒左右),有可能某些時候會看到5xx的error,5開頭的http狀態碼錶明服務器或者是網關存在問題,好比說服務器拒絕鏈接、網關超時或者是應用代碼存在bug等都會致使5xx的錯誤。在熱點事件發生1小時內,系統應該能夠恢復正常的服務。緩存
從網站開發、運維人員的角度來看服務器
- 運維:臥槽?怎麼訪問流量這麼高?是出啥bug了嗎?臥槽!不會是又有人出軌吸毒了吧?emmmm....個人國慶假期可還沒結束啊!
- 運維:兄弟們,快醒醒!快加機器啊!系統要崩了!
- 開發:別催!再催自殺!
- leader:測試在擴容以後趕忙拉出來測測!
- 測試:人在家中躺,鍋從天上來!
上面都是我亂說的!cookie
爲何我以爲微博在高併發大流量訪問方面的表現已經很不錯了呢?舉個例子吧:淘寶每一年在雙11購物節的時候也要應對高併發的場景,可是這是能夠提早作不少準備的,好比說提早購買帶寬資源、增長服務器資源、進行完備的異地容災等等,不少都是可預測的。而微博呢?熱點事件隨時均可能發生,因此這對於微博的運維工程師來講是很大的考驗。固然,如今的運維平臺也是很是的智能了,能夠對各項指標進行實時監控,一有異常,立刻進行短信或者郵件報警,以後就是各個崗位的工程師人肉上場調配各種資源了。網絡
那微博在平時爲何不增長一些服務器資源呢?session
服務器資源、網絡帶寬資源等既重要,又昂貴。因爲並非每時每刻都必須應對高併發的場景,所以若是說在平時增長了冗餘的服務器資源致使大量機器空載,也是一種很大的浪費。咱們在考慮提供可用服務的同時,也必須考慮一下成本。架構
原本我開始寫這篇博客的時候就是想回顧一下本身之前學習過的大型網站高可用架構相關知識。可是因爲高性能、伸縮性、拓展性與高可用性密不可分,因此我寫着寫着就感受寫不下去了。想寫的東西太多了,有點不知道從哪裏開始寫。因此下面我就針對高可用性架構中常常會提到的幾個點來說講。併發
不論是對於小型網站仍是大型網站來講,分層都是必須的:粗粒度的分層通常爲應用層、業務層和數據層。橫向分層以後,可能還會根據模塊的不一樣對每一層進行縱向的分割。拿微博舉例,我以爲它的評論模塊和點贊模塊應該是解耦的。越是複雜的系統,橫向和縱向的分層分割粒度就會越細。不少時候你用起來覺得它就是一個系統,其實後面多是由幾百上千個獨立部署的系統對外提供服務。
集羣在大型網站架構中是一個很是很是重要的概念。因爲服務器(不論是應用服務器仍是數據服務器)容易發生單點問題,一旦一臺服務器gg了,就必須進行失效轉移。
通常來講,應用服務器必須是無狀態的。什麼叫無狀態服務器呢?在介紹它以前,咱們先來講一下狀態服務器:狀態服務器通常會保存請求相關的信息,每一個請求會默認地使用之前的請求信息。這樣就很容易致使會話粘滯問題:若是一臺狀態服務器宕機了,那麼它保存的請求信息(例如session)就丟失了,可能會致使不可預知的問題。
那麼相對的,無狀態服務器就不保存請求信息,它處理的客戶信息必須由請求本身攜帶,或者是從其餘服務器集羣獲取。所以無狀態服務器相對於狀態服務器來講更加地健壯,就算是重啓服務器甚至是服務器宕機都不會丟失狀態。由此引伸出來的另外一個優勢就是方便擴容:只要在增長的服務器上部署相同的應用並作好反向代理就能對外提供正常的服務。
既然應用服務器是無狀態的,那麼用戶的登陸信息(session)如何管理呢?比較常見的有下面四種方式。可是因爲前三種都有很大的侷限性,這裏只聊聊基於集羣的session服務器管理方式。
咱們在這裏是將服務器的狀態進行分離:分爲無狀態的應用服務器和有狀態的session服務器。固然,這裏說的session服務器確定說的是session服務器集羣。咱們能夠藉助分佈式緩存或者是關係型數據庫來存儲session。對於微博來講,這裏確定得用分佈式緩存了:由於用關係型數據庫的話數據庫鏈接資源容易成爲瓶頸,而且I/O操做也很耗時間。比較常見的K-V內存數據庫有Redis。我以爲微博內容中的贊數、用戶的關注數和粉絲數用Redis來存應該算是比較合適的。
既然提到了集羣,確定得說說負載均衡。可是感受負載均衡應該能夠歸類到可伸縮性裏面去,因此這裏就不詳細講啦,就簡單說說有哪些常見的負載均衡的方式以及負載均衡算法。
忽然想到一個比較有意思的東西:在微博的架構中,應該採用的是異步拉模型而不是同步推模型。什麼意思呢?咱們舉個例子:鹿晗的粉絲有3000多萬,關曉彤的粉絲有1000多萬。假如他倆發了條微博的同時須要往這4000萬粉絲的內容列表中(假設這裏用的是關係型數據庫)推送過去,這就是簡化的同步推模型。
那這樣有什麼缺點呢?首先,這樣會消耗大量的數據庫鏈接資源,更重要的是這樣不太符合軟件設計規範:由於對於兩人的粉絲來講,分別由有3000多萬和1000多萬的數據是冗餘的。假如說陳赫、鄧超在第一時間對他倆的微博進行了點贊,此時瓶頸就來了:剛纔往數據庫裏插入4000多萬感受還能夠接受,可是如今四人的粉絲數加起來好幾億了,同時往數據庫插這麼多數據是否是感受不太合適?
不要緊,咱們如今換一種內容推送方式:咱們如今不用同步推了,而是用異步拉。咱們每次在手機上刷微博的時候,若是想要看到更新的內容是否是都要下拉刷新獲取?沒錯這就是異步拉。異步拉有什麼好處呢?很明顯的一個好處就是能夠將熱點數據進行集中管理,而且不用進行大量的數據插入冗餘操做。另外對系統資源的消耗也較少。那麼微博內容從哪裏拉呢?主流的解決方案是把熱點內容放到緩存中,每次都去查緩存,這樣能夠減小I/O操做而且避免發生因資源枯竭形成的超時問題。
PS:寫到這裏的時候我開始水羣了,如今回過頭來繼續寫感受無法兒寫下去了。過久沒寫博客了,不少知識略有遺忘。不過今天算是在腦海中把相關的東西梳理了一下,由於畢業設計也打算作高併發大流量相關的東西。今天算是蹭蹭熱點順便複習一下之前學過的知識吧~
其實高可用性架構還包括服務升級、服務降級、數據備份、失效轉移等等。關於網站高可用、高性能、高拓展方面感受其實還有不少不少東西來寫。可是有些知識沒有必定的實踐經驗呢,又不能很好的掌握。那麼就等我後面再慢慢聊吧~
最後,打個廣告:以前一直在簡書上寫技術博客,可是慢慢地感受簡書雜七雜八的內容太多了,一點也不純粹。打算之後休閒娛樂的東西就放到簡書上寫吧,技術博客慢慢會轉移到掘金的陣地上來了。關注簡書做者-EakonZhao