Jack Jiang

          我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
          posts - 499, comments - 13, trackbacks - 0, articles - 1

          本文由微信技術團隊分享,原題“十年前的微信消息收發架構長啥樣?”,下文進行了排版和內容優化等。

          1、引言

          2023 年,微信及 WeChat 的 DAU(月活用戶)達到 13.4 億,微信已經是很多人工作、生活中不可或缺的一個環節。從 2011 年 1 月 21 日上線至今,微信已經走過了 13 個年頭,其背后的技術基座與架構也發生了巨大的變化。這些變化背后,所折射的也正是中國互聯網高速發展的黃金年代。

          好的架構是迭代出來的,卻也少不了良好的設計,本文將帶大家回顧微信背后最初的也是最核心的IM消息收發技術架構,愿各位讀者能從中獲得啟發。

           
           

          技術交流:

          - 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

          - 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK備用地址點此

          (本文已同步發布于:http://www.52im.net/thread-4636-1-1.html

          2、微信技術起步

          微信誕生于 QQMail 團隊,初始的整個微信后臺架構都帶著濃重的郵箱氣息,消息收發架構作為微信最為核心的部分,同樣是基于郵箱的存儲轉發機制演變而來

          微信定位為即時通訊IM軟件,對消息的收發有2個基本的要求:

          • 1)消息盡可能的實時送達;
          • 2)不丟消息。

          在郵箱的存儲轉發機制上做了改良后,微信的消息收發實現了以上2個基本要求。

          3、消息發送架構

          首先通過手機 A 給手機 B 發送一條微信消息來看消息發送的整體架構是怎樣的(如下圖所示)。

          微信消息發送在整體架構上可以分為2個部分。

          第一部分:手機A發送消息到服務器(上圖中1、2、3部分):

          • 1)- 手機A發送發消息請求到接入層 ConnnectSvr;
          • 2)2 - 接入層收到請求后,將請求轉到邏輯層 SendSvr 進行處理;
          • 3)3 - 邏輯層處理完各種邏輯(如反垃圾,黑名單等等)之后,將消息存入存儲層 MsgStore。

          第二部分:服務器發送通知到手機B(上圖中4、5.1、5.2、6、7部分):

          1)4 - 邏輯層 SendSvr 將給手機 B 的新消息到達通知發送到通知處理服務器 PushSvr。

          2)5.1 - PushSvr 查詢手機 B 在接入層所在長連接的 ConnectSvr,并將通知發給該 ConnectSvr。

          3)5.2 - PushSvr 發送一個 Push tips 給手機操作系統自建的第三方 Push 系統(如蘋果的 APNsPush,微軟的 WPPush,黑莓的 BBPush 等)。像蘋果的 IOS 系統,在 APP 退出到后臺10分鐘后就會釋放掉該 APP 所持有的所有資源(如 CPU,網絡,內存等),導致之前建立的長連接通道也會一并斷掉,此時通過5.1的方式進行通知是不可達的,所以還需要依賴與蘋果自身的 apns 通道來達到實時通知的目的。

          4)6 - 接入層 ConnnectSvr 通過手機 B 建立的長連接通道將新消息達到通知發送給手機 B。

          5)7 - 第三方 Push 服務器通過自建的 Push 通過發送 Push tips 到手機 B。

          4、消息接收架構

          手機 B 在收到新消息到達通知后進行消息收取的整體架構如下圖所示:

           

          消息收取的流程主要分為3個步驟:

          • 1)手機 B 發起收取消息的請求到接入層服務器 ConnnectSvr;
          • 2)接入層服務器 ConnnectSvr 接到請求后轉給邏輯層服務器 ReceiveSvr 進行處理;
          • 3)ReceiveSvr 從存儲層 MsgStore 中獲取到需要下發的消息。

          5、消息收發架構小結

          在上述第4、5兩節中分享的消息收發架構保障之下,微信可以保證手機 A 在發出消息 100ms 級別內讓手機 B 收取到該條消息。

          當然,對于退出后臺的蘋果 iOS 的微信用戶,在蘋果的 APNs 服務器正常的情況下,也可以保證在秒級別內通知到手機 B 點開 APP 進入前臺來收取消息。

          6、消息防丟失機制

          雖然消息收發架構保證了消息收發雙方能夠及時收發消息,但該架構不能保證消息在傳輸過程中不發生丟棄。

          當然為了達到任意一條消息都不丟的狀態,最簡單的方案是手機端對收到的每條消息都給服務器進行一次 ack 確認,但該方案在手機端和服務器之間的交互過多,并且也會遇到在弱網絡情況下 ack 丟失等問題。

          為了完美的做到消息不丟,微信消息系統對消息收發引入了 sequence 機制。

          PS:感興趣的話,以下是更多與IM消息送達保證有關的文章,可以一并閱讀:

          1. 理解IM消息“可靠性”和“一致性”問題,以及解決方案探討
          2. 融云技術分享:全面揭秘億級IM消息的可靠投遞機制
          3. 從客戶端的角度來談談移動端IM的消息可靠性和送達機制
          4. IM消息送達保證機制實現(一):保證在線實時消息的可靠投遞

          7、消息防丟失機制技術實現

          7.1sequence 機制

          • 1)每個用戶都有42億的 sequence 空間(從1到 UINT_MAX),從小到大連續分配;
          • 2)每個用戶的每條消息都需要分配一個 sequence;
          • 3)服務器存儲有每個用戶已經分配到的最大 sequence;
          • 4)手機端存儲有已收取消息的最大 sequence。

          PS:微信sequence序列號生成的具體算法和實現詳見《微信技術分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)》。

          7.2消息收取sequnece確認機制

          當服務器和手機端都擁有了一個 sequence 之后,服務器和手機端之間就可以根據兩者 sequence 的差異來收取消息,同時保證手機端未收取下去的消息最終能夠收取下去。

          具體流程如下圖表示:

          1)根據服務器和手機端之間 sequence 的差異,可以很輕松的實現增量下發手機端未收取下去的消息。

          2)對于在弱網絡環境差的情況,丟包情況發生概率是比較高的,此時經常會出現服務器的回包不能到達手機端的現象。由于手機端只會在確切的收取到消息后才會更新本地的 sequence,所以即使服務器的回包丟了,手機端等待超時后重新拿舊的 sequence 上服務器收取消息,同樣是可以正確的收取未下發的消息。

          3)由于手機端存儲的 sequence 是確認收到消息的最大 sequence,所以對于手機端每次到服務器來收取消息也可以認為是對上一次收取消息的確認。一個帳號在多個手機端輪流登錄的情況下,只要服務器存儲手機端已確認的 sequence,那就可以簡單的實現已確認下發的消息不會重復下發,不同手機端之間輪流登錄不會收到其他手機端已經收取到的消息。

          如上圖4所示:假如手機 A 拿 Seq_cli = 100 上服務器收取消息,此時服務器的 Seq_svr =  150,那手機 A 可以將 sequence 為[101 - 150]的消息收取下去,同時手機 A 會將本地的 Seq_cli 置為150。

           

          如上圖5所示:手機 A 在下一次再次上來服務器收取消息,此時 Seq_cli = 150,服務器的 Seq_svr = 200,那手機 A 可以將 sequence為[151 - 200]的消息收取下去。

          如上圖6所示:假如原手機 A 用戶換到手機 B 登錄,并使用 Seq_cli = 120 上服務器收取消息,由于服務器已經確認 sequence <= 150 的消息已經被手機收取下去了,故不會再返回 sequence 為[121 - 150]的消息給手機 B,而是將 sequence 為[151 - 200]的消息下發給手機 B。

          這里雖然 sequence 為[151 - 200]的消息有可能是被手機 A 和手機 B 都收取到,但由于手機 A 在收到 sequence 為[151 - 200]的消息時并沒有給服務器進行確認或者這些消息手機 A 壓根就沒有收取到,所以為了防止消息丟失,sequence 為[的消息也是需要下發給手機 B 的。

          8、本文小結

          以上簡單文字描述的就是微信最初的IM消息收發的架構。

          該架構實現了即時通訊軟件對消息收發所需的兩個基本要求:

          • 1)消息盡可能的實時送達 ;
          • 2)不丟消息。

          以上:是 2014 年微信古早時期的消息收發架構的基本介紹,時過境遷,微信的消息收發架構已經發生了巨大的變化,但我們還是可以從中看到技術演變的價值與力量。

          程序員最大的成就與幸福,或許就是自己的代碼跑在千萬人的設備上,默默支撐著海量的需求。

          9、參考資料

          [1] iOS的推送服務APNs詳解:設計思路、技術原理及缺陷等

          [2] 了解iOS消息推送一文就夠:史上最全iOS Push技術詳解

          [3] 消息推送技術干貨:美團實時消息推送服務的技術演進之路

          [4] 微信技術分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)

          [5] 企業微信的IM架構設計揭秘:消息模型、萬人群、已讀回執、消息撤回等

          [6] 一套億級用戶的IM架構技術干貨(上篇):整體架構、服務拆分等

          [7] 一套億級用戶的IM架構技術干貨(下篇):可靠性、有序性、弱網優化等

          [8] 從新手到專家:如何設計一套億級消息量的分布式IM系統

          [9] 一套分布式IM即時通訊系統的技術選型和架構設計

          [10] 從客戶端的角度來談談移動端IM的消息可靠性和送達機制

          [11] IM消息送達保證機制實現(一):保證在線實時消息的可靠投遞

          [12] IM開發寶典:史上最全,微信各種功能參數和邏輯規則資料匯總

          [13] 零基礎IM開發入門(一):什么是IM系統?

          [14] 理解IM消息“可靠性”和“一致性”問題,以及解決方案探討

          [15] 融云技術分享:全面揭秘億級IM消息的可靠投遞機制

          10、微信團隊的其它文章

          微信七年回顧:歷經多少質疑和差評,才配擁有今天的強大

          前創始團隊成員分享:盤點微信的前世今生——微信成功的必然和偶然

          即時通訊創業必讀:解密微信的產品定位、創新思維、設計法則等

          [技術腦洞] 如果把14億中國人拉到一個微信群里技術上能實現嗎?

          那些年微信開發過的雞肋功能,及其帶給我們的思考

          讀懂微信:從1.0到7.0版本,一個主流IM社交工具的進化史

          同為IM社交產品中的王者,QQ與微信到底有什么區別

          還原真實的騰訊:從最不被看好,到即時通訊巨頭的草根創業史

          社交應用教父級人物的張小龍和馬化騰的同與不同

          專訪馬化騰:首次開談個人經歷、管理心得、技術創新、微信的誕生等

          一文讀懂微信之父張小龍:失敗天才、顛覆者、獨裁者、人性操控師

          微信團隊分享:極致優化,iOS版微信編譯速度3倍提升的實踐總結

          IM“掃一掃”功能很好做?看看微信“掃一掃識物”的完整技術實現

          微信團隊分享:微信支付代碼重構帶來的移動端軟件架構上的思考

          IM開發寶典:史上最全,微信各種功能參數和邏輯規則資料匯總

          微信團隊分享:微信直播聊天室單房間1500萬在線的消息架構演進之路

          企業微信的IM架構設計揭秘:消息模型、萬人群、已讀回執、消息撤回等

          IM全文檢索技術專題(四):微信iOS端的最新全文檢索技術優化實踐

          微信團隊分享:微信后臺在海量并發請求下是如何做到不崩潰的

          微信Windows端IM消息數據庫的優化實踐:查詢慢、體積大、文件損壞等

          微信技術分享:揭秘微信后臺安全特征數據倉庫的架構設計

          IM跨平臺技術學習(九):全面解密新QQ桌面版的Electron內存優化實踐

          企業微信針對百萬級組織架構的客戶端性能優化實踐

          揭秘企業微信是如何支持超大規模IM組織架構的——技術解讀四維關系鏈

          微信團隊分享:詳解iOS版微信視頻號直播中因幀率異常導致的功耗問題

          微信團隊分享:微信后端海量數據查詢從1000ms降到100ms的技術實踐

          大型IM工程重構實踐:企業微信Android端的重構之路

          IM技術干貨:假如你來設計微信的群聊,你該怎么設計?


          (本文已同步發布于:http://www.52im.net/thread-4636-1-1.html

          posted @ 2024-04-11 11:05 Jack Jiang 閱讀(108) | 評論 (0)編輯 收藏

          關于MobileIMSDK

          MobileIMSDK 是一套專門為移動端開發的開源IM即時通訊框架,超輕量級、高度提煉,一套API優雅支持 UDP 、TCP 、WebSocket 三種協議,支持 iOS、Android、H5、標準Java、小程序、Uniapp,服務端基于Netty編寫。

          工程開源地址是:

          關于RainbowChat

          ► 詳細產品介紹:http://www.52im.net/thread-19-1-1.html
          ► iOS端更新記錄:http://www.52im.net/thread-2735-1-1.html
          ► 全部運行截圖:iOS端全部運行截圖 (另:Android端運行截圖 點此查看
          ► 在線體驗下載:App Store安裝地址 (另:Android端下載體驗 點此查看

           

          RainbowChat是一套基于開源IM聊天框架 MobileIMSDK 的產品級移動端IM系統。RainbowChat源于真實運營的產品,解決了大量的屏幕適配、細節優化、機器兼容問題(可自行下載體驗:專業版下載安裝)。

          RainbowChat可能是市面上提供im即時通訊聊天源碼的,唯一一款同時支持TCP、UDP兩種通信協議的IM產品(通信層基于開源IM聊天框架 MobileIMSDK 實現)。

          v9.0 版更新內容

          此版更新內容更多歷史更新日志):

          • 1)[新增] 新增“@”功能;
          • 2)[新增] 新增消息引用功能(支持引用全部消息類型);
          • 3)[bug] 解決顯示Android端發起的的音視頻呼叫記錄時,顯示的是JSON文本的問題;
          • 4)[bug] 解決了消息轉發時,“最近消息”列表中的表情內容沒有被轉義成表情圖標的問題;
          • 5)[bug] 聊天界面中對新發的圖片消息等長按時不顯示彈出菜單的問題(直到表格被刷新后才會正常);
          • 6)[優化] 首頁消息列表中的語音消息將顯示語音時長(跟新版微信一樣);
          • 7)[優化] 其它優化及bug修復。

          新增功能運行截圖(更多截圖點此查看):

          posted @ 2024-04-07 12:18 Jack Jiang 閱讀(526) | 評論 (0)編輯 收藏

               摘要: 本文由蘇三說技術分享,原題“微信群聊功能,原來是這樣設計的!”,下文進行了排版和內容優化等。1、引言當我那天拿著手機,正在和朋友們的微信群里暢聊著八卦新聞和即將到來的周末計劃時,忽然一條帶著喜意的消息撲面而來,消息正中間寫著八個大字:恭喜發財,大吉大利。搶紅包!!相信大部分人對此都不陌生,微信的這個群聊系統可以方便地聊天、分享圖片和表情,還有那個神奇的紅包功能。微信作為 1...  閱讀全文

          posted @ 2024-04-03 10:25 Jack Jiang 閱讀(107) | 評論 (0)編輯 收藏

               摘要: 本文由騰訊技術yeconglu分享,原題“企業微信大型Android系統重構之路”,下文進行了排版和內容優化等。1、引言企業微信本地部署版(下文簡稱為本地版)是從2017年起,脫胎于企業微信的一款產品。本地版的后臺服務能獨立部署在政府或者大型企業的本地服務器上。在一個已經迭代了7年的大型Android端工程中,企業微信本地版不可避免地會暴露出一些遺留系統的特點。本文將探討我...  閱讀全文

          posted @ 2024-03-28 11:21 Jack Jiang 閱讀(126) | 評論 (0)編輯 收藏

          本文由微信技術團隊仇弈彬分享,原題“微信海量數據查詢如何從1000ms降到100ms?”,本文進行了內容修訂和排版優化。

          1、引言

          微信的多維指標監控平臺,具備自定義維度、指標的監控能力,主要服務于用戶自定義監控。作為框架級監控的補充,它承載著聚合前 45億/min、4萬億/天的數據量。

          當前,針對數據層的查詢請求也達到了峰值 40萬/min,3億/天。較大的查詢請求使得數據查詢遇到了性能瓶頸:查詢平均耗時 > 1000ms,失敗率居高不下。

          針對大數據量帶來的查詢性能問題,微信團隊對數據層查詢接口進行了針對性的優化,將平均查詢速度從1000ms+優化到了100ms級別。本文為各位分享優化過程,希望對你有用!

           
           

          技術交流:

          - 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

          - 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK備用地址點此

          (本文已同步發布于:http://www.52im.net/thread-4629-1-1.html

          2、技術背景

          微信多維指標監控平臺(以下簡稱多維監控),是具備靈活的數據上報方式、提供維度交叉分析的實時監控平臺。

          在這里,最核心的概念是“協議”、“維度”與“指標”。

          例如:如果想要對某個【省份】、【城市】、【運營商】的接口【錯誤碼】進行監控,監控目標是統計接口的【平均耗時】和【上報量】。在這里,省份、城市、運營商、錯誤碼,這些描述監控目標屬性的可枚舉字段稱之為“維度”,而【上報量】、【平均耗時】等依賴“聚合計算”結果的數據值,稱之為“指標”。而承載這些指標和維度的數據表,叫做“協議”。

          多維監控對外提供 2 種 API:

          1)維度枚舉查詢:用于查詢某一段時間內,一個或多個維度的排列組合以及其對應的指標值。它反映的是各維度分布“總量”的概念,可以“聚合”,也可以“展開”,或者固定維度對其它維度進行“下鉆”。數據可以直接生成柱狀圖、餅圖等。

          2)時間序列查詢:用于查詢某些維度條件在某個時間范圍的指標值序列。可以展示為一個時序曲線圖,橫坐標為時間,縱坐標為指標值。

          然而,不管是用戶還是團隊自己使用多維監控平臺的時候,都能感受到明顯的卡頓。主要表現在看監控圖像或者是查看監控曲線,都會經過長時間的數據加載。

          團隊意識到:這是數據量上升必然帶來的瓶頸。

          目前:多維監控平臺已經接入了數千張協議表,每張表的特點都不同。維度組合、指標量、上報量也不同。針對大量數據的實時聚合以及 OLAP 分析,數據層的性能瓶頸越發明顯,嚴重影響了用戶體驗。

          于是這讓團隊人員不由得開始思考:難道要一直放任它慢下去嗎?答案當然是否定的。因此,微信團隊針對數據層的查詢進行了優化。

          3、優化分析1:用戶查詢行為分析

          要優化,首先需要了解用戶的查詢習慣,這里的用戶包含了頁面用戶和異常檢測服務。

          于是微信團隊盡可能多地上報用戶使用多維監控平臺的習慣,包括但不限于:常用的查詢類型、每個協議表的查詢維度和查詢指標、查詢量、失敗量、耗時數據等。

          在分析了用戶的查詢習慣后,有了以下發現:

          1)時間序列查詢占比 99% 以上:

          出現如此懸殊的比例可能是因為:調用一次維度枚舉,即可獲取所關心的各個維度。

          但是針對每個維度組合值,無論是頁面還是異常檢測都會在查詢維度對應的多條時間序列曲線中,從而出現「時間序列查詢」比例遠遠高于「維度枚舉查詢」。

          2)針對1天前的查詢占比約 90%:

          出現這個現象可能是因為每個頁面數據都會帶上幾天前的數據對比來展示。異常檢測模塊每次會對比大約 7 天數據的曲線,造成了對大量的非實時數據進行查詢。

          4、優化分析2:數據層架構

          分析完用戶習慣,再看下目前的數據層架構。

          多維監控底層的數據存儲/查詢引擎選擇了 Apache-Druid 作為數據聚合、存儲的引擎,Druid 是一個非常優秀的分布式 OLAP 數據存儲引擎,它的特點主要在于出色的預聚合能力和高效的并發查詢能力。

          它的大致架構如圖:

          具體解釋就是:

          5、優化分析3:為什么查詢會慢

          查詢慢的核心原因,經微信團隊分析如下:

          1)協議數據分片存儲的數據片段為 2-4h 的數據,每個 Peon 節點消費回來的數據會存儲在一個獨立分片。

          2)假設異常檢測獲取 7 * 24h 的數據,協議一共有 3 個 Peon 節點負責消費,數據分片量級為 12*3*7 = 252,意味著將會產生 252次 數據分片 I/O。

          3)在時間跨度較大時、MiddleManager、Historical 處理查詢容易超時,Broker 內存消耗較高。

          4)部分協議維度字段非常復雜,維度排列組合極大(>100w),在處理此類協議的查詢時,性能就會很差。

          6、優化實踐1:拆分子查詢請求

          根據上面的分析,團隊確定了初步的優化方向:

          • 1)減少單 Broker 的大跨度時間查詢;
          • 2)減少 Druid 的 Segments I/O 次數;
          • 3)減少 Segments 的大小。

          在這個方案中,每個查詢都會被拆解為更細粒度的“子查詢”請求。例如連續查詢 7 天的時間序列,會被自動拆解為 7 個 1天的時間序列查詢,分發到多個 Broker,此時可以利用多個 Broker 來進行并發查詢,減少單個 Broker 的查詢負載,提升整體性能。

          但是這個方案并沒有解決 Segments I/O 過多的問題,所以需要在這里引入一層緩存。

          7、優化實踐2:拆分子查詢請求+Redis Cache

          7.1概述

          這個方案相較于 v1,增加了為每個子查詢請求維護了一個結果緩存,存儲在 Redis 中(如下圖所示)。

          假設獲取 7*24h 的數據,Peon 節點個數為 3,如果命中緩存,只會產生 3 次 Druid 的 Segments I/O (最近的 30min)數據,相較幾百次 Segments I/O 會大幅減少。

          接下來看下具體方法。

          7.2時間序列子查詢設計

          針對時間序列的子查詢,子查詢按照「天」來分解,整個子查詢的緩存也是按照天來聚合的。

          以一個查詢為例:

          {

              "biz_id": 1, // 查詢協議表ID:1

              "formula": "avg_cost_time", // 查詢公式:求平均

              "keys": [

                  // 查詢條件:維度xxx_id=3

                  {"field": "xxx_id", "relation": "eq", "value": "3"}

              ],

              "start_time": "2020-04-15 13:23", // 查詢起始時間

              "end_time": "2020-04-17 12:00"http:// 查詢結束時間

          }

          其中 biz_id、 formula,、keys 了每個查詢的基本條件。但每個查詢各不相同,不是這次討論的重點。

          本次優化的重點是基于查詢時間范圍的子查詢分解,而對于時間序列子查詢分解的方案則是按照「天」來分解,每個查詢都會得到當天的全部數據,由業務邏輯層來進行合并。

          舉個例子:04-15 13:23 ~ 04-17 08:20 的查詢,會被分解為 04-15、04-16、04-17 三個子查詢,每個查詢都會得到當天的全部數據,在業務邏輯層找到基于用戶查詢時間的偏移量,處理結果并返回給用戶。

          每個子查詢都會先嘗試獲取緩存中的數據,此時有兩種結果:

          經過上述分析不難看出:對于距離現在超過一天的查詢,只需要查詢一次,之后就無需訪問 DruidBroker 了,可以直接從緩存中獲取。

          而對于一些實時熱數據,其實只是查詢了cache_update_time-threshold_time 到 end_time 這一小段的時間。在實際應用里,這段查詢時間的跨度基本上在 20min 內,而 15min 內的數據由 Druid 實時節點提供。

          7.3維度組合子查詢設計

          維度枚舉查詢和時間序列查詢不一樣的是:每一分鐘,每個維度的量都不一樣。

          而維度枚舉拿到的是各個維度組合在任意時間的總量,因此基于上述時間序列的緩存方法無法使用。在這里,核心思路依然是打散查詢和緩存。

          對此,微信團隊使用了如下方案。

          緩存的設計采用了多級冗余模式,即每天的數據會根據不同時間粒度:天級、4小時級、1 小時級存多份,從而適應各種粒度的查詢,也同時盡量減少和 Redis 的 IO 次數。

          每個查詢都會被分解為 N 個子查詢,跨度不同時間,這個過程的粗略示意圖如下:

          舉個例子:例如 04-15 13:23 ~ 04-17 08:20 的查詢,會被分解為以下 10 個子查詢:

          04-15 13:23 ~ 04-15 14:00

          04-15 14:00 ~ 04-15 15:00

          04-15 15:00 ~ 04-15 16:00

          04-15 16:00 ~ 04-15 20:00

          04-15 20:00 ~ 04-16 00:00

          04-16 00:00 ~ 04-17 00:00

          04-17 00:00 ~ 04-17 04:00

          04-17 00:00 ~ 04-17 04:00

          04-17 04:00 ~ 04-17 08:00

          04-17 08:00 ~ 04-17 08:20

          這里可以發現:查詢 1 和查詢 10,絕對不可能出現在緩存中。因此這兩個查詢一定會被轉發到 Druid 去進行。2~9 查詢,則是先嘗試訪問緩存。如果緩存中不存在,才會訪問 DruidBroker,在完成一次訪問后將數據異步回寫到 Redis 中。

          維度枚舉查詢和時間序列一樣,同時也用了 update_time 作為數據可信度的保障。因為最細粒度為小時,在理想狀況下一個時間跨越很長的請求,實際上訪問 Druid 的最多只有跨越 2h 內的兩個首尾部查詢而已。

          8、優化實踐3:更進一步(子維度表)

          通過子查詢緩存方案,我們已經限制了 I/O 次數,并且保障 90% 的請求都來自于緩存。但是維度組合復雜的協議,即 Segments 過大的協議,仍然會消耗大量時間用于檢索數據。

          所以核心問題在于:能否進一步降低 Segments 大小?

          維度爆炸問題在業界都沒有很好的解決方案,大家要做的也只能是盡可能規避它,因此這里,團隊在查詢層實現了子維度表的拆分以盡可能解決這個問題,用空間換時間。

          具體做法為:

          • 1) 對于維度復雜的協議,抽離命中率高的低基數維度,建立子維度表,實時消費并入庫數據;
          • 2) 查詢層支持按照用戶請求中的查詢維度,匹配最小的子維度表。

          9、優化成果

          9.1緩存命中率>85%

          在做完所有改造后,最重要的一點便是緩存命中率。因為大部分的請求來自于1天前的歷史數據,這為緩存命中率提供了保障。

          具體是:

          • 1)子查詢緩存完全命中率(無需查詢Druid):86%;
          • 2)子查詢緩存部分命中率(秩序查詢增量數據):98.8%。

          9.2查詢耗時優化至 100ms

          在整體優化過后,查詢性能指標有了很大的提升:

          平均耗時 1000+ms -> 140ms;P95:5000+ms -> 220ms。

           

          10、相關文章

          [1] 微信后臺基于時間序的海量數據冷熱分級架構設計實踐

          [2] IM開發基礎知識補課(三):快速理解服務端數據庫讀寫分離原理及實踐建議

          [3] 社交軟件紅包技術解密(六):微信紅包系統的存儲層架構演進實踐

          [4] 微信后臺基于時間序的新一代海量數據存儲架構的設計實踐

          [5] 陌陌技術分享:陌陌IM在后端KV緩存架構上的技術實踐

          [6] 現代IM系統中聊天消息的同步和存儲方案探討

          [7] 微信海量用戶背后的后臺系統存儲架構(視頻+PPT) [附件下載]

          [8] 騰訊TEG團隊原創:基于MySQL的分布式數據庫TDSQL十年鍛造經驗分享

          [9] IM全文檢索技術專題(四):微信iOS端的最新全文檢索技術優化實踐

          [10] 微信Windows端IM消息數據庫的優化實踐:查詢慢、體積大、文件損壞等

          [11] 微信技術分享:揭秘微信后臺安全特征數據倉庫的架構設計

          [12] 現代IM系統中聊天消息的同步和存儲方案探討

          11、微信團隊的其它文章

          Android版微信安裝包“減肥”實戰記錄

          iOS版微信安裝包“減肥”實戰記錄

          移動端IM實踐:iOS版微信界面卡頓監測方案

          微信“紅包照片”背后的技術難題

          IPv6技術詳解:基本概念、應用現狀、技術實踐(上篇)

          微信技術分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)

          微信團隊分享:Kotlin漸被認可,Android版微信的技術嘗鮮之旅

          社交軟件紅包技術解密(二):解密微信搖一搖紅包從0到1的技術演進

          社交軟件紅包技術解密(十一):解密微信紅包隨機算法(含代碼實現)

          QQ設計團隊分享:新版 QQ 8.0 語音消息改版背后的功能設計思路

          微信團隊分享:極致優化,iOS版微信編譯速度3倍提升的實踐總結

          IM“掃一掃”功能很好做?看看微信“掃一掃識物”的完整技術實現

          微信團隊分享:微信支付代碼重構帶來的移動端軟件架構上的思考

          IM開發寶典:史上最全,微信各種功能參數和邏輯規則資料匯總

          微信團隊分享:微信直播聊天室單房間1500萬在線的消息架構演進之路

          企業微信的IM架構設計揭秘:消息模型、萬人群、已讀回執、消息撤回等

          微信團隊分享:微信后臺在海量并發請求下是如何做到不崩潰的

          IM跨平臺技術學習(九):全面解密新QQ桌面版的Electron內存優化實踐

          企業微信針對百萬級組織架構的客戶端性能優化實踐

          揭秘企業微信是如何支持超大規模IM組織架構的——技術解讀四維關系鏈

          微信團隊分享:詳解iOS版微信視頻號直播中因幀率異常導致的功耗問題


          (本文已同步發布于:http://www.52im.net/thread-4629-1-1.html

          posted @ 2024-03-21 13:25 Jack Jiang 閱讀(104) | 評論 (0)編輯 收藏

          本文由冀浩東分享,原題“單核QPS近6000S,陌陌基于OceanBase的持久化緩存探索與實踐”,為了閱讀便利,本文進行了排版和內容優化等。

          1、引言

          摯文集團于 2011 年 8 月推出了陌陌,這款立足地理位置服務的開放式移動視頻IM應用在中國社交平臺領域內獨樹一幟。陌陌和探探作為陌生人社交領域的主流IM應用,涵蓋了多種核心業務模塊,包括直播服務、附近動態功能、即時通訊(IM)業務以及增值服務等,每個業務場景都具有其獨特性和挑戰。

          在本文中,陌陌數據庫負責人冀浩東將聚焦探討陌陌的 KV 系統架構選型思路,深入解析如何進行此類系統的甄選決策,同時進一步分享陌陌團隊在采用 OceanBase(OBKV)過程中所經歷的探索與實踐經驗。

          技術交流:

          - 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

          - 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK備用地址點此

          (本文已同步發布于:http://www.52im.net/thread-4627-1-1.html)

          2、關于作者

          冀浩東:陌陌(現摯文集團)數據庫負責人。目前負責陌陌和探探兩個數據庫團隊建設以及集團數據庫存儲運營工作。在大規模數據源穩定性建設 、團隊建設、成本優化、機房遷移等方面等領域積累了深厚的專業經驗與實戰心得。

          3、陌陌的主要IM業務場景特點

          1)直播業務:在陌陌眾多業務場景中,直播業務占據了顯著位置,其特點就在于隨時可能出現的流量突發場景。由于低延時和高并發的需求,直播場景對數據庫系統的實時處理能力提出了較高要求。平臺需要確保在大量用戶同時在線觀看和互動時,數據能夠被及時、準確地處理和分發。

          2)附近動態:此功能則涉及到用戶的地理位置信息、活動軌跡以及社交關系等復雜數據。這類數據會迅速積累,并隨著時間的推移形成大規模的數據集。數據具有明顯的冷熱分層特性,即某些數據在某一時刻可能會成為熱點,如當某用戶發布的帖子引發熱議并成為熱門話題時。這要求系統能夠有效管理并快速響應熱點數據的訪問需求。

          3)IM 業務:此場景的核心特點是低延遲和高并發通信。信息的送達時間必須精確,對實時性有極高的要求。為了保證用戶體驗,應用程序需要確保消息能夠即時、可靠地在用戶之間傳遞。

          4)增值服務:則主要側重于數據的一致性和實時性。在處理用戶購買、贈送虛擬物品或享受會員特權等操作時,系統需要確保數據的準確性并及時更新用戶賬戶狀態。同時,為了提供優質的增值服務,實時性也是不可或缺的因素,例如實時計算用戶的積分、等級或者權益等。

          陌陌和探探在運營這些業務場景時,都需要強大的數據處理和管理系統來應對各種特性和挑戰,以確保為用戶提供高效、穩定且滿足個性化需求的社交體驗。

          針對以上的業務場景,我們應該如何選擇 KV 系統呢?

          4、陌陌后端KV緩存架構的演進階段

          在公司的成長過程中,存儲選型通常會經歷四個階段。

          4.1初始階段

          公司的主要目標是能夠運行起來。

          在創業初期,基于新開發的 App 進行運營工作時,由于業務能力可能還未成熟,為了應對快速迭代的業務需求,對系統的期望不會過高。只需要確保技術層面能夠滿足基本的業務需求并逐步演進即可。在這個階段,常見的架構選擇包括 Redis 主從架構和 Redis Cluster 等原生架構。

          Redis 主從集群架構的優勢在于可以迅速構建主從集群或分片集群,并且許多設計可以直接在客戶端操作。然而,這種簡單的操作方式可能導致設計與客戶端業務代碼的高度耦合,不利于后期的彈性擴容。

          相比之下,Redis Cluster 集群架構支持動態擴容和高可用性。

          然而,使用 Redis Cluster 時,業務依賴客戶端感知節點變更。如果客戶端未能正確處理節點變更,可能會導致服務中斷或業務性能下降,因此對于對錯誤敏感的業務,Redis Cluster 可能會引入額外的復雜性。盡管 Redis Cluster 具有去中心化、組件少、提供 Smart Client 以及支持水平擴展等優點,但也存在批處理功能不友好和缺乏有效流控機制等問題。

          4.2第二階段

          進入第二階段,隨著公司的發展和用戶數量的增長,需要架構具備快速擴展的能力。

          這一階段的代表性架構例如 Codis、Twemproxy 等基礎性 Redis分片架構。

          其中,Codis提供了服務端分片方案、中心化管理、故障自動轉移、節點水平擴展(1024 槽位)、動態擴縮容,以及支持 pipeline 和批處理等功能。

          然而,Codis的當前版本較為陳舊,官方僅提供 3.2.9 版本,更新版本需要自行修復和適配,且由于組件多、資源消耗大。

          4.3第三階段

          隨著業務的進一步發展和公司進入相對穩定期,可能會發現先前急于擴張時遺留了一些問題。

          例如:是否過度使用內存,數據是否可以冷熱分層等。這些問題需要重新檢驗和優化。這個優化過程是第三階段的重點。

          在這個階段,常見的持久化架構選擇包括 oneStore-Pika、Tendis 和 Pika 等。

          4.4第四階段

          最后,在第四階段,公司業務和技術可能已經進入了深度復雜的領域,簡單的優化調整可能無法帶來顯著的收益,甚至可能出現無法進一步優化的情況。

          這時,可以通過引入更穩定的架構或者采用新的解決思路來應對挑戰。

          我們個人推薦考慮多模態架構,它能夠適應多種數據類型和工作負載,提供更大的靈活性和優化空間。

          總的來說,公司在不同發展階段的存儲選型應根據業務需求、技術成熟度、成本效益以及未來的擴展性和優化空間等因素進行綜合考慮和決策。隨著公司的發展和業務復雜性的增加,存儲架構也需要不斷進化和優化,以確保系統的穩定、高效和可持續發展。

          5、陌陌自研的KV緩存“oneStore”

          針對當前公司的業務狀況,陌陌面臨的最顯著挑戰在于集群規模的不斷增長。

          當單集群分片數量超過 1000 個,數據量超過 10TB,以及 QPS 超過 100 萬時,現有的 Codis 架構和 Redis Cluster 架構已然無法滿足需求,達到了其承載能力的極限。

          為了解決這一瓶頸問題,公司自主研發了一款名為 oneStore 的存儲產品(如下圖所示)。

          這一架構經過了分階段的優化和改進過程,旨在突破原有的限制,以適應更高的分片數量、更大的數據量以及更密集的查詢請求。通過 oneStore 架構,陌陌力求實現業務擴展的無縫對接和性能的大幅提升。

          1)第一階段:提供服務端 Proxy 方案,并通過自主研發的 oneStore Watcher 哨兵組件進行架構精簡。這樣一來,只需要部署一套哨兵集群,就能有效地管理一個業務區域。

          2)第二階段:提供客戶端 SDK 方案。雖然服務端 Proxy 方案表現優秀,但隨著業務的穩定,公司著眼于降本增效。直接使用客戶端 SDK 方案,感知集群拓撲變化,并且通過 SDK 直連后端 Redis 地址,這樣可以去除服務端 Proxy 組件,節省技術資源開銷。然而,我們并沒有完全摒棄服務端 Proxy 方案。因為目前陌陌的客戶端 SDK 方案僅支持 Java 和 C++,對于 PHP、Python 等其他語言的用戶,仍需要通過服務端 Proxy 訪問數據源。這兩種方案的成功運用,幫助我們統一了公司層面 Redis 的接入方式,并顯著提升了機房遷移的效率。

          隨著業務的進一步穩定,陌陌開始從成本角度進行優化,選擇 Pika 替代部分請求量不高的 Redis 集群,再提升架構的持久化能力(如下圖所示)的同時降低存儲成本。

          然而現階段 Pika 主要用來存儲一些相對較冷數據,對于熱數據的處理性能仍有待提高,后續團隊也會持續關注并努力提升這一方面的性能。

          總的來說,目前陌陌還面臨一些需要解決和優化的場景:

          1)單機多實例之間互相影響的問題:陌陌迫切需要解決單機多實例之間相互影響的問題,以確保各個實例的穩定運行和高效協作。這涉及到系統的整體穩定性和協同性,需要有針對性的優化和調整。

          2)數據持久化支持:陌陌計劃增強數據持久化的支持能力,以實現完整的數據持久化解決方案,以保障數據的完整性和可靠性。不僅僅局限于冷數據,而是要覆蓋更廣泛的數據類型,以確保數據的完整性和可靠性。這將是系統長期穩定性的一個重要保障。

          所以,陌陌需要通過一個簡單可靠可擴展的 KV 系統來解決以上問題。

          6、陌陌的分布式KV緩存選型

          6.1OceanBase

          OBKV 是 OceanBase 數據庫提供的通過 API 接口訪問 Table 模型 Hbase 模型的能力。

          有關OceanBase 數據庫的來歷,詳見:阿里技術分享:阿里自研金融級數據庫OceanBase的艱辛成長之路 。

          之所以選擇 OceanBase(OBKV),主要看中其兩大優勢:

          • 1)性能更好;
          • 2)穩定性高。

          6.2關于性能

          OceanBase(OBKV)基于 Table 模型構建,與 Redis 數據結構持久化方案這個典型的表模型匹配,且性能比傳統持久化存儲更強 ,能構建更豐富的數據結構。

          下圖是OceanBase(OBKV)在大量寫數據的場景(TPS 17000),由于不同階段都有任務在寫數據,可以看出 TPS 非常陡峭,并且響應延時在 2 毫秒以下,事務的響應時間明細與預期是相對應的。

          下圖為 CPU 監控圖:可以看到 CPU 使用率在 10% 以下,相對穩定。MemStore 的使用比例也是正常的,在 24% 以內,波動范圍非常小,符合預期。

          整體來看:OceanBase(OBKV) 生產環境波動小,資源占用穩定。

          6.3關于穩定性

          OceanBase(OBKV)基于 OceanBase ,存儲引擎經過豐富的大規模 TP 場景驗證,能提供高并發、低延時的能力。

          從下圖OceanBase(OBKV) 的多租戶功能可見其穩定性。黑色線代表OceanBase(OBKV)租戶,藍色線的租戶是 MySQL 租戶。在 11:30 左右發起壓測以后,OceanBase(OBKV) 租戶的響應正常, MySQL 租戶也沒有受到影響。從服務器層面來看,CPU 負載是因為壓測而上升的,而 MySQL 租戶并不受影響。

          因此可以得出:多租戶功能能夠有效解決單機多實例的相互影響問題。下圖展示了是線上 MySQL 生產租戶的表現,TPS 為 5000時,整體表現非常穩定。CPU 和內存使用波動較小,符合預期。

          此外:能夠便捷地通過 KV 接口將數據存入數據庫,并運用 SQL 進行數據查詢。OceanBase(OBKV)進一步增強了這一便捷性,支持二級索引以及服務端TTL功能,這有助于顯著簡化上層服務架構的設計。

          盡管如此,OceanBase(OBKV)也存在一定的局限性,如僅提供單機事務處理能力;若要開啟分布式事務支持,則可能會影響到系統在高并發環境下的性能表現和低延時響應能力。但鑒于當前陌陌業務的需求,我們認為OceanBase(OBKV)的單機事務能力完全符合要求,并因此共同構建了結合OceanBase(OBKV)- Redis 儲存方案。

          7、陌陌的分布式KV集群架構改進

          陌陌與 OceanBase 開源團隊共同打造了一個內部代號為 modis 的項目。

          該項目整體架構涵蓋了接入層、數據結構層、緩沖層、存儲層以及管理平面等多個層次(具體可參考下圖)。

          值得注意的是:緩沖層在未來的規劃中將用于有效解決熱點讀取及大 KEY 問題的挑戰。而在存儲層方面,陌陌將對其進行標準化抽象設計,構建出標準的 Storage 結構,以便能夠靈活接入包括但不限于OceanBase(OBKV)在內的多種存儲解決方案。

          在測試評估過程中,將 Pika 數據(總計 158GB)成功遷移到 OceanBase(OBKV)-Redis 集群后,存儲占用空間顯著減少至 95GB,這一舉措帶來了存儲成本的顯著優化,總體上節約了大約 40% 的存儲成本。

          為了評估性能表現,特意構建了一個專門的測試環境(具體規格參見下圖),并在該環境中模擬了不同并發線程場景以觀測其峰值性能情況。

          基于多租戶管理的思路,不會對單一租戶分配過多資源,而是優先觀察各個租戶在使用過程中哪個率先達到性能瓶頸,并據此計算單核的 QPS。當前,陌陌提供的標準規格為 12C40G 內存。未來,為了更好地適應業務需求的變化,可能會推出更小規格的配置方案,例如 4C8G 或 8C16G 等規格,這些決策將完全取決于實際業務的具體需要。

          下圖展示了 128 個線程數  QPS 70000 情況下 OceanBase(OBKV)-Redis 的性能表現。

          具體是:

          • 1)P90 響應延遲為 1.9 ms;
          • 2)P95 響應延遲為 2.2 ms;
          • 3)P99響應延遲為6.3 ms;

          平均計算下來,單核讀寫比例是 4:1,此時單核能力接近 6000 QPS。

          此外:在運維管理方面,深入對比了 OceanBase(OBKV)、Pika 以及 TiKV 在日常運維操作中的特性差異。目前,只有 OceanBase(OBKV)提供了原生的多租戶支持功能,這一優勢有效地解決了在單機部署多實例時所面臨的相互干擾的問題。值得一提的是,OceanBase(OBKV)憑借完備的圖形化界面管理工具和參數變更即刻生效的特點,對于數據庫運維工作來說,無疑是極其貼心且高效的解決方案。

          總的來說,OceanBase(OBKV)-Redis 實現了性能的顯著提升、更少的磁盤使用以及運維管理的極大簡化。

          這主要得益于 OceanBase(OBKV)-Redis 的幾個優勢:

          • 1)多租戶隔離,解決單機多實例互相影響的困境;
          • 2)存儲成本更低。通過 Encoding 框架 + 通用壓縮 ,進行表模型存儲;
          • 3)性能更高。將請求過濾直接下壓存儲,不用序列化以及反序列化,支持服務端 TTL。

          8、相關文章

          [1] 知乎技術分享:從單機到2000萬QPS并發的Redis高性能緩存實踐之路

          [2] 微信后臺基于時間序的新一代海量數據存儲架構的設計實踐

          [3] 現代IM系統中聊天消息的同步和存儲方案探討

          [4] 騰訊TEG團隊原創:基于MySQL的分布式數據庫TDSQL十年鍛造經驗分享

          [5] 社交軟件紅包技術解密(六):微信紅包系統的存儲層架構演進實踐

          [6] 微信技術分享:揭秘微信后臺安全特征數據倉庫的架構設計

          [7] 阿里技術分享:深度揭秘阿里數據庫技術方案的10年變遷史

          [8] 阿里技術分享:阿里自研金融級數據庫OceanBase的艱辛成長之路

          [9] 阿里IM技術分享(九):深度揭密RocketMQ在釘釘IM系統中的應用實踐

          [10] 阿里IM技術分享(七):閑魚IM的在線、離線聊天數據同步機制優化實踐

          [11] 阿里IM技術分享(八):深度解密釘釘即時消息服務DTIM的技術設計

          [12] IM開發基礎知識補課(六):數據庫用NoSQL還是SQL?讀這篇就夠了!

          [13] 小紅書萬億級社交網絡關系下的圖存儲系統的架構設計與實踐

          [14] IM開發基礎知識補課(三):快速理解服務端數據庫讀寫分離原理及實踐建議

          [15] 微信后臺基于時間序的海量數據冷熱分級架構設計實踐

          (本文已同步發布于:http://www.52im.net/thread-4627-1-1.html

          posted @ 2024-03-14 12:09 Jack Jiang 閱讀(27) | 評論 (0)編輯 收藏

          為了更好地分類閱讀 52im.net 總計1000多篇精編文章,我將在每周三推送新的一期技術文集,本次是第35 期。

          ​[- 1 -] 直播系統聊天技術(一):百萬在線的美拍直播彈幕系統的實時推送技術實踐之路

          [鏈接] http://www.52im.net/thread-1236-1-1.html

          [摘要] 本文作者是美拍的架構師,經歷了直播彈幕從無到有,從小到大的過程,借此文為大家分享構建彈幕系統的經驗,希望能為正在開發或正打算開發彈幕、消息推送、IM聊天等系統的技術同行帶來一些啟發。

          [- 2 -] 直播系統聊天技術(二)阿里電商IM消息平臺,在群聊、直播場景下的技術實踐

          [鏈接] http://www.52im.net/thread-3252-1-1.html

          [摘要] 本文來自淘寶消息業務團隊的技術實踐分享,分析了電商IM消息平臺在非傳統IM應用場景下的高發并、強互動群聊和直播業務中的技術特點,總結并分享了在這些場景下實現大量多對多實時消息分發投遞的一些架構方面的設計實踐。

          [- 3 -] 直播系統聊天技術(三):微信直播聊天室單房間1500萬在線的消息架構演進之路

          [鏈接] http://www.52im.net/thread-3376-1-1.html

          [摘要] 本文將回顧微信直播聊天室單房間海量用戶同時在線的消息組件技術設計和架構演進,希望能為你的直播聊天互動中的實時聊天消息架構設計帶來啟發。

          [- 4 -] 直播系統聊天技術(四):百度直播的海量用戶實時消息系統架構演進實踐

          [鏈接] http://www.52im.net/thread-3515-1-1.html

          [摘要] 本文主要分享的是百度直播的消息系統的架構設計實踐和演進過程。

          [- 5 -] 直播系統聊天技術(七):直播間海量聊天消息的架構設計難點實踐

          [鏈接] http://www.52im.net/thread-3835-1-1.html

          [摘要] 本文將主要從高可用、彈性擴縮容、用戶管理、消息分發、客戶端優化等角度,分享直播間海量聊天消息的架構設計技術難點的實踐經驗。

          [- -] 直播系統聊天技術(八):vivo直播系統中IM消息模塊的架構實踐

          [鏈接] http://www.52im.net/thread-3994-1-1.html

          [摘要] 本文針對秀場直播,結合我們一年以來通過處理不同的業務線上問題,進行了技術演進式的IM消息模塊架構的升級與調整,并據此進行了技術總結、整理成文,希望借此機會分享給大家。

          [- 7 -] 直播系統聊天技術(九):千萬級實時直播彈幕的技術實踐

          [鏈接] http://www.52im.net/thread-4299-1-1.html

          [摘要] 本文基于網易云信針對TFBOYS某場線上演唱會的技術支持,為你分享千萬級在線用戶量的直播系統中實時彈幕功能的技術實踐,希望能帶給你啟發。

          [- 8 -] 企業微信的IM架構設計揭秘:消息模型、萬人群、已讀回執、消息撤回等

          [鏈接] http://www.52im.net/thread-3631-1-1.html

          [摘要] 本文總結了企業微信的IM消息系統架構設計,闡述了企業業務給IM架構設計帶來的技術難點和挑戰,以及技術方案的對比與分析。同時總結了IM后臺開發的一些常用手段,適用于IM消息系統。

          [- -]  融云IM技術分享:萬人群聊消息投遞方案的思考和實踐

          [鏈接] http://www.52im.net/thread-3687-1-1.html

          [摘要] 本文根據融云技術團隊的實踐經驗,總結了萬人群聊消息投遞方案的一些思考和實踐,希望能給你帶來啟發。

          [- 10 -] 實時社群技術專題(一):支持百萬人超級群聊,一文讀懂社群產品Discord

          [鏈接] http://www.52im.net/thread-4300-1-1.html

          [摘要] 本文為系列文章的首篇,文章內容不討論Discord具體的技術實現,僅從其產品定義的角度上對Discord軟件進行詳盡和具體的介紹,希望能幫助你對Discord從產品形態上有較為完整的認知,也方便你閱讀本系列文章的后續篇章。

          [- 11 -] 實時社群技術專題(二):百萬級成員實時社群技術實現(消息系統篇)

          [鏈接] http://www.52im.net/thread-4321-1-1.html

          [摘要] 本文是序列文章的第2篇,將要分享的是云信的實時社群產品“圈組”(“圈組”是云信的類Discord產品實現方案)的消息系統技術設計實踐。

          [- 12 -] 海量用戶IM聊天室的架構設計與實踐

          [鏈接] http://www.52im.net/thread-4404-1-1.html

          [摘要] 本文將分享網易云信針對海量用戶IM聊天室的架構設計與應用實踐,希望能帶給你啟發。

          ??52im社區本周新文:《陌陌技術分享:陌陌IM在后端KV緩存架構上的技術實踐》,歡迎閱讀!??

          我是Jack Jiang,我為自已帶鹽!https://github.com/JackJiang2011/MobileIMSDK/

          posted @ 2024-03-13 14:00 Jack Jiang 閱讀(66) | 評論 (0)編輯 收藏

               摘要: 本文由百度技術團隊分享,引用自百度Geek說,原題“千萬級高性能長連接Go服務架構實踐”,為了閱讀便利,本文進行了排版優化等。1、引言移動互聯網時代,長連接服務成為了提升應用實時性和互動性的基礎服務。本文將介紹百度基于golang實現的統一長連接服務,從統一長連接功能實現和性能優化等角度,描述了其在設計、開發和維護過程中面臨的問題和挑戰,并重點介紹了解決相關問題和挑戰的方案...  閱讀全文

          posted @ 2024-03-07 10:59 Jack Jiang 閱讀(115) | 評論 (0)編輯 收藏

          本文由ELab團隊公眾號授權發布,原題《Rust語言在IM客戶端的實踐》,來自抖音電商前端團隊的分享,本文有修訂和改動。

          1、引言

          本文將介紹飛鴿IM前端團隊如何結合Rust對飛鴿客戶端接待能力進行的技術提升,一步步從概念驗證、路徑分解到分工開發,再到最后上線收益論證,并分享了其中遇到的技術挑戰與經驗總結等。

          本項目是一個長周期的復雜項目,相信本項目落地的經驗對其他同學及團隊能有所借鑒。

           
           

          技術交流:

          - 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

          - 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK備用地址點此

          (本文已同步發布于:http://www.52im.net/thread-4620-1-1.html

          2、技術背景

          飛鴿是在抖音電商業務上面向商家和用戶的聊天工具,其拉通售前、售中、售后渠道,為商家履約提供重要支撐。

          對于飛鴿桌面端IM而言,我們會面臨很多基礎挑戰,比如做好會話穩定性、操作流暢性、冷啟動速度等,而在滿足98%以上的用戶需求且業務趨于穩定后,一些在沖刺后遺留的性能天花板問題暴露在我們面前,其中 高并發接待 & 多開是兩個重要的挑戰,是舊賬與難啃的硬骨頭。

          為何持續會有這些挑戰存在?

          1)歷史技術選型,包含者成本、人力、效率等考量,飛鴿客戶端使用的技術棧是react + electron:

          * im sdk與業務渲染代碼都由 js 編寫,im sdk同時是cpu密集型 & io 密集型的組件,在高并發場景下,渲染頻率也比較高,業務與sdk相互搶占cpu資源與io資源,導致收發消息慢、操作卡頓(高并發限制)。

          * 由于im sdk運行在webview中,所以收發消息依賴webview存活,故多開賬號 = 多個webview,內存成本線性增長。

          2)im頁面在web層面多次優化后已接近架構上限,無法基于現有架構做更多天花板的突破。

          對于以上這些挑戰,我們給出的解法是:對現有架構進行調整,使用Rust語言對im sdk進行重寫,徹底解除這一塊的性能瓶頸!

          3、為什么選Rust語言?

          飛鴿im sdk是一個對運行穩定性要求高的組件,其工程量大、邏輯復雜,對于異步特性使用非常頻繁,其對于內存安全、 線程安全有著比較嚴格的要求。

          假如使用C++,作為新手并沒有把握能夠將復雜的IM SDK少bug的編寫下來(團隊限制)。

          Rust學習曲線雖然陡峭,但是其為安全設計的各類語言特性、強大的編譯器,能夠將新人編寫代碼的問題數降到最低(邏輯問題除外)。

          并且飛書團隊提供了客戶端的rust生態庫,幫助我們解決很多的基建問題,所以這里使用Rust是相當合適的。

          Rust學習成長曲線:

          4、飛鴿IM客戶端歷史架構的問題

          如背景中所描述,歷史架構存在這兩個問題:

          • 1)IM SDK 與 業務JS代碼共用Weview資源,接待密集的時候,sdk與業務,互相搶占cpu與io資源,導致容易卡頓、消息延遲;
          • 2)多開的賬號必須依賴IM Webview存活(否則無法收到消息),內存線性增長。

          5、飛鴿IM客戶端新架構與預期目標

          具體是:

          • 1)Rust獨立進程承擔所有的im sdk的計算壓力,可以大幅減輕js線程壓力,可提升壓力場景接待體驗;
          • 2)Rust im SDK 解除瀏覽器中的IO限制(如同域名并發數限制);
          • 3)解除Webview存活依賴,依靠rust進程也可收消息,為更多賬號的多開能力提供了鋪墊。

          6、先用Rust進行技術可行性驗證

          為了驗證推測切實可行,我們提前做了完備的POC驗證。

          在POC中,我們針對“單進程單線程模型”、“多進程模型”、“多線程模型”,這三種模型搭建了mvp demo,即簡易的客服聊天模型,并進行壓力測試,并監測其內存、cpu等指標。

          通過POC,我們得出的結論是:

          具體就是:

          • 1)rust 整體優于 js,計算占比越重,優勢越明顯(高壓時cpu差別能到達3倍以上);
          • 2)架構選型上,rust進程獨立是最好的方案,穩定性更優、性能損耗相差較小。

          7、新架構開始實施

          路要一步步走,整個項目粗估下來會有上百的工作日,作為業務團隊,我們無法在短期內投入大量的資源去做這個項目,所以需要一步一步拆解、驗證、拿收益。

          團隊內native開發資源有限,這件事情的進行也需要團隊進行學習、成長。下面我們將詳細分享這個過程 。

          8、新架構實施階段1:Rust SDK工程基建

          造房子先得有一個地基 —— Rust工程的基礎建設,是Native業務的前置條件!

          桌面端同學牽頭搭建了整個RustSDK地基,地基解決的問題如下圖所示:

          需要做的工作:

          • 1)業務容器:有規律的組織代碼結構,進行業務隔離、資源隔離;
          • 2)跨進程調用封裝:降低業務調用難度;
          • 3)建設日志系統、日志回撈:降低排查問題的難度;
          • 4)構建跨平臺異步執行環境:簡化異步代碼編寫,底層封裝,便于跨平臺代碼遷移;
          • 5)跨平臺編譯,跨平臺集成;
          • 6)... ...

          9、新架構實施階段2:IM基礎能力夯實

          在擁有一部分地基后,我們開始針對IM SDK的基礎能力進行實現和驗證。

          因為只有完成基礎能力驗證之后,我們才會有信心在新的架構上疊加更多的功能。

          這階段我們關注以下指標( 希望其存在優化,至少不劣化):

          • 1)長鏈在線率;
          • 2)消息發送成功率;
          • 3)卡頓率;
          • 4)Rust進程崩潰率、無響應率。

          僅實現長鏈能力下沉,驗證&提升其穩定:

          本階段論證結果如下:

          • 1)Rust Crash率, 達成預期;
          • 2)Rust無響應率 - 未達預期,可優化;
          • 3)長鏈在線率 - 達成預期,但是存在優化空間;
          • 4)卡頓率 - 不劣化 達成預期;
          • 5)消息發送成功率 - 不劣化,達成預期。

          這階段的工作是考驗耐心的,因為這個階段并不能帶來實質性的用戶體驗提升、也無法拿到明顯的提升數據,只是作為中間階段,它有存在的必要性。

          這階段后,在穩定性治理、基礎能力驗證、 Rust 語言經驗、指標制定合理性這幾方面,我們踩上了一個更結實的臺階,更有信心去進行更復雜的下一階段。

          10、 新架構實施階段3:使用Rust實現IM SDK全部能力

          夯實基礎后,我們開始發力沖刺,大刀闊斧的對IM SDK進行重新設計、實現、聯調以及上線。

          此階段要實現im sdk的全部能力、 并對線上運行的js im sdk進行替換。

          由于飛鴿im對于通信模塊的穩定程度要求是很高的,替換過程就像是在高速行駛的車輛上替換輪胎,如果出現問題也容易導致大量的客服負面反饋。

          因此,新rust sdk的穩定性、異常問題時的兜底方案、灰度時的監控觀察、對新增反饋的留意都很重要,放量過程會存在一定精神壓力。

          工作內容大致如下。

          1)多實例的Rust IM SDK設計(商家單聊、群聊、平臺客服)、Js -> Rust IMSDK跨端調用協議設計:

          • a)分析、拆解所有Js Im SDK至今具有的能力,并以貼合Rust的方式重新設計;
          • b)需要在協議設計中,盡可能的合并 & 簡化 Js -> Rust的調用,以減少IPC通信成本。

          2)開發:

          • a)Rust IM SDK核心實現;
          • b)Rust\Js適配同學緊密合作,根據協議進行業務實現、業務適配;
          • c)密切溝通,發現問題及時糾偏;
          • d)編寫單測;

          3)測試:

          • a)各類IM場景回歸測試;
          • b)性能進行驗證。

          4)異常兜底方案實現:

          設計數據冗余,當Rust進程出現崩潰、無響應、不可恢復的網絡錯誤時,識別并fallback到 web版本,使用冗余數據快速恢復im sdk正常運行狀態,確保用戶體驗。

          5)穩妥的上線方案 & 穩定性治理。

          6)調用&適配優化,結合Native能力進一步性能優化。

          7)結果回收。

          8)其中各個步驟都會存在一些挑戰,在后后面的內容會提到。

          調用簡化模型:

          IM Core簡化模型:

          11、新架構實施階段4:基于穩定的RustIM SDK實現形態升級

          最后的階段,我們基于完善的Rust IM SDK的能力進行形態的升級。

          本階段正在進行中,完成后會做更多的分享。

          1)多窗口改造:銷毀后臺的多開賬號,讓多開賬號數量突破到25個。

           

          2)消息提醒、通知流程改造。

          3)消息本地化能力:加快消息上屏。

          12、技術挑戰與實踐總結

          12.1編程語言 & IM領域知識突破

          一個有戰斗力的團隊,一定是持續學習、進步的。

          比如:

          • 1)獲取學習的純粹快樂:當沉浸在學習中,并感受到自己在進步的時候,會是一個快樂的狀態;
          • 2)逐步克服小挑戰,及時獲得正反饋;
          • 3)在同事中找到伙伴和老師,詢問與探討:建立團隊中的學習氛圍。

           

          12.2長周期技術項目,如何持續保持信心 ?

          比如 :

          • 1)Leader與同事認可與支持 — 團隊基礎、價值觀鼓勵;
          • 2)關注長期收益,訓練自己延遲滿足感;
          • 3)做好階段性分解與驗證,縮短單個周期(如本文的一二階段拆解,可逐步累積信心);
          • 4)增強自身實力,做好問題把控,及時發現&解決問題。

           

          12.3高效合作

          團隊Native開發同學少,且各自并行業務需求,需合理的安排開發路線,減少總開發時長。

           
          • 1)合理的設計開發并行路線,減少串行依賴
          • 2)協議與接口先行;
          • 3)各同學負責其相近&擅長的部分;
          • 4)聯調時縮短彼此距離,高效溝通。

           

          12.4保障用戶體驗的灰度上線

          1)編寫模塊的健康自檢,檢測到異常時用最小的代價切換備用老方案。

          2)完善業務監控&技術指標監控:crash率、無響應率、長鏈在線率、發消息成功率、請求成功率、卡頓率等。

          3)對真實用戶使用體驗進行跟蹤:

          • a)書反饋群組維護,及時獲得用戶反饋;
          • b)與商家客服保持線下聯系,獲取一手體驗情況。

          4)放量節奏的把控:

          • a)大型改動可以先給白名單用戶試用,收集反饋;
          • b)放出能夠識別問題的量,解決問題后再繼續放量;
          • c)放量期間主動查詢用戶實時反饋數據,有問題及時解決。

           

          12.5如何減少IPC通信成本帶來的開銷

          頻率過高的IPC通信可能使得CPU優化適得其反,因為老版本都運行在Js中,所以調用頻率是沒有節制的(循環讀取數據也經常出現),必須要在設計上降低下來——降低業務JS線程的壓力。

          以下措施可以將本場景通信成本降低90%以上。

          1)更高效的數據協議 protobuf:相較于json,數據更小、解析和序列化性能更高、跨語言生成代碼工具。

          2)Rust push to js:使用數據收集去重 + debounce批量更新的策略,合并多個數據回調接口,減少通信頻率。

          3)Js call rust(單次基礎耗時4ms):

          • a)適當緩存數據,不用每次都回源查詢;
          • b)需要頻繁調用的邏輯下沉Rust,Rust邏輯自完善。

          12.6結果回收:極端場景下的優化大盤數據體現不明顯

           

          針對某種場景做的優化工作不容易在大盤數據中得到體現(尤其在灰度階段),我們應該針對特殊場景建立新指標。

          即編寫策略,識別并收集極端場景下的數據:為了衡量極端場景的的卡頓優化,建立了忙碌與卡頓指標,可以衡量出用戶接待忙碌程度與卡頓率的關系,并且通過此指標將優化清晰的衡量出來。

          12.7Rust SDK的問題治理

          具體是:

          • 1)前期的問題不穩定,需更多信息輔助排查,日志盡量完整;
          • 2)與真實用戶群體保持聯系,可加快問題驗證、問題發現的過程;
          • 3)需要建設便捷的日志回撈 & 日志分析工具(幫助快速找到日志還原現場)。

          13、新架構帶來的收益

          壓力評測:

          數據表現:

          解讀一下:

          • 1)客服發送消息,大盤端到端耗時降低 40%;
          • 2)消息發送成功率三個9 -> 四個9;
          • 3)im頁面大盤卡頓率降低 15%;
          • 4)密集接待場景,卡頓率降低 50%。

          全量至今,再無大量進線導致卡頓的反饋。回訪歷史反饋用戶,皆無因大量接待導致的卡頓現象

          14、相關文章

          [1] 阿里技術分享:閑魚IM基于Flutter的移動端跨端改造實踐

          [2] IM開發干貨分享:有贊移動端IM的組件化SDK架構設計實踐

          [3] IM開發干貨分享:我是如何解決大量離線消息導致客戶端卡頓的

          [4] 如約而至:微信自用的移動端IM網絡層跨平臺組件庫Mars已正式開源

          [5] 從客戶端的角度來談談移動端IM的消息可靠性和送達機制

          [6] IM開發干貨分享:IM客戶端不同版本兼容運行的技術思路和實踐總結

          [7] IM全文檢索技術專題(四):微信iOS端的最新全文檢索技術優化實踐

          [8] 從游擊隊到正規軍(二):馬蜂窩旅游網的IM客戶端架構演進和實踐總結

          [9] IM跨平臺技術學習(九):全面解密新QQ桌面版的Electron內存優化實踐

          [10] IM跨平臺技術學習(五):融云基于Electron的IM跨平臺SDK改造實踐總結

          [11] 抖音技術分享:抖音Android端手機功耗問題的全面分析和詳細優化實踐

          [12] 社交軟件紅包技術解密(十二):解密抖音春節紅包背后的技術設計與實踐


          (本文已同步發布于:http://www.52im.net/thread-4620-1-1.html

          posted @ 2024-02-29 10:26 Jack Jiang 閱讀(91) | 評論 (0)編輯 收藏

          為了更好地分類閱讀 52im.net 總計1000多篇精編文章,我將在每周三推送新的一期技術文集,本次是第34 期。

          [- 1 -] 快速裂變:見證微信強大后臺架構從0到1的演進歷程(一)

          [鏈接] http://www.52im.net/thread-168-1-1.html

          [摘要] 2個月的開發時間,微信后臺系統經歷了從0到1的過程。從小步慢跑到快速成長,經歷了平臺化到走出國門,微信交出的這份優異答卷,解題思路是怎樣的?


          [- 2 -] 如何保證IM實時消息的“時序性”與“一致性”?

          [鏈接] http://www.52im.net/thread-714-1-1.html

          [摘要] 實時消息時序和一致性是分布式系統架構設計中非常難的問題(尤其IM應用這種以消息為中心的應用形態),困難在哪?有什么常見優化實踐?這就是本文要討論的內容。


          [- 3 -] IM單聊和群聊中的在線狀態同步應該用“推”還是“拉”?

          [鏈接] http://www.52im.net/thread-715-1-1.html

          [摘要] “用戶在線狀態的一致性”(單聊好友在線狀態、群聊用戶在線狀態)是IM應用領域比較難解決的一個技術問題,如何精準實時的獲得好友、群友的在線狀態,是今天將要探討的話題。


          [- 4 -]IM群聊消息如此復雜,如何保證不丟不重?

          [鏈接] http://www.52im.net/thread-753-1-1.html

          [摘要] 由于“消息風暴擴散系數”的存在(概念詳見《IM單聊和群聊中的在線狀態同步應該用“推”還是“拉”?》),群消息的復雜度要遠高于一對一的單聊消息。群消息的實時性、可達性、離線消息是今天將要討論的核心話題。


          [- 5 -] 微信后臺團隊:微信后臺異步消息隊列的優化升級實踐分享

          [鏈接] http://www.52im.net/thread-801-1-1.html

          [摘要] 本文分享了該組件2.0版本的功能特點及優化實踐,希望能為類似業務(比如移動端IM系統等)的消息隊列設計提供一定的參考。


          [- -] 移動端IM中大規模群消息的推送如何保證效率、實時性?

          [鏈接] http://www.52im.net/thread-1221-1-1.html

          [摘要] 當然,實際在生產環境下,群消息的發送都會想盡辦法進行壓縮,并開展各種改善性能的處理辦法,而不是像上述舉例里的直接擴散寫(即2000人群里,一條消息被簡單地復制為2000條一對一的消息投遞)。具體有哪些優先策略?本文或許可以帶給你一些啟發。


          [- 7 -] 現代IM系統中聊天消息的同步和存儲方案探討

          [鏈接] http://www.52im.net/thread-1230-1-1.html

          [摘要] 本文內容主要涉及IM系統中的消息系統架構,探討一種適用于大用戶量的消息同步以及存儲系統的架構實現,能夠支持消息系統中的高級特性『多端同步』以及『消息漫游』。在性能和規模上,能夠做到全量消息云端存儲,百萬TPS以及毫秒級延遲的消息同步能力。


          [- 8 -] 關于IM即時通訊群聊消息的亂序問題討論

          [鏈接] http://www.52im.net/thread-1436-1-1.html

          [摘要] 問題描述:客戶端A、B、C,服務端S,例如:A發三條群消息,B、C收到的消息都是亂序,目前問題:A發第一條消息失敗之后排到隊列,這時服務端還在持續發消息,那么第二條消息送達到B、C,然后客戶端最先顯示的就不是第一條消息,導致亂序出現。


          [- 9 -]  IM群聊消息的已讀回執功能該怎么實現?

          [鏈接] http://www.52im.net/thread-1611-1-1.html

          [摘要] 那么群聊消息的收發流程、消息的送達保證、已讀回執機制,到底該怎么實現呢?這就是今天要討論的話題。


          [- 10 -] IM群聊消息究竟是存1份(即擴散讀)還是存多份(即擴散寫)?

          [鏈接] http://www.52im.net/thread-1616-1-1.html

          [摘要] 任何技術方案,都不是天才般靈感乍現想到的,一定是一個演進迭代,逐步優化的過程。今天就聊一聊,IM群聊消息,為啥只需要存一份。


          [- 11 -] 一套高可用、易伸縮、高并發的IM群聊、單聊架構方案設計實踐

          [鏈接] http://www.52im.net/thread-2015-1-1.html

          [摘要] 本文將分享的是一套生產環境下的IM群聊消息系統的高可用、易伸縮、高并發架構設計實踐,屬于原創第一手資料,內容較專業,適合有一定IM架構經驗的后端程序員閱讀。


          [- 12 -] [技術腦洞] 如果把14億中國人拉到一個微信群里技術上能實現嗎?

          [鏈接] http://www.52im.net/thread-2017-1-1.html

          [摘要] 聽到這個問題,全廠的人都炸了。要知道一個微信群最多只能有500人啊,QQ群也只有2000而已。當你有機會加入一個2000人QQ群的時候,你就已經感受到“信息爆炸”的可怕……


          [- 13 -] IM群聊機制,除了循環去發消息還有什么方式?如何優化?

          [鏈接] http://www.52im.net/thread-2213-1-1.html

          [摘要] 目前我是用循環來獲取群成員,然后獲取群成員ID去循環調用senddata()方法,想不用循環或者用其他什么方式來優化群聊循環發送這個機制,各位大佬有什么辦法沒?


          [- 14 -] 網易云信技術分享:IM中的萬人群聊技術方案實踐總結

          [鏈接] http://www.52im.net/thread-2707-1-1.html

          [摘要] 本文內容是網易云信團隊為了響應萬人群聊功能需求,在設計實現萬人群聊技術方案中總結的技術實踐,借此機會分享給各IM開發者同行。


          [- 15 -] 阿里釘釘技術分享:企業級IM王者——釘釘在后端架構上的過人之處

          [鏈接] http://www.52im.net/thread-2848-1-1.html

          [摘要] 本文適合有一定IM后端架構設計經驗的開發者閱讀,或許出于商業產品技術秘密的考慮,分享者在本次所分享的內容上有所保留,鑒于阿里對于釘釘在技術上的內容分享做的非常少,所以本文雖然內容不夠全面,但仍然值得一讀。


          ??52im社區本周新文:《抖音技術分享:飛鴿IM桌面端基于Rust語言進行重構的技術選型和實踐總結》,歡迎閱讀!??

          我是Jack Jiang,我為自已帶鹽!https://github.com/JackJiang2011/MobileIMSDK/

          posted @ 2024-02-28 13:19 Jack Jiang 閱讀(114) | 評論 (0)編輯 收藏

          僅列出標題
          共50頁: First 上一頁 5 6 7 8 9 10 11 12 13 下一頁 Last 
          Jack Jiang的 Mail: jb2011@163.com, 聯系QQ: 413980957, 微信: hellojackjiang
          主站蜘蛛池模板: 涿州市| 措美县| 顺昌县| 定远县| 镇平县| 塔河县| 定安县| 资阳市| 淮安市| 乳山市| 博白县| 永兴县| 余干县| 龙井市| 榆社县| 曲水县| 新邵县| 封开县| 阳泉市| 佛学| 天水市| 宜宾市| 林口县| 苍溪县| 大邑县| 柘城县| 灵丘县| 武城县| 甘德县| 福州市| 神农架林区| 道孚县| 彰化市| 郁南县| 手游| 云林县| 怀柔区| 柳林县| 徐水县| 青铜峡市| 桃园市|