? 几万条群离线消息,如何高效拉取,会不会丢?_CQITer_重庆IT人之家 yabo10.com亚博体育,亚博娱乐在线网站,亚博国际娱乐7171 ?

几万条群离线消息,如何高效拉取,会不会丢?

几万条群离线消息,如何高效拉取,会不会丢?

继续答球友提问:

群离线消息是推还是拉?

几万条群离线消息,怎么保证不丢失?

群离线消息,是推还是拉?

关于写扩散、读扩散的问题,之前专门撰文写过,今天不直接同步结论,重点说说设计的思考过程。

画外音:结论不如思路重要。

假如群离线是推,流程应该如何?会遇到什么问题?

先看看群离线消息的核心数据结构。

群成员表:

t_group_users(group_id,?user_id)?

画外音:用来描述一个群里有多少成员。

群离线消息表:

t_offine_msgs(user_id,?group_id,?sender_id,time,?msg_id,?msg_detail)?

画外音:用来描述一个群成员的离线消息。

推,写扩散,存储群离线消息的过程如何?

先从群成员表中,获取群里有多少个用户;

从某个服务中,获取这些用户有多少个不在线;

将群消息,插入到这些用户的群离线消息表;

画外音:如果要支持消息漫游,则可以省略步骤二。

此时,用户拉取离线消息的过程如何?

用户登录,向server拉取离线消息;

server返回并删除离线消息;

离线消息推,存在什么问题?

对于同一份群消息的内容,多个离线用户要存储很多份。假设群中有200个用户离线,离线消息则冗余了200份,这极大的增加了数据库的存储压力。

如何优化,减少消息冗余量?

为了减少离线消息的冗余度,增加一个群消息表,用来存储所有群消息的内容,离线消息表只存储用户的群离线消息msg_id,就能大大的降低数据库的冗余存储量。

群消息表:

t_group_msgs(group_id,?sender_id,?time,?msg_id,?msg_detail)?

画外音:用来存储一个群中所有的消息内容。

群离线消息表,需要进行优化:

t_offine_msgs(user_id,?group_id,?msg_id)?

画外音:优化后只存储msg_id。

这样优化后,群消息的发送和存储要做一些升级:

每次发送群消息之前,先存储群消息的内容;

每次存储离线消息时,只存储msg_id,而不用为每个用户存储msg_detail;

相应的,拉取离线消息也要做对应的升级:

先拉取所有的离线消息msg_id;

再根据msg_id拉取msg_detail;

删除时,只删除自己的离线msg_id,而不删除msg_detail;

画外音:毕竟msg_detail只存储了一份,不能随便删。

上述过程,能保证离线消息的可达性么?

不能。

例如:server返回客户端离线消息之后,删除了离线消息,但客户端没有展现就奔溃了,离线消息就会丢失。

如何解决离线消息可达性呢?

很容易想到,通过ACK机制,server返回离线消息之后,不能立刻删除离线消息,而必须等客户端ACK,才能删除。

此时,离线消息拉取升级为:

用户登录,向server拉取离线消息;

server返回离线消息;

客户端确认收到了离线消息;

server再删除离线消息;

画外音:增加了3和4两个步骤。

还有一个问题,一次有几十个群,每个群有几千条离线消息,共计几万条群离线消息,消息量过大怎么办?

当然不能一次性拉取,可以:

分群拉取;

每个群分页拉取;

拉取一页,删除一页,拉取下一页,删除下一页...

如果拉取了消息,却没来得及应用层ACK,会收到重复的消息么?

可以在客户端去重,对于重复的msg_id,对用户不展现,从而不影响用户体验。

几万条群离线消息,如何高效拉取,会不会丢?

如上所示,简单总结就是:

群消息表存储消息实体msg_detail;

群离线消息表,存每个用户的msg_id;

分页拉取+应用层ACK,即保证性能,又保证消息可达性;

客户端msg_id去重,保证用户体验;

上面讲的都是“推”模式,群离线消息的设计,真正线上应用较多的,是“拉”模式。

推模式,存在什么问题?

对于离线的每一条消息,虽然只存储了msg_id,但是每个用户的每一条离线消息都将在数据库中保存一条记录,有没有办法减少离线消息的记录数呢?

对于一个群用户,在ta登出后的离线期间内,肯定是所有的群消息都没有收到的,完全不用对所有的每一条离线消息存储一个离线msg_id,而只需要存储最近一条拉取到的离线消息的time(或者msg_id),下次登录时拉取在那之后的所有群消息即可,而完全没有必要存储每个人未拉取到的全部离线消息msg_id。

拉模式,需要对数据结构进行怎样的升级?

群成员表,增加一个属性:

t_group_users(group_id,?user_id,?last_ack_msg_id)?

画外音:用来描述一个群里有多少成员,以及每个成员最后一条ack的群消息的msg_id(或者time)。

群消息表,不变:

t_group_msgs(group_id,?sender_id,?time,?msg_id,?msg_detail)?

画外音:还是用来存储一个群中所有的消息内容。

群离线消息表:不再需要。

使用拉模式后,群消息的发送和存储也要升级:

在消息msg_detail存储到群消息表后,不再需要操作离线消息表(之前需要将msg_id插入离线消息表);

用户收到消息,应用层ACK后,将last_ack_msg_id更新(之前需要将msg_id从离线消息表删除);

几万条群离线消息,如何高效拉取,会不会丢?

群离线消息的拉取流程也类似:

分页拉取离线消息;

ACK离线消息;

更新last_ack_msg_id;

总结

群消息还是非常有意思的,做个简单总结:

群离线消息一般采用拉取模式,只存一份,不需要为每个用户存储离线群msg_id,只需存储一个最近ack的群消息id/time;

为了保证消息可达性,在线消息和离线消息都需要ACK;

离线消息过多,可以分群拉取、分页拉取等优化;

画外音:还可按需拉取,登录不拉取,点进群再拉取。

如果收到重复消息,需要msg_id去重,让用户无感知;

【本文为51CTO专栏作者“58沈剑”原创稿件,转载请联系原作者】

几万条群离线消息,如何高效拉取,会不会丢?

戳这里,看该作者更多好文

相关推荐
新闻聚焦
猜你喜欢
热门推荐
  • 微软AI面试题有多难?这里有一份样卷

      究竟什么样的AI人才能被微软这样的巨头聘用呢?今天,文摘君就淘来了几道微软AI 面试题,同时给出了最基本的解答......

    06-25????来源:澎湃新闻网

    分享
  • 全球最聪明的大脑怎么看AI?他们预测了

      2017年AI领域取得了诸多成果。2018年AI又将何去何从?以下是来自世界顶级研究人员和行业领军人物对2018年AI领域发展作......

    02-20????来源:虎嗅网

    分享
  • 2017JavaScript框架战报 - React分战场

      我们来看看与React有关的软件包的生态系统。当Facebook构建React时,就有许多来自开源社区的第三方软件包。为提供完......

    02-27????来源:湖北新闻网

    分享
  • 小白学数据:教你用Python实现简单监督学

      监督学习作为运用最广泛的机器学习方法,一直以来都是从数据挖掘信息的重要手段。即便是在无监督学习兴起的近......

    03-05????来源:今日头条

    分享
  • 现代编程语言Swift、Kotlin等十大有趣功能

      最近学习了一些现代编程语言,比如Reason,Swift,Kotlin和Dart。这些编程语言提供了许多新功能,本文主要分享了我认......

    04-29????来源:祁东新闻网

    分享
  • 领域场景分析的6W模型

      组成场景的要素常常被称之为6W模型,即描写场景的过程必须包含Who,What,Why,Where,When与hoW这六个要素。......

    04-30????来源:砍柴网

    分享
  • 开源应用服务器WildFly 12发新季度交付模式

      WildFly 12 Final版本现在已经可以下载了,WildFly是一款灵活的开源应用服务器,支持开发人员构建轻量级应用程序。支持......

    05-10????来源:青岛新闻网

    分享
  • 基于Spring Cloud的微服务落地

      微服务架构模式的核心在于如何识别服务的边界,设计出合理的微服务。但如果要将微服务架构运用到生产项目上,......

    06-04????来源:广西新闻网

    分享
  • 为什么阿里工程师纷纷在内网晒代码?

      前阵子,在阿里一个小黑屋里,5名对代码有着极致追求的工程师参与阿里代码领域最高荣誉“多隆奖”的最终角逐。......

    06-08????来源:四川新闻网

    分享
  • 超级大汇总!200多个最好的机器学习、

      我把这篇文章分为了四个部分:机器学习,自然语言处理,python和数学。在每个部分中我都列举了一些主题,但是因......

    09-25????来源:洛阳新闻网

    分享
返回列表
Ctrl+D?将本页面保存为书签,全面了解最新资讯,方便快捷。