IM開發(fā)干貨分享:淺談IM系統(tǒng)中離線消息符匾、歷史消息的最佳實(shí)踐

本文由融云技術(shù)團(tuán)隊(duì)原創(chuàng)分享叨咖,原題“IM 消息數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)設(shè)計(jì)”,內(nèi)容有修訂啊胶。

1甸各、引言

在如今的移動(dòng)互聯(lián)網(wǎng)時(shí)代,IM類產(chǎn)品已是我們生活中不可或缺的組成部分焰坪。像微信趣倾、釘釘、QQ等是典型的以 IM 為核心功能的社交產(chǎn)品某饰。另外也有一些應(yīng)用雖然IM功能不是核心儒恋,但I(xiàn)M能力也是其整個(gè)應(yīng)用極其重要的組成部分善绎,比如在線游戲、電商直播等應(yīng)用诫尽。

在IM技術(shù)應(yīng)用場(chǎng)景越來越廣泛的前提下禀酱,對(duì)即時(shí)通訊IM技術(shù)的學(xué)習(xí)和掌握就顯的越來越有必要。

在IM龐大的技術(shù)體系中箱锐,消息系統(tǒng)無疑是最核心的比勉,而消息系統(tǒng)中,最關(guān)鍵的部分是消息的分發(fā)和存儲(chǔ)驹止,而離線消息和歷史消息又是這個(gè)關(guān)鍵環(huán)節(jié)中不可回避的技術(shù)要點(diǎn)浩聋。

本文將基于IM消息系統(tǒng)的技術(shù)實(shí)踐,分享關(guān)于離線消息和歷史消息的正確理解臊恋,以及具體的技術(shù)配合和實(shí)踐衣洁,希望能為你的離線消息和歷史消息技術(shù)設(shè)計(jì)帶來最佳實(shí)踐靈感。

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

2抖仅、相關(guān)文章

技術(shù)相關(guān)文章:

什么是IM系統(tǒng)的可靠性坊夫?

閑魚IM的在線、離線聊天數(shù)據(jù)同步機(jī)制優(yōu)化實(shí)踐

閑魚億級(jí)IM消息系統(tǒng)的可靠投遞優(yōu)化實(shí)踐

一套億級(jí)用戶的IM架構(gòu)技術(shù)干貨(下篇):可靠性撤卢、有序性环凿、弱網(wǎng)優(yōu)化等

IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(二):保證離線消息的可靠投遞

我是如何解決大量離線消息導(dǎo)致客戶端卡頓的

融云技術(shù)團(tuán)隊(duì)分享的其它文章:

融云安卓端IM產(chǎn)品的網(wǎng)絡(luò)鏈路保活技術(shù)實(shí)踐

全面揭秘億級(jí)IM消息的可靠投遞機(jī)制

解密融云IM產(chǎn)品的聊天消息ID生成策略

萬人群聊消息投遞方案的思考和實(shí)踐

基于WebRTC的實(shí)時(shí)音視頻首幀顯示時(shí)間優(yōu)化實(shí)踐

融云IM技術(shù)分享:萬人群聊消息投遞方案的思考和實(shí)踐

3放吩、IM消息投遞的一般做法

在通常的IM消息系統(tǒng)中智听,對(duì)于實(shí)時(shí)消息、離線消息渡紫、歷史消息大概都是下面這樣的技術(shù)思路到推。

對(duì)于在線用戶:消息會(huì)直接實(shí)時(shí)發(fā)送到在線的接收方,消息發(fā)送完成后惕澎,服務(wù)器端并不會(huì)對(duì)消息進(jìn)行落地存儲(chǔ)莉测。

而對(duì)于離線的用戶:服務(wù)器端會(huì)將消息存入到離線庫(kù),當(dāng)用戶登錄后唧喉,從離線庫(kù)中將離線消息拉走捣卤,然后服務(wù)器端將離線消息刪除。

這樣實(shí)現(xiàn)的缺點(diǎn)就是消息不持久化欣喧,導(dǎo)致消息無法支持消息漫游腌零,降低了消息的可靠性。

PS:實(shí)際上唆阿,這其實(shí)也不能算是缺點(diǎn)益涧,因?yàn)橐恍﹫?chǎng)景下存儲(chǔ)歷史消息并不是必須的,所謂的消息漫游能力也不是必備的驯鳖,比如微信闲询。)

而在我們?cè)O(shè)計(jì)的消息系統(tǒng)中久免,服務(wù)器只要接收到了發(fā)送方發(fā)上來的消息,在轉(zhuǎn)發(fā)給接收方的同時(shí)也會(huì)在離線數(shù)據(jù)庫(kù)及歷史消息庫(kù)中進(jìn)行消息的落地存儲(chǔ)扭弧,而歷史消息的落地也就能支持消息漫游等相關(guān)功能了阎姥。

4、什么是離線消息和歷史消息鸽捻?

關(guān)于離線消息和歷史消息呼巴,在技術(shù)上,我們是這樣定義御蒲。

1)離線消息:

離線消息就是用戶(即接收方)在離線過程中收到的消息衣赶,這些消息大多是用戶比較關(guān)心的消息,具有一定的時(shí)效性厚满。

以我們的系統(tǒng)經(jīng)驗(yàn)來說府瞄,我們的離線消息默認(rèn)只保存最近七天的消息。

用戶(即接收方)在下次登錄后會(huì)全量獲取這些離線消息碘箍,然后在客戶端根據(jù)聊天會(huì)話進(jìn)行離線消息的UI展示(比如顯示一個(gè)未讀消息氣泡等)遵馆。

PS:用戶離線的可能性在技術(shù)上其實(shí)是由很多種情況組成的,比如對(duì)方不在線丰榴、對(duì)方網(wǎng)絡(luò)斷掉了货邓、對(duì)方手機(jī)崩潰了、服務(wù)器發(fā)送時(shí)出錯(cuò)了等等四濒,嚴(yán)格來講——只要無法實(shí)時(shí)發(fā)送成的消息逻恐,都算“離線消息”。)

2)歷史消息:

歷史消息存儲(chǔ)了用戶所有的聊天消息峻黍,這些消息包括發(fā)出的消息以及接收到的消息。

在客戶端獲取歷史消息時(shí)拨匆,通常是按照會(huì)話進(jìn)行分頁獲取的姆涩。

以我們的系統(tǒng)經(jīng)驗(yàn)來說,歷史消息的存儲(chǔ)時(shí)間我們?cè)O(shè)計(jì)默認(rèn)為半年惭每,當(dāng)然這個(gè)時(shí)間可以按實(shí)際的產(chǎn)品運(yùn)營(yíng)規(guī)則來定骨饿,沒有硬性規(guī)定。

5台腥、IM消息的發(fā)送及存儲(chǔ)流程

以下是我們系統(tǒng)整體的消息發(fā)送及存儲(chǔ)流程:

如上圖所示:當(dāng)用戶發(fā)送聊天消息到服務(wù)器端后宏赘,首先會(huì)進(jìn)入到消息系統(tǒng)中,消息系統(tǒng)會(huì)對(duì)消息進(jìn)行分發(fā)以及存儲(chǔ)黎侈。

這個(gè)過程中:對(duì)于在線的接收方察署,會(huì)選擇直接推送消息。但是遇到接收方不在線或者是消息推送失敗的情況下峻汉,也會(huì)有另外的消息獲取方式贴汪,比如接收方會(huì)主動(dòng)向服務(wù)器拉取未收到的消息脐往。但是接收方何時(shí)來服務(wù)器拉取消息以及從哪里拉取是未知的,所以消息存入到離線庫(kù)的意義也就在這里扳埂。

消息系統(tǒng)存儲(chǔ)離線的過程中业簿,為了不影響整個(gè)系統(tǒng)的更為平穩(wěn),我們使用了MQ消息隊(duì)列進(jìn)行IO解偶阳懂,所以聊天消息實(shí)際上是異步存入到離線庫(kù)中的(通過MQ進(jìn)行慢IO解偶梅尤,這其實(shí)也是慣常做法)。

在分發(fā)完消息后:消息服務(wù)會(huì)同步一份消息數(shù)據(jù)到歷史消息服務(wù)中岩调,歷史消息服務(wù)同樣會(huì)對(duì)消息進(jìn)行落地存儲(chǔ)巷燥。

對(duì)于新的客戶端設(shè)備:會(huì)有同步消息的需求(所謂的消息漫游能力),而這也正是歷史消息的主要作用誊辉。在歷史消息庫(kù)中矾湃,客戶端是可以拉取任意會(huì)話的全量歷史消息的。

6堕澄、IM離線消息邀跃、歷史消息在存儲(chǔ)邏輯上的區(qū)別

6.1 概述

通過上面的圖中能清晰的看到:

1)離線消息我們存儲(chǔ)介質(zhì)選用的是?Redis

2)歷史消息我們選用的是?HBase蛙紫。

對(duì)于為什么選用不同的存儲(chǔ)介質(zhì)拍屑,其實(shí)我們考慮的是離線消息和歷史消息不同的業(yè)務(wù)場(chǎng)景和讀寫模式。

下面我們重點(diǎn)介紹一下離線消息和歷史消息存儲(chǔ)的區(qū)別坑傅。

6.2 離線消息存儲(chǔ)模式——“擴(kuò)散寫”

離線消息的存儲(chǔ)模式我們用的是擴(kuò)散寫僵驰。

如上圖所示:每個(gè)用戶都有自己?jiǎn)为?dú)的收件箱和發(fā)件箱:

1)收件箱存放的是需要向這個(gè)接收端同步的所有消息;

2)發(fā)件箱里存放的是發(fā)送端發(fā)出的所有消息唁毒。

以單聊為例:聊天中的兩人會(huì)話中蒜茴,消息會(huì)產(chǎn)生兩次寫,即發(fā)送者的發(fā)件箱和接收端的收件箱浆西。

而在群的場(chǎng)景下:寫入會(huì)被更加的放大(擴(kuò)散)粉私,如果群里有 N 個(gè)人,那一條群消息就會(huì)被擴(kuò)散寫 N 次近零。

小結(jié)一下:

1)擴(kuò)散寫的優(yōu)點(diǎn)是:接收端的邏輯會(huì)非常清晰簡(jiǎn)單诺核,只需要從收件箱里讀取一次即可,大大降低了同步消息所需的讀的壓力久信;

2)擴(kuò)散寫的缺點(diǎn)是:寫入會(huì)被成指數(shù)地放大窖杀,特別是針對(duì)群這種場(chǎng)景。

6.3 歷史消息存儲(chǔ)模式——“擴(kuò)散讀”

歷史消息的存儲(chǔ)模式我們用的是擴(kuò)散讀裙士。

因?yàn)闅v史消息中入客,每個(gè)會(huì)話都保存了整個(gè)會(huì)話的全量消息。在擴(kuò)散讀這種模式下,每個(gè)會(huì)話的消息只保存一次痊项。

對(duì)比擴(kuò)散寫模式锅风,擴(kuò)散讀的優(yōu)點(diǎn)和缺點(diǎn)如下:

1)優(yōu)點(diǎn)是:寫入次數(shù)大大降低,特別是針對(duì)群消息鞍泉,只需要存一次即可皱埠;

2)缺點(diǎn)是:接收端接收消息非常的復(fù)雜和低效,因?yàn)檫@種模式客戶端想拉取到所有消息就只能每個(gè)會(huì)話同步一次咖驮,讀就會(huì)被放大边器,而且可能會(huì)產(chǎn)生很多次無效的讀,因?yàn)橛行?huì)話可能根本沒有新消息托修。

6.4 小結(jié)

在 IM 這種應(yīng)用場(chǎng)景下忘巧,通常會(huì)用到擴(kuò)散寫這種消息同步模型,一條消息產(chǎn)生一條睦刃,但是可能會(huì)被讀多次砚嘴,是典型的讀多寫少的場(chǎng)景

一個(gè)優(yōu)化好的IM系統(tǒng)涩拙,必須從設(shè)計(jì)上平衡讀寫壓力际长,避免讀或者寫任意一個(gè)維度達(dá)到天花板。

當(dāng)然擴(kuò)散寫這種模式也有其弊端兴泥,比如萬人群工育,會(huì)導(dǎo)致一條消息,寫入了一萬次搓彻。

綜合來講:我們需要根據(jù)自己的業(yè)務(wù)場(chǎng)景做相應(yīng)設(shè)計(jì)選擇如绸,以我們的IM系統(tǒng)為例,就是是根據(jù)了離線和歷史消息的不同場(chǎng)景選擇了寫擴(kuò)散和讀擴(kuò)散的組合模式旭贬。適合的才是最好的怔接,沒有必要死搬硬套理論。

7稀轨、IM客戶端的拉取消息邏輯

7.1 離線消息拉取邏輯

對(duì)于IM客戶端而言蜕提,離線消息的獲取針對(duì)的是自己的整個(gè)離線消息,包括所有的會(huì)話(直白了說靶端,就是上線時(shí)拉取此次離線過程中的所有未收取的離線消息)。

離線消息的獲取是自上而下的方式(按時(shí)間序)凛膏,我們的經(jīng)驗(yàn)是一次獲取 200 條(PS:如果離線消息過多杨名,會(huì)分頁多次拉取,拉取1“次”可以理解為拉取1“頁”)猖毫。

在客戶端拉取離線消息的信令中台谍,需要帶上當(dāng)前客戶端緩存的消息的最大時(shí)間戳

通過上節(jié)的圖我們應(yīng)該知道吁断,離線消息我們存儲(chǔ)的是一個(gè)線性結(jié)構(gòu)(指的是按時(shí)間順序)趁蕊,Server 會(huì)根據(jù)這個(gè)時(shí)間戳向下查找離線消息坞生。當(dāng)重裝或者新安裝 App 時(shí),客戶端的“當(dāng)前客戶端緩存的消息的最大時(shí)間戳”可以傳 0 上來掷伙。

Server 也會(huì)緩存客戶端拉取到的最后一條消息的時(shí)間戳是己,然后根據(jù)業(yè)務(wù)場(chǎng)景,客戶端類型等因素來決定從哪里開始拉取任柜,如果沒有拉取完 Server 會(huì)在拉取消息的應(yīng)答中帶相應(yīng)的標(biāo)記位卒废,告訴客戶端繼續(xù)拉取,客戶端循環(huán)拉取宙地,直到所有離線消息拉完摔认。

7.2 歷史消息拉取邏輯

歷史消息的獲取通常針對(duì)的是單一會(huì)話。

在拉取過程中宅粥,需要向服務(wù)端提交兩個(gè)參數(shù):

1)對(duì)方的 ID(如果是單聊的話就是對(duì)方的 UserID参袱,如果是群則是群組ID);

2)當(dāng)前會(huì)話的最前面消息的時(shí)間戳(即當(dāng)前會(huì)話最老一條消息的時(shí)間戳)秽梅。

Server據(jù)這兩個(gè)參數(shù)抹蚀,可以定位到這個(gè)客戶端的此會(huì)話,然后一次獲取 20 條歷史消息风纠。

消息的拉取時(shí)序上采用的是自下而上的方式(也就是時(shí)間序逆序)况鸣,即從最后面往前翻。只要有消息竹观,客戶端可以一直向前翻镐捧,手動(dòng)觸發(fā)獲取會(huì)話的歷史消息。

上面的拉取邏輯臭增,在IM界面功能上通常對(duì)應(yīng)的是下拉或點(diǎn)擊“加載更多”懂酱,比如這樣:

8、本文小結(jié)

本文主要分享了IM中有關(guān)離線消息和歷史消息的正確誊抛,主要包括離線消息和歷史消息的區(qū)別列牺,以及二者在存儲(chǔ)、分發(fā)拗窃、拉取邏輯方面的最佳踐等瞎领。如對(duì)文中內(nèi)容有異議,歡迎留言討論随夸。

9九默、參考資料

[1]?一套海量在線用戶的移動(dòng)端IM架構(gòu)設(shè)計(jì)實(shí)踐分享(含詳細(xì)圖文)

[2]?一套原創(chuàng)分布式即時(shí)通訊(IM)系統(tǒng)理論架構(gòu)方案

[3]?從零到卓越:京東客服即時(shí)通訊系統(tǒng)的技術(shù)架構(gòu)演進(jìn)歷程

[4]?一套億級(jí)用戶的IM架構(gòu)技術(shù)干貨(上篇):整體架構(gòu)、服務(wù)拆分等

[5]?閑魚億級(jí)IM消息系統(tǒng)的架構(gòu)演進(jìn)之路

[6]?閑魚億級(jí)IM消息系統(tǒng)的可靠投遞優(yōu)化實(shí)踐

[7]?閑魚億級(jí)IM消息系統(tǒng)的及時(shí)性優(yōu)化實(shí)踐

[8]?基于實(shí)踐:一套百萬消息量小規(guī)模IM系統(tǒng)技術(shù)要點(diǎn)總結(jié)

[9]?IM消息送達(dá)保證機(jī)制實(shí)現(xiàn)(一):保證在線實(shí)時(shí)消息的可靠投遞

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

[11]?零基礎(chǔ)IM開發(fā)入門(一):什么是IM系統(tǒng)驼修?

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子乙各,更是在濱河造成了極大的恐慌墨礁,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件耳峦,死亡現(xiàn)場(chǎng)離奇詭異恩静,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)妇萄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門蜕企,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人冠句,你說我怎么就攤上這事轻掩。” “怎么了懦底?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵唇牧,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我聚唐,道長(zhǎng)丐重,這世上最難降的妖魔是什么杆查? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任扮惦,我火速辦了婚禮,結(jié)果婚禮上亲桦,老公的妹妹穿的比我還像新娘崖蜜。我一直安慰自己,他們只是感情好客峭,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布豫领。 她就那樣靜靜地躺著,像睡著了一般舔琅。 火紅的嫁衣襯著肌膚如雪等恐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天备蚓,我揣著相機(jī)與錄音课蔬,去河邊找鬼。 笑死郊尝,一個(gè)胖子當(dāng)著我的面吹牛购笆,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播虚循,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了横缔?” 一聲冷哼從身側(cè)響起铺遂,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎茎刚,沒想到半個(gè)月后襟锐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡膛锭,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年粮坞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片初狰。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡莫杈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出奢入,到底是詐尸還是另有隱情筝闹,我是刑警寧澤,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布腥光,位于F島的核電站关顷,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏武福。R本人自食惡果不足惜议双,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捉片。 院中可真熱鬧平痰,春花似錦、人聲如沸界睁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽翻斟。三九已至逾礁,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間访惜,已是汗流浹背嘹履。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留债热,地道東北人砾嫉。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像窒篱,于是被迫代替她去往敵國(guó)和親焕刮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子舶沿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容