架構之道:3個程式設計師成就微信朋友圈日均10億釋出量

IT技術精選文摘發表於2018-05-12

640?wx_fmt=jpeg

前言


截止到2015年7月,微信每月活躍使用者約5.49億,朋友圈每天的發表量(包括贊和評論)超過10億,瀏覽量超過100億。得益於4G網路的發展,以上資料仍有很快的增長,而且相對於PC網際網路時代,移動網際網路時代的峰值要來得更加凶猛。比如,2015年元月的流量到了平時的2倍,而峰值則達到了平時峰值的2倍,相當於平時正常流量的5倍,這對整個系統的考驗是很殘酷的。本次分享將簡單介紹微信後臺團隊的開發模式、微信朋友圈的架構以及在效能上的一些工作,供各位參考。

基本介紹

640?wx_fmt=png

伺服器的配置基本都是普通的伺服器,最好的伺服器也就是64G記憶體,這部分佔比不多,大部分是32G記憶體,也有很少一部分8G記憶體的。硬碟是SSD和SATA都有。CPU以16核居多,有一部分新機器是32核。至於頻寬則是比較多的,對外頻寬很大。

架構概述


整個微信是微服務的架構,每一個請求後面可能會涉及到幾百個服務,每一個服務都有一個QoS,目的是對一些重要的服務進行保證。比如除夕晚上流量達到平時的5倍,這時整個系統的效能肯定不夠,所以要優先保證什麼呢?優先保證支付,優先保證紅包的體驗。紅包體驗保證了,再保證訊息,比如點對點兩人之間的訊息。這兩個保證的前提下,再保證群聊。如果群聊也能保證,再保證朋友圈。效能不夠時將優先順序低的服務暫時停掉,這個過程是不需要人工干預的。

640?wx_fmt=png

然後到邏輯層。邏輯層包括註冊、訊息、群聊、朋友圈等等,還有iOS系統的通知。iOS系統跟安卓不一樣在於,一個iOS App進入後臺之後只有大概15秒的存活期,所以iOS上的推送通知要用API的Push完成,不在接入層做。

再往下走就是儲存代理層,這一層主要負責一些關鍵資料的維護操作,比如使用者在賬號裡面的動作操作和事故資訊。儲存代理層下面對接KV儲存,這個KV儲存是不負責業務邏輯的,只是單純的Key-Value對映,以及負載均衡和容錯。(有關KV儲存系統的詳細說明,可以參考微信架構師許家滔在QCon北京2014上的演講“微信後臺儲存架構”。)

涉及朋友圈資料的有四個核心的表:

640?wx_fmt=png

上面提到過,微信現在每天的釋出有10億多,瀏覽量超過100億,對效能的要求很高,所以上面的儲存都是做成可以水平擴充套件的。對於水平擴充套件的實現,下面舉例說明。

應用原理

640?wx_fmt=png

在釋出的表寫完之後,會把這個K2的釋出索引到小王的相簿表裡。所以相簿表其實是很小的,裡面只有索引指標。相簿表寫好了之後,會觸發一個批處理的動作。這個動作就是去跟小王的每個好友說,小王有一個新的釋出,請把這個釋出插入到每個好友的時間線裡面去。

然後比如說現在Mary上朋友圈了,而Mary是小王的一個好友。Mary拉自己的時間線的時候,時間線會告訴到有一個新的釋出K2,然後Mary的微信客戶端就會去根據K2的後設資料去獲取圖片在CDN上的URL,把圖片拉到本地。

在這個過程中,釋出是很重的,因為一方面要寫一個自己的資料副本,然後還要把這個副本的指標插到所有好友的時間線裡面去。如果一個使用者有幾百個好友的話,這個過程會比較慢一些。這是一個單資料副本寫擴散的過程。但是相對應的,讀取就很簡單了,每一個使用者只需要讀取自己的時間線表,就這一個動作就行,而不需要去遍歷所有好友的相簿表。

為什麼選擇這樣一個寫擴散的模型?因為讀是有很多失敗的。一個使用者如果要去讀兩百個好友的相簿表,極端情況下可能要去兩百個伺服器上去問,這個失敗的可能性是很大的。但是寫失敗了就沒關係,因為寫是可以等待的,寫失敗了就重新去拷貝,直到插入成功為止。所以這樣一個模型可以很大的減少服務的開銷。

至於贊和評論的實現,是相對簡單的。上面說了微信後臺有一個專門的表儲存評論和讚的資料,比如Kate是Mary和小王的朋友的話,刷到了K2這一條釋出,就會同時從評論表裡面拉取對應K2的、Mary留下的評論內容,插入到K2內容的下方。而如果另一個人不是Mary和小王的共同朋友,則不會看到這條評論。

容災方案

640?wx_fmt=png

第二個層次的容災是跨地域的。微信最早在國內有一個上海的資料中心,這個資料中心承載了全國所有的使用者。後來有一天上海來了個海嘯還是什麼的,所有資料都沒了,於是後來在深圳又建立一個資料中心,上海服務北方使用者,深圳服務南方。後來因為微信發展海外使用者,於是在香港建立了第三個資料中心,主要服務東南亞、南亞、中東和非洲。後來在加拿大又建立了第四個資料中心,主要服務美洲和歐洲。

這第二個層次的資料中心跟上面說的園區不太一樣。每一個微信使用者事實上都屬於一個特定的資料中心,比如兩個北方的使用者,他們的資料都在上海的資料中心,如果說上海資料中心跟其他資料中心的連線斷了,這兩個使用者之間的通訊是不會受到影響的。但如果有一個外國朋友在加拿大的資料中心,那麼他跟國內使用者的通訊就可能受到影響。資料中心之間是有專線連線的,但實際上國內到國外的專線渠道並不太有保障,所以專線出問題的時候,兩個資料中心之間的資料交換會切換到公網上,走普通的網際網路。

新建一個資料中心涉及到很多同步,微信訊息的資料同步是通過一個idcqueue元件實現的,是一個非同步的資料同步方式。這個非同步的寫操作可能會由於網路阻塞或者其他原因,慢個一兩秒種、幾分鐘甚至半天,但它會一直重試,能夠保持正確性。而對於朋友圈來說,朋友圈是多資料副本的模型,那麼多資料副本在跨資料中心同步的時候如何保證正確性,如何保證沒有衝突?

640?wx_fmt=png

當然有關這一塊還有很多細節的問題,尤其是因為國內到國外的網路延遲很大,從大陸ping美國可能兩百個毫秒,ping阿根廷或者南非可能有四百個毫秒,另外公網的丟包也比較嚴重,這對於資料同步的實現是很有影響的。這種情況就不適合用TCP了,TCP是針對大頻寬、小延遲、有序的環境設計的,所以微信在跨資料中心做資料同步這一塊就自己研發了一套類TCP的協議,這種協議對高延遲、高丟包有很高的容忍度,能夠做到每秒同步幾百兆到上G的資料。另一方面,由於從專線切換到公網存在資訊保安隱患,這其中的資料加密也是很重要的一個工作。

公眾號推薦:

640?wx_fmt=jpeg

640?wx_fmt=jpeg

640?wx_fmt=jpeg


相關文章