微博春晚背后的技術故事

jopen 10年前發布 | 12K 次閱讀 微博

前言

  一年一度的春晚再次落下帷幕,而微博也順利地陪伴大家度過除夕之夜。

  談及馬年春晚,人們首先想到的不是春晚上精彩的節目,而是微博上的吐槽,邊看春晚,邊刷微博,邊吐槽,已經成了國人的習慣。看春晚不再是為了看節目,而是為了能夠在微博上吐槽,知道大家在吐槽什么,更有人戲稱不是春晚成就了微博,而是微博拯救了春晚。

  馬年春晚又格外引人注目,不僅僅是因為馮小剛親自坐鎮,擔當總導演,更值得一提的是本屆春晚首次將社交平臺作為其與觀眾互動的主要途徑,而新浪 微博更是成為官方二維碼獨家合作方。在節目播出時,用戶通用手機客戶端,掃描屏幕右下角的官方二維碼,即可參與春晚的話題討論。不僅如此,參與討論的觀 眾,還可以免費獲得微博紅包,抽大獎的機會。如此一來,大大的提升了微博的活躍度瞬間提升,同時在線人數翻了幾倍,給微博系統帶來前所未有的訪問壓力。

  根據以往統計的數據,春晚期間微博的訪問量將激增到日常水平的數倍之多,而瞬時發表量更是飆升數十倍,如此場景絲毫不亞于淘寶雙 11 和 12306 搶票時的”盛況”。

  而最后的統計數據結果表明,馬年春晚直播期間,微博的訪問量和發表量都再創新高,而我們系統也自始至終平穩運行,經受住了此次高峰的考驗。這成功的背后,是我們的工程師將近一個月的努力。其間面臨了哪些問題,又是如何解決的呢?下面,我們一一為大家揭秘。

  挑戰1:如何應對數倍于日常訪問量的壓力?

  每年春運搶票時,12306 都會崩潰;淘寶雙 11 時,也會有短暫的購買失敗的情況。究其原因還是,有限的服務器資源難以承受上千萬人同時在線訪問。同樣,春晚的時候,微博的訪問量也會激增,同時在線人數 到達日常的數倍之多。面對突然增長的訪問壓力,大部分互聯網公司都會臨時擴容來加以應對,同樣我們也需要進行擴容。那么如何進行擴容?哪些部分需要擴容? 具體擴容多少?這都是厄需解決的問題。

  需要提到一點的是,微博目前線上部署了幾千臺服務器,來保障日常的正常訪問。假如面對原來數倍的訪問壓力時,如果簡單粗暴通過線性擴容來應對的 話,需要部署原來數倍的服務器,也就是需要上萬臺服務器。無論從硬件成本還是從管理成本上,這都是不可接受的。那么,又該如何做呢?

  在線壓測,找極限,最小化擴容前端機

  眾所周知,為了盡可能的保障線上運行的服務器的穩定,資源都是有一定冗余度的,一般安全值在 30% 以上。在面臨 5 倍的訪問量時,出于成本的考慮,單純的擴容難以令人接受。這個時候,就要充分利用每臺服務器,在不影響業務性能的前提下,使每臺服務器的利用率發揮到極 限,可以極大的降低資源擴容的數量。如何評估服務器的承受極限是其中的關鍵,為此我們在業務低峰時期,對線上的服務器進行了實際的壓測。具體方法如下:

  假如線上一個服務池里有 300 臺 tomcat 服務器在提供 API 服務,正常情況下,每臺服務器的負載都小于1(為了簡化模型,我們這里只提到了系統 load 這個指標,實際情況要比這個復雜的多,還要考慮 CPU 利用率、帶寬、io 延遲等)。通過運維系統,我們以 10%、20%、30%、40%、50% 等比例逐步將該服務池里的 300 臺 tomcat 機器 503,通過觀察一臺 tomcat 服務器的負載以及 API 服務的接口性能,當服務器的負載達到極限或者 API 服務的接口性能達到閾值時,假設此時服務池里正常狀態的 tomcat 服務器的數量是 100 臺,那么我們就可以推斷出該服務池,極限情況下可以承受 3 倍與日常的訪問壓力。同理,為了承擔 5 倍的訪問量,只需再擴容一倍機器即可。

  挑戰2:如何應對瞬時可達幾萬/s 的發表量?

  互聯網應用有個顯著特點,就是讀多寫少。針對讀多有很多成熟的解決方案,比如可以通過 cache 來緩存熱數據來降低數據庫的壓力等方式來解決。而對于寫多的情況,由于數據庫本身寫入性能瓶頸,相對較難解決。

  微博系統在處理發表微博時,采用了異步消息隊列。具體來講,就是用戶發表微博時,不是直接去更新數據庫和緩存,而是先寫入到 mcq 消息隊列中。再通過隊列機處理程序讀取消息隊列中的消息,再寫入到數據庫和緩存中。那么,如何保證消息隊列的讀寫性能,以及如何保證隊列機處理程序的性 能,是系統的關鍵所在。

  按消息大小設置雙重隊列,保證寫入速度。

  眾所知之,微博最大長度不超過 140 個字,而大部分用戶實際發表的微博長度都比較小。為了提高寫入消息隊列的速度,我們針對不同長度的微博消息,寫入不同大小的消息隊列。比如以 512 字節為分界線,大于 512 字節的寫入長隊列,小于 512 字節的寫入短隊列,其中短隊列的單機寫入性能要遠遠高于長隊列。實際在線結果表明,短隊列的 QPS 在萬/s 級別,長隊列的 QPS 在千/s 級別,而 99% 的微博消息長度均小于 512 字節。這種優化,大大提高了微博消息的寫入和讀取性能。

  堵塞隊列,壓隊列機極限處理能力。

  為了驗證隊列機處理程序的極限處理能力,我們在業務低峰時期,對線上隊列機進行了實際的壓測,具體方法如下:

  通過開關控制,使隊列機處理程序停止讀取消息,從而堵塞消息隊列,使堆積的消息分別達到 10 萬,20 萬,30 萬,60 萬,100 萬,然后再打開開關,使隊列機重新開始處理消息,整個過程類似于大壩蓄水,然后開閘泄洪,可想而知,瞬間涌來的消息對隊列機將產生極大的壓力。通過分析日 志,來查找隊列機處理程序最慢的地方,也就是瓶頸所在。

  通過兩次實際的壓測模擬,出乎意料的是,我們發現系統在極限壓力下,首先達到瓶頸的并非是數據庫寫入,而是緩存更新。因此,為了提高極限壓力下,隊列機處理程序的吞吐量,我們對一部分緩存更新進行了優化。

  挑戰3:如何保證系統的可靠性?

  無論是發微博,還是刷 feed,在微博系統內的處理過程都十分復雜,依賴著各種內部資源和外部服務,保證系統的可靠性顯得尤為困難。

  為此,我們內部開發了代號為試金石——TouchStone 的壓測系統,對系統的可靠性進行全面檢測。

  首先,我們對微博的各個接口進行了服務依賴和資源依賴的梳理,并針對每個服務和資源定義了相應的 SLA 和降級開關。然后,模擬資源或者服務出現異常,再來查看其對接口性能的影響。以 redis 資源為例, 假設系統定義了 redis 的 SLA 是 300ms,相應的端口是 6379,通過 TouchStone,使該端口不可用,從而模擬 redis 資源出現異常,然后驗證依賴該資源的接口的性能,確保 SLA 。同時,通過降級開關,對該資源進行降級,驗證降級開關的有效。

  基于以上方法,對系統進行了全面的檢測,并對各個服務和資源的 SLA 和降級開關進行梳理,總結成業務降級手冊,保證在出現問題時,運維人員無需開發的介入,也能第一時間根據降級手冊進行降級,確保問題能夠盡快解決。

  挑戰4:如何保證核心系統的穩定性?

  任何一個系統,都包含核心系統和非核心系統。在出現異常的情況下,棄車保帥,只保障核心系統的穩定性也是可以接受的。

  為此,我們降核心接口和非核心接口拆分,部分部署到不同的應用池子當中,確保非核心業務不會影響核心業務。比如發微博和刷 feed 屬于核心業務,而評論,贊屬于非核心業務,所以兩者應當部署到不同的應用池中。在評論或者贊出現異常時,發微博和刷 feed 就不會受到影響,從而保障系統核心業務的穩定性。

  同樣,對于一個業務,也要區分核心邏輯和非核心邏輯。以發微博為例,更新緩存和寫數據庫屬于核心邏輯,而給其它業務部門推送數據則屬于非核心邏輯。因此,可以將推送數據進行異步化處理,交給單獨的線程池處理,在出現異常時,不會對更新緩存和寫數據庫造成影響。

  挑戰5:如何做到異地容災?

  近些年來,異地容災成為全球性互聯網企業面臨的難題之一。無論是在國內,以微信為例,還是在國外,以 推ter 為例,都曾經出現過全球性宕機的事故。由此可見,異地容災仍舊是一個挑戰。

  微博早在 2010 年就開始了多機房的部署,如今已經具備三大機房(分別針對聯通、電信和海外用戶)。

  由于人為或者天氣等不可抗拒因素,網絡故障近年來時有發生。微博的三個機房,各自獨立承擔了一部分用戶的訪問。在一個機房出現故障或者壓力過大 的時候,通過 DNS 切換等手段,將流量遷移到另外兩個機房,從而確保該訪問該機房的用戶不受影響。一個現實的情況例子,在馬年春晚直播期間,由于觀看人群的地域分布的特點, 出現了聯通機房的訪問量突增,同時在線人數的增長超過了電信機房和廣州機房,我們通過切換一部分聯通機房的流量到電信機房,使得聯通機房的負載降到了安全 值的范圍。

  挑戰6:如何實時監控系統狀態?

  我們都知道,地震的發生都是有前兆的,比如一些動物的異常反應。同樣,系統中的任何問題出現之前,也是有線索可尋的。這就需要對系統的關鍵指標做實時的監控,當指標出現異常時,能夠第一時間發出報警信息。

  為此,我們基于實時流處理系統 Storm 開發了一套監控系統——dashboard。有別于以往的監控系統,它能實時處理系統產生的海量日志,繪制出更加直觀的曲線,方便運維進行管理。通過 dashborad,我們能夠了解系統的實時狀態,主要包括 feed 的訪問量、微博的發表量、隊列機的處理性能,消息隊列的堆積量等指標。當某個監控指標出現異常時,能夠第一時間在 dashboard 中反映出來,從而第一時間采取措施,解決問題,避免問題擴大化。

  后記

  春晚已經過去一個月了,漸漸成為回憶。但春晚背后,我們的工程師所付出的巨大的努力所產生的價值,卻是一筆寶貴的財富,希望這篇文章能給大家帶來啟發甚至幫助,也在此向為微博春晚默默貢獻的工程師們致敬!

  關于作者

  胡忠想(微博昵稱:@古月中心相心),目前任職于新浪微 博的平臺研發部門,主要負責微博 Feed 服務相關工作,曾先后參與微博 Feed 存儲、微博計數器、微博閱讀數等重大業務產品的開發。2012 年 3 月份畢業于北京航空航天大學計算系,同年 4 月份,加入新浪微博并工作至今。業余愛好戶外,曾徒步過貢嘎、雨崩,攀登過四姑娘三峰。

來自: InfoQ
                    <span id="shareA4" class="fl">                          </span>
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!