自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

開發(fā) 開發(fā)工具
任何技術方案,都不是天才般靈感乍現想到的,一定是一個演進迭代,逐步優(yōu)化的過程。今天就聊一聊,群消息,為啥只需要存一份。

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

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

[[375144]]

群信息,用戶信息,群成員關系都是基礎數據:

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

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

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

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

用戶收到的群消息,也是基礎數據:

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

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

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

“在線的群友不存儲,離線的群友才存儲”會帶來的問題是,如果第四步發(fā)生異常,群友會丟失消息。

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

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

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

先將消息落地,能夠保證消息可達性,那何時才能刪除已經落地的群消息呢?

對于在線的群友,收到群消息后,給個ack確認,才能刪除。

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

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

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

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

故基礎數據可以由:

  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); 

這個優(yōu)化,對于消息投遞,以及消息刪除的核心流程沒有影響,幾個實踐為:

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

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

  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 

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

于是乎,基礎數據可以由:

  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); // 不再需要 

即,群消息只存儲一份,群友無需冗余任何消息實體,或者消息ID了。

對于在線的群友,收到群消息后,修改這個last_ack_msgid。

對于離線的群友,拉取群消息后,也修改這個last_ack_msgid。

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

總結

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

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

架構不只是設計出來的,更是演進出來的。

任何脫離業(yè)務的架構設計都是耍流氓。

【本文為51CTO專欄作者“58沈劍”原創(chuàng)稿件,轉載請聯系原作者】

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

 

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2021-01-08 08:22:17

消息數據結構開發(fā)

2024-08-29 08:30:10

2021-02-20 23:19:24

JavaScript開源GitHub

2021-01-05 09:23:49

網頁端消息

2021-06-24 08:30:08

架構億級消息中心數據

2020-02-03 11:33:53

開源JavaScriptGithub

2021-02-10 07:21:22

Github開源Java

2020-02-06 11:23:22

GithubPython開源項目

2015-11-16 17:38:59

2022-06-25 21:52:09

程序員

2020-02-13 10:46:54

GithubJavaScript開源項目

2021-02-15 12:14:45

開源PythonGithub

2019-02-12 09:14:26

GitHubJavaScrip開源

2021-04-03 12:44:16

編程語言數據Python

2021-02-18 10:53:17

GithubJava開源

2020-02-10 10:42:55

Java開源項目Github

2012-03-20 10:45:50

Windows 8

2019-02-12 08:30:53

GitHub開源項目Java

2019-02-12 08:50:49

GitHub開源項目Python

2020-02-13 15:11:38

JavaScript開源項目
點贊
收藏

51CTO技術棧公眾號