美文网首页
即时通讯群聊消息应该选择即扩散读还是即扩散写?

即时通讯群聊消息应该选择即扩散读还是即扩散写?

作者: 可爱的小云朵 | 来源:发表于2022-10-13 10:00 被阅读0次

IM的群聊消息,究竟存1份(即扩散读方式)还是存多份(即扩散写方式)?

最基本的方案:“在线的群友不存储消息,离线的群友才存储”

群信息,用户信息,群成员关系都是基础数据:

group_info(gid, group_info);

user_info(uid, user_info);

group_members(gid, uid);

假设一个群(gid)里有4个成员,其中三个在线(A, uid1, uid2),一个不在线(uid3)。

A发送了一条消息,很容易想到,对于不同的群友消息存多份,每个群友一个队列来存储。但由于在线的用户会实时的收到消息,所以暂定只为离线的用户存储。

用户收到的群消息,也是基础数据:

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

很容易想到,整个群消息的发送流程:

1)发送消息;

2)查询状态;

3)不在线的存储离线;

4)在线的实时推送。

“在线的群友不存储,离线的群友才存储”会带来的问题是,如果第四步发生异常,群友会丢失消息。

优化的方案:“不管群员是否在线,都要先存储消息”

消息的可达性是聊天系统中最重要的要素(没有之一),故这个方案是不行的,需要优化为“不管是否在线,都要先存储”。即时通讯聊天软件app开发可以加蔚可云的v:weikeyun24咨询

发送群消息的流程优化为:

1)发送消息;

2)所有人都存一份;

3)查询状态;

4)在线的实时推送。

先将消息落地,能够保证消息可达性,那何时才能删除已经落地的群消息呢?我们继续往下看。

对于在线的群友:收到群消息后,给个ack确认才能删除。

画外音:逻辑删除,还是物理删除,根据业务是否有消息漫游决定。

对于离线的群友:在下次登陆后,拉取完离线消息再给ack确认才能删除。

总之:为了保证消息的可达性,不管是在线消息还是离线消息,必须接收方给ack确认,才能删除消息。

“不管群员是否在线,都冗余一份群消息”带来的问题

“不管是否在线,都冗余一份群消息”带来的问题是:同一条消息存储了很多次,对磁盘和带宽造成了很大的浪费。

很容易想到的优化是:群消息实体存储一份,用户只冗余消息ID。

故基础数据可以由:

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

优化为:

group_msgs(msgid,gid,sender_uid,time,content);

user_msgs(uid, msgid, gid);

这个优化,对于消息投递,以及消息删除的核心流程没有影响,几个实践为:

在线用户投递消息实体,ack消息ID;

离线用户先拉取消息ID,再拉取消息实体,再ack消息ID。

如此这般,假如在某个群友A期间,群里陆续发送了N条消息,则user_msgs(uid, msgid, gid)里,会有 uidA -> mid1,mid2, mid3, … midN 等N条离线记录,拉取离线消息时,可以把这N条消息一次性拉取出来,然后再删除:

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

终级方案:利用群消息的“偏序”特性优雅地实现“只存1份”

然而,群消息具备“偏序”特性,上面的一次性删除完全可以优化为:

delete from user_msgs

where msgid >= $mid1 and gid=$gid

这就意味着,每个用户只需要记录“最近一次收到的消息ID”,而不用记录“所有未收到的消息ID集合”,每当收在线消息ack,以及拉离线消息ack时,只需要更新这个“最近一次收到的消息ID”即可。

于是乎,基础数据可以由:

group_members(gid, uid);

group_msgs(msgid,gid,sender_uid,time,content);

user_msgs(uid, msgid, gid);

优化为:

group_members(gid, uid, last_ack_msgid);

group_msgs(msgid,gid,sender_uid,time,content);

user_msgs(uid, msgid, gid); // 不再需要

即:群消息只存储一份,群友无需冗余任何消息实体,或者消息ID了。

对于在线的群友:收到群消息后,修改这个last_ack_msgid。

对于离线的群友:拉取群消息后,也修改这个last_ack_msgid。

相关文章

  • IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?

    1、前言 IM的群聊消息,究竟存1份(即扩散读方式)还是存多份(即扩散写方式)? 上一篇文章《IM群聊消息的已读回...

  • 数据存储结构设计,是读扩散,还是写扩散?

    今天在某个即时通讯的群中无意看到这么一句话: 不由问自己,什么是读扩散?什么是写扩散?感觉这两个词昨天才看的,怎么...

  • feed流 读扩散和写扩散 2022-06-28

    feed流 微信朋友圈、微博、小红书,都是典型的feed流应用 通俗的说就是用户拥有发布者和粉丝两种角色,依据用户...

  • 池塘那些事第七阶段总结

    在池塘中,氧的主要来源有光合作用和空气扩散(包括强化扩散,即机械增氧)以及偶尔化学增氧;氧的消耗主要来自饲料、氧债...

  • 扩散

    天天窝在家里实在烦。前段时间天天下雨,昨天明知没啥事也上县去转了一趟。 大概是9点到县城西门口,老远就望到右手边那...

  • 扩散

    3.7,周六 8时起床,完成学习强国43分,订阅加1分,排名仍为11,无变动。 国外确诊病例已达17000,全球近...

  • 扩散

    大家都知道我要说什么,但是呢,我没法说那个的,也没法说那个词,因为这是不允许说的事情,但是我告诉大家的是大家也都知...

  • 扩散

    才明白,原来,向别人倾诉,并不能缓解烦恼。 反而,会让你更加烦恼。

  • 扩散

    一瞬间从2019跨到2022 可能是疫情吧 也有可能是 从20到30的跨度有点大 忽然又有种 那天坐在广州街头的失...

  • 金山云财报:继续亏损、持续扩张

    金山云选择在全球疫情持续扩散的5月登陆美股市场,行险一搏大获全胜,一上市即获市场追捧,上市当天股价爆涨40%。但是...

网友评论

      本文标题:即时通讯群聊消息应该选择即扩散读还是即扩散写?

      本文链接:https://www.haomeiwen.com/subject/grgqzrtx.html