導讀:網易雲信新晉的 IM 頂流產品「圈組」出道後獲取到了極大的關注,很多雲信的客戶在接入的同時對於「圈組」的底層技術細節和原理也非常關注,為此,我們決定推出雲信「圈組」相關的系列技術文章,分享網易雲信在「圈組」技術設計上的一些思考。
業務特點
在網際網路行業盛行一句話,技術是為業務服務的。具體到實踐中,一個重要方面就是要面向業務特點設計技術方案。因此,想要了解「圈組」的關係系統設計,就要首先了解「圈組」的關係業務特點。
「圈組」的關係業務特點是什麼?其一是關係複雜,即關係主體多、管理機制雜、聯動耦合重;其二是規模巨大,即成員數量可達百萬量級、變更批量可達百萬量級。
所謂關係複雜,具體來講:首先是關係主體多。在「圈組」業務中,關係主體包括伺服器、頻道、身份組、頻道分組等,伺服器承載社群關係,負責社群成員關係維護;頻道從屬於伺服器,承載內容關係,負責內容互動關係維護;身份組可從屬於伺服器或頻道,承載身份許可權關係,負責身份設定和許可權配置;頻道分組從屬於伺服器,又關聯一組頻道,承載頻道模版關係,負責分類頻道和共享配置。其次是管理機制雜。在「圈組」業務中,僅就成員管理機制而言,伺服器成員採用邀請/申請機制,頻道成員採用公開/私密模式+黑/白名單機制,身份組成員採用加入/移出機制,頻道分組成員與頻道成員採用同步機制。最後是聯動耦合。在「圈組」業務中,以頻道成員維護為例,頻道成員不僅受到公開/私密模式+黑/白名單配置變更的影響,而且會伴隨伺服器成員變更、身份組變更、身份組成員變更等做聯動變更。
所謂規模巨大,具體來講:一方面是成員數量可達百萬量級。在「圈組」業務中,伺服器成員數量可以達到數百萬人,進一步,百萬成員伺服器下的頻道和身份組,其成員數量也可以達到百萬量級。另一方面是變更批量可達百萬量級。在「圈組」業務中,不僅成員數量規模巨大,而且變更操作一個批次數量也可以達到百萬量級。包括:刪除百萬成員的伺服器/頻道/身份組,增刪頻道/頻道分組黑白名單中的百萬成員身份組等。
從「圈組」關係業務的兩大特點出發,可以發現「圈組」關係是不同於群組關係的全新業務場景,將會面臨全新的技術難點。
技術難點
「圈組」關係系統的技術難點主要有兩個方面。其一是多關係主體、多管理機制在層級結構下關聯耦合導致的業務邏輯的複雜性;其二是成員數量、變更批量規模巨大導致的業務處理在時間、空間、資源等開銷上的複雜性。
業務邏輯複雜性
首先「圈組」有多級結構。包括伺服器/頻道二級結構、伺服器/頻道分組/頻道三級結構等。單個關係主體變更,不僅涉及自身的變更,而且涉及上下級關係主體的變更,可以說牽一髮動全身。相比而言,群組是沒有層級的,群組變更只要獨善其身就好。
其次「圈組」有身份組。一個身份組是一組有共同許可權的伺服器成員的集合,不同身份組的成員可以相互交叉,身份組會作為整體參與到成員管理中。也就是說,成員變更不再只是個別成員(1-100人)的進入退出,將會出現整組成員(1-1000000人)的大進大出。相比而言,群組是沒有身份組的,群組特殊成員包括群主、管理員等也都數量不多、互不重複。
最後「圈組」有多種成員管理機制。伺服器成員和身份組成員的管理機制與群組類似,頻道成員和頻道分組成員的管理機制卻是全新模式。頻道分為公開和私密兩種,公開模式預設允許所有伺服器成員可見,但要排除黑名單身份組和黑名單成員;私密模式預設不許所有伺服器成員可見,但要放開白名單身份組和白名單成員。除了受到公開/私密模式+黑/白名單配置變更的影響,頻道成員也受到所依賴的關係主體(伺服器成員、身份組、身份組成員)變更的影響。進一步,頻道成員還受到所同步的頻道分組變更的影響。相比而言,群組成員的邀請/申請機制,可以說是小巫見大巫。
業務處理複雜性
首先是成員數量規模巨大。由於成員數量可達百萬,整個成員列表的儲存空間開銷、網路傳輸開銷,變得十分巨大,不論全量成員列表資料的伺服器快取,還是全量成員列表資料從伺服器到客戶端的同步,都將變得難以實現。
其次是變更批量規模巨大。單次介面呼叫的關係變更,可能伴隨百萬規模的聯動關係變更,這會導致巨大的處理時間開銷、計算資源開銷,不論所有變更同步完成處理,還是所有變更單機完成處理,都將變得難以實現。
最後是通知訊息規模巨大。關係系統不僅需要做關係變更的資料處理,而且需要通知變更結果到客戶端。由於在「圈組」中各個關係主體的成員數量規模巨大,使得單個變更需要擴散為百萬通知同時下發,所需計算資源開銷、網路傳輸開銷十分巨大。
相比而言,群組方案因為成員數量、變更批量規模有限,並不涉及這些技術難點。
從「圈組」關係系統的兩個方面技術難點出發,可以發現「圈組」關係系統面臨不同於群組的全新技術難點,想要解決這些技術難點,需要創新的技術方案。
技術剖析
「圈組」關係系統是整個「圈組」方案的重要組成部分,在具體介紹「圈組」關係系統技術方案之前,有必要首先了解「圈組」方案的整體架構。
「圈組」整體架構
上面展示了「圈組」方案的整體架構,可以看到「圈組」整體是一個分層架構。從上到下看:
- 客戶層:包括可供客戶端整合的移動端、桌面端、跨平臺 SDK,和可供伺服器呼叫的 OpenAPI。
- 接入層:包括 LBS 服務、長連線服務和 API 閘道器,分別對應客戶端 SDK 和使用者伺服器。
- 網路層:包括自研的全球實時傳輸網路 WE-CAN。
- 業務層:包括用於 SDK 業務處理的 App 服務和用於 OpenAPI 業務處理的 WebServer 服務。
- 服務層:劃分有登入、訊息、關係、身份組、支援等服務模組,每個服務模組包括有多個微服務或消費者。
- 基礎設施層:包括系統所用的資料庫和中介軟體。
關係系統架構
關係系統技術細節
在「圈組」關係系統中,下面具體討論三個方案要點的技術細節,包括頻道成員關係管理、變更通知線上廣播和關係資料雲端檢索。
頻道成員關係管理
頻道成員關係管理,是「圈組」中極具挑戰性的問題。頻道成員涉及多關係主體、多管理機制、聯動變更耦合嚴重,成員數量和變更批量規模巨大,可以說是「圈組」關係業務的典型代表。頻道成員關係管理在業務邏輯和業務處理兩方面的複雜性可想而知。針對頻道成員關係管理問題,「圈組」設計了兩大機制加以解決。包括:終態維護與過渡計算相結合機制、事件按序非同步並行處理機制。
終態維護與過渡計算相結合機制,具體來講,頻道成員關係資料最終被維護在持久化資料庫中,並在頻道成員沒有變更的終態階段,直接支援頻道成員資料的查詢需求。當頻道成員發生變更時,由於變更邏輯和變更處理兩方面的複雜性,完成關係變更需要一段時間,稱之為過渡階段。在過渡階段,資料庫持久化的頻道成員表資料是不完全準確的,無法直接支援頻道成員資料的查詢需求。此時轉為由頻道成員配置後設資料直接計算頻道成員以支援查詢需求。因為頻道成員配置後設資料的變更是同步處理的,所以在過渡階段由頻道成員配置後設資料直接計算頻道成員可以保證查詢準確性。通過將頻道成員關係管理分為終態和過渡兩個階段,並在不同階段採用不同頻道成員查詢方案,不僅解決了單純由計算獲取頻道成員資源開銷大的問題,而且解決了頻道成員變更延遲導致由資料庫獲取頻道成員結果不準確的問題。
除了頻道成員的獲取查詢問題,頻道成員的變更處理也很重要。事件按序非同步並行處理機制,就是用於解決頻道成員的變更處理問題。其一通過將影響頻道成員關係的變更操作分層級、系統化定義為變更事件,顯著降低頻道成員關係管理的業務邏輯複雜性。其二通過 ID 雜湊、分散式鎖、事件版本號控制等保證變更事件的按序處理,有效避免事件處理亂序導致的持久化資料錯誤。其三通過訊息佇列中轉事件並在消費者上非同步處理,有效解決聯動變更批量過大導致介面呼叫阻塞的問題。其四通過在單個事件處理中的多執行緒並行加速和本地快取重用加速,顯著縮短頻道成員關係變更的時間延遲。
變更通知線上廣播
關係系統不僅需要做關係變更的資料處理,而且需要通知變更結果到客戶端。在百萬量級的「圈組」關係中,每條關係變更通知,都會面臨海量擴散的接收者。除了通知分發量激增,不同接收者對於通知接收的緩急差異也值得關注。針對變更通知線上廣播問題,「圈組」設計了兩大機制加以解決。包括:變更分類通知機制、資料通知拉取機制。
在變更分類通知機制中,一方面,根據相關人員在變更中的角色,劃分為參與者和觀察者分類做通知,即參與者一定通知,觀察者按照訂閱需求通知。其中參與者一般是變更中的少數關鍵人員,觀察者則是除了參與者之外可以看到變更結果的其它人員。通過分類通知,不同接收者對於通知接收的緩急差異得到合理關注,變更通知的擴散規模也得到精準縮小。另一方面,觀察者按照訂閱需求通知,可以充分發揮「圈組」的線上廣播訂閱模式的優勢。所謂線上廣播訂閱模式,是指在使用者登陸之後,需要訂閱感興趣的伺服器/頻道的通知,「圈組」系統會記錄下這些訂閱資訊,當有新的通知時,「圈組」系統通過訂閱關係而非成員列表 + 線上狀態獲取需要線上廣播的使用者列表,從而不再需要遍歷伺服器/頻道的所有成員及其線上狀態。通過採用線上廣播訂閱模式,不僅顯著降低變更通知線上廣播的計算開銷和頻寬開銷,而且可以實現變更通知線上廣播在長連線服務叢集的並行加速和水平擴充套件。
變更通知的最終目的是將變更後的資料給到客戶端。不同於群組,「圈組」並不將變更後的資料直接由通知帶給客戶端,而是採用通知客戶端有變更再觸發客戶端拉取結果資料的機制。究其原因,不同於群組將關係資料全量同步到客戶端,「圈組」客戶端不再儲存關係資料的全量映象,因此不再需要通過全量歷史 + 增量變更的方式維護客戶端上的關係資料全量映象。與此同時,訂閱變更通知的觀察者也並不是每時每刻都要關心變更的結果資料,關心某次變更結果資料的觀察者相比訂閱變更通知的觀察者在數量上會少很多,因此,資料通知拉取機制會顯著降低變更通知的資源開銷。另外,相比帶變更資料通知,只通知有變更,便於直接合並相同型別的通知,而不用關心合併變更資料存在的時序、併發等問題,如此,資料通知拉取機制可以通過短時間內通知合併顯著降低伺服器線上廣播開銷和客戶端通知接收開銷。
關係資料雲端檢索
在「圈組」中,伴隨關係規模的大幅增長,群組基於應用伺服器全量查詢關係資料或客戶端全量同步關係資料實現精準查詢和靈活排序的方案不再適用。對此,「圈組」採用了關係資料雲端檢索的方案。
「圈組」關係資料雲端檢索方案可以支援伺服器、頻道、成員等的檢索能力。從檢索場景上分,包括廣場檢索和內部檢索。
廣場檢索:用於檢索感興趣的伺服器。可以根據名稱、類別等多種維度檢索。檢索結果可以根據預定義欄位(成員數量等)或自定義值(資料熱度等)等進行排序。
內部檢索:用於檢索使用者可見的伺服器、頻道、成員等。可以根據名稱、暱稱等多種維度檢索。檢索結果可以根據預定義欄位(建立時間等)或自定義值(資料熱度等)等進行排序。
總結
說了這麼多,雲信「圈組」作為一款全新設計的產品,沒有任何歷史包袱的限制(但是卻可以充分吸收歷史優點),你可以使用它構建一個類 Discord 產品,或者任何你想得到的社交/娛樂/遊戲產品,歡迎大家選擇。