日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問(wèn)題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷(xiāo)解決方案
群消息,究竟存1份還是多份?

群消息,究竟存一份還是多份?

任何技術(shù)方案,都不是天才般靈感乍現(xiàn)想到的,一定是一個(gè)演進(jìn)迭代,逐步優(yōu)化的過(guò)程。今天就聊一聊,群消息,為啥只需要存一份。

群信息,用戶信息,群成員關(guān)系都是基礎(chǔ)數(shù)據(jù):

 
 
 
 
  1. group_info(gid, group_info); 
  2. user_info(uid, user_info); 
  3. group_members(gid, uid); 

假設(shè)一個(gè)群(gid)里有4個(gè)成員,其中:

  • 三個(gè)在線(A, uid1, uid2);
  • 一個(gè)不在線(uid3);

A發(fā)送了一條消息,很容易想到,對(duì)于不同的群友消息存多份,每個(gè)群友一個(gè)隊(duì)列來(lái)存儲(chǔ)。但由于在線的用戶會(huì)實(shí)時(shí)的收到消息,所以暫定只為離線的用戶存儲(chǔ)。

用戶收到的群消息,也是基礎(chǔ)數(shù)據(jù):

 
 
 
 
  1. user_msgs(uid,msgid,gid,sender_uid,time,content); 

很容易想到,整個(gè)群消息的發(fā)送流程如上圖1-4:

  • 發(fā)送消息;
  • 查詢狀態(tài);
  • 不在線的存儲(chǔ)離線;
  • 在線的實(shí)時(shí)推送;

“在線的群友不存儲(chǔ),離線的群友才存儲(chǔ)”會(huì)帶來(lái)的問(wèn)題是,如果第四步發(fā)生異常,群友會(huì)丟失消息。

消息的可達(dá)性是聊天系統(tǒng)中最重要的要素(沒(méi)有之一),故這個(gè)方案是不行的,需要優(yōu)化為“不管是否在線,都要先存儲(chǔ)”。

發(fā)送群消息的流程優(yōu)化為,如上圖1-4:

  • 發(fā)送消息;
  • 所有人都存一份;
  • 查詢狀態(tài);
  • 在線的實(shí)時(shí)推送;

先將消息落地,能夠保證消息可達(dá)性,那何時(shí)才能刪除已經(jīng)落地的群消息呢?

對(duì)于在線的群友,收到群消息后,給個(gè)ack確認(rèn),才能刪除。

畫(huà)外音:邏輯刪除,還是物理刪除,根據(jù)業(yè)務(wù)是否有消息漫游決定。

對(duì)于離線的群友,在下次登陸后,拉取完離線消息,再給ack確認(rèn),才能刪除。

總之,為了保證消息的可達(dá)性,不管是在線消息,還是離線消息,必須接收方給ack確認(rèn),才能刪除消息。

“不管是否在線,都冗余一份群消息”帶來(lái)的問(wèn)題是,同一條消息存儲(chǔ)了很多次,對(duì)磁盤(pán)和帶寬造成了很大的浪費(fèi)。很容易想到的優(yōu)化是:群消息實(shí)體存儲(chǔ)一份,用戶只冗余消息ID。

故基礎(chǔ)數(shù)據(jù)可以由:

 
 
 
 
  1. user_msgs(uid,msgid,gid,sender_uid,time,content); 

優(yōu)化為:

 
 
 
 
  1. group_msgs(msgid,gid,sender_uid,time,content); 
  2. user_msgs(uid, msgid, gid); 

這個(gè)優(yōu)化,對(duì)于消息投遞,以及消息刪除的核心流程沒(méi)有影響,幾個(gè)實(shí)踐為:

  • 在線用戶投遞消息實(shí)體,ack消息ID;
  • 離線用戶先拉取消息ID,再拉取消息實(shí)體,再ack消息ID;

如此這般,假如在某個(gè)群友A期間,群里陸續(xù)發(fā)送了N條消息,則user_msgs(uid, msgid, gid)里,會(huì)有 uidA -> mid1,mid2, mid3, … midN 等N條離線記錄,拉取離線消息時(shí),可以把這N條消息一次性拉取出來(lái),然后再刪除:

 
 
 
 
  1. delete from user_msgs  
  2.     where msgid in($mid1,$mid2…, $midN) and gid=$gid 

 然而,群消息具備“偏序”特性,上面的一次性刪除完全可以優(yōu)化為:

 
 
 
 
  1. delete from user_msgs  
  2.     where msgid >= $mid1 and gid=$gid 

這就意味著,每個(gè)用戶只需要記錄“最近一次收到的消息ID”,而不用記錄“所有未收到的消息ID集合”,每當(dāng)收在線消息ack,以及拉離線消息ack時(shí),只需要更新這個(gè)“最近一次收到的消息ID”即可。

于是乎,基礎(chǔ)數(shù)據(jù)可以由:

 
 
 
 
  1. group_members(gid, uid); 
  2. group_msgs(msgid,gid,sender_uid,time,content); 
  3. user_msgs(uid, msgid, gid); 

優(yōu)化為:

 
 
 
 
  1. group_members(gid, uid, last_ack_msgid); 
  2. group_msgs(msgid,gid,sender_uid,time,content); 
  3. user_msgs(uid, msgid, gid); // 不再需要 

即,群消息只存儲(chǔ)一份,群友無(wú)需冗余任何消息實(shí)體,或者消息ID了。

對(duì)于在線的群友,收到群消息后,修改這個(gè)last_ack_msgid。

對(duì)于離線的群友,拉取群消息后,也修改這個(gè)last_ack_msgid。

畫(huà)外音:這里的討論,僅限于接收方收到了哪些消息,和發(fā)送方的已讀回執(zhí)沒(méi)有關(guān)系。

總結(jié)

任何架構(gòu)方案都不是靈光一現(xiàn),而是逐步迭代優(yōu)化產(chǎn)生的:

  • 存多份,只存在線,消息容易丟;
  • 存多份,所有群友都存儲(chǔ),消息冗余多;
  • 存多份,只存ID,未利用偏序;
  • 存一份,只存last_ack_msgid;

架構(gòu)不只是設(shè)計(jì)出來(lái)的,更是演進(jìn)出來(lái)的。

任何脫離業(yè)務(wù)的架構(gòu)設(shè)計(jì)都是耍流氓。

【本文為專欄作者“58沈劍”原創(chuàng)稿件,轉(zhuǎn)載請(qǐng)聯(lián)系原作者】

戳這里,看該作者更多好文


標(biāo)題名稱:群消息,究竟存1份還是多份?
鏈接地址:http://www.5511xx.com/article/dhojcip.html