微信朋友圈技術之道:三個人的后臺團隊與每日十億的發布量

0 評論 27455 瀏覽 148 收藏 14 分鐘

概述

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

團隊與技術棧簡介

微信后臺研發團隊由三位工程師組成。開發模式采用了敏捷的方式,大概一個月一個小版本,一個季度出一個大版本,另外每天都會有不停的后臺更新,很多是用戶看不見的,也有一些是AB測試,比如選擇一億的用戶,或者一定百分比的用戶,或者一部分男性用戶和女性用戶來做AB測試。開發語言主要使用C++,正在往C++11上遷移,編譯器在往GCC 4.8.2遷移。

服務器的配置基本都是普通的服務器,最好的服務器也就是64G內存,這部分占比不多,大部分是32G內存,也有很少一部分8G內存的。硬盤是SSD和SATA都有。CPU以16核居多,有一部分新機器是32核。至于帶寬則是比較多的,對外帶寬很大。

微信朋友圈的架構概述

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

微信的架構跟普通的架構差不多,最上面是終端通過接入服務器接進來。接入層主要是長連接,長連接主要是為了安卓系統,一個是減少建立新連接的性能消耗,另一個是為了推送通知,因為Google服務在國內基本是不可用的,安卓系統上的推送通知都是用長連接完成。

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

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

涉及朋友圈數據的有四個核心的表:

  • 一個是發布。發布數據記錄了來自所有用戶所有的feed,比如一個用戶發布了幾張圖片,每張圖片的URL是什么,在CDN里的URL是什么,它有哪些元屬性,誰可以看,誰不可以看等等。
  • 一個是相冊。相冊是每個用戶獨立的,記錄了該用戶所發布的所有內容。
  • 一個是評論。評論就是針對某個具體發布的朋友評論和點贊操作。
  • 一個是時間線。所謂“刷朋友圈”,就是刷時間線,就是一個用戶所有朋友的發布內容。

上面提到過,微信現在每天的發布有10億多,瀏覽量超過100億,對性能的要求很高,所以上面的存儲都是做成可以水平擴展的。對于水平擴展的實現,下面舉例說明。

微信朋友圈的工作流程概述

比如有兩個用戶小王和Mary。小王和Mary各自有各自的相冊,可能在同一臺服務器上,也可能在不同的服務器上?,F在小王上傳了一張圖片到自己的朋友圈。上傳圖片不經過微信后臺服務器,而是直接上傳到最近的騰訊CDN節點,所以非???。圖片上傳到該CDN后,小王的微信客戶端會通知微信的朋友圈CDN:這里有一個新的發布(比如叫K2),這個發布的圖片URL是什么,誰能看到這些圖片,等等此類的元數據,來把這個發布寫到發布的表里。

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

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

在這個過程中,發布是很重的,因為一方面要寫一個自己的數據副本,然后還要把這個副本的指針插到所有好友的時間線里面去。如果一個用戶有幾百個好友的話,這個過程會比較慢一些。這是一個單數據副本寫擴散的過程。但是相對應的,讀取就很簡單了,每一個用戶只需要讀取自己的時間線表,就這一個動作就行,而不需要去遍歷所有好友的相冊表。

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

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

微信朋友圈的容災

容災有不同的層次,先看區域性的。微信在上海有一個IDC,該IDC是由三個獨立的園區——A、B、C三個園區構成的。每一個園區都有獨立的供電、制冷,獨立的帶寬,帶寬同時連接聯通、電信,而且每個園區的容量都有富余。三個園區直接有高速連接。所以無論任何一個區,比如C區整個不可用了,那么用戶的客戶端會自動連接到另外兩個區,這兩個區有足夠的容量承載所有的服務。這種切換是無損的、無感知的。

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

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

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

解法其實也簡單,只要單項同步最初的發布寫操作。比如小王這個用戶是在上海數據中心的,他在自己相冊上新增了一條發布K2,那么就只要單項同步把K2寫到香港去就好了。反過來,比如Mary是在香港,那么她有新的發布,只要在香港寫進去之后,單項同步到上海就可以了。這樣就不存在時間線多數據副本同步的問題了,只要在各個數據中心內分別做批處理。

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

作者簡介

陳明,微信高級工程師、朋友圈負責人,2012年加入微信后臺團隊,負責微信后臺核心服務的研發,包括朋友圈、即時通信、基礎設施等。他獲得清華大學計算機系學士和博士學位,研究方向是分布式系統。在加入微信前,他在騰訊搜索和微軟亞洲研究院工作多年,內容包括搜索架構與分布式存儲等。

 

文章來源@InfoQ技術沙龍

版權聲明:若該文章涉及版權問題,請聯系我們主編,QQ:419297645

更多精彩內容,請關注人人都是產品經理微信公眾號或下載App
評論
評論請登錄
  1. 目前還沒評論,等你發揮!