默认
发表评论 15
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
聊一下im服务端的离线消息存储方案的痛点及改进
阅读(50260) | 评论(15 收藏1 淘帖 1
原服务端方案:

  • 痛点一:扩散方式记录离线消息
  • 痛点二:APP上线后全量拉取

先说下目前对于痛点一:扩散方式记录本没有多大问题,简单点说是存储空间问题,加块硬盘就可以搞定的事,然而问题并不像想象的那么简单,随着数据量达到千万级,亿级,对于数据库的性能要求就无情的显现出来了(相信我,很快你也会遇到同样的问题)。

临时解决方案(假设离线数据量达到亿级别):

1)对missu_offline_history进行分表处理,固定分40表,通过uid%40方式把不同用户的离线数据导航到missu_offline_history00-39,确保同一用户的数据只会存在一张表内,另外减少频繁插入数据造成大量的锁表问题,在数据分布均匀的理想状态下,单表数据量<300w

2)在1的基础上对表missu_offline_history00-39做分区处理,通过key方式分7个区,进一步对用户离线数据进行细分到不同分区,确保同一用户的数据只会存在一个分区内,在数据分布均匀的理想状态下,单分区数据量<50w(为什么采用key分区?因为分表方案采用了和hash分区一样的求模算法,因此再分区就需要key分区方式了)

经过以上2步,几亿数据可以轻松应对了,于是我们就可以多存几天离线了。

再说下痛点二:全量拉取的缺点应该不必多说,前端的处理能力本就有限,大量数据到达的时候,难免会产生卡顿,即使你再很努力的发掘前端性能,另外还会对于服务器宝贵带宽造成不必要的浪费

解决方案(分页拉取):

1)APP离线重连后首次批量拉取(用户离线期间可能产生多个聊天会话),目前单个会话拉取最新40条,并且只有重连后才会触发(后端需要帮前端记录离线期间产生了哪些会话,这是关键)

2)APP聊天界面实现下拉刷新,进行单个会话的离线消息拉取(由用户行为进行触发剩余离线消息的拉取)

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

标签:离线 IM开发
上一篇:这张IM架构图里为何消息到达logic后继续往后还要用到mq?下一篇:大家im的心跳间隔、服务端判断连接过期一般是多长时间?
推荐方案
评论 15
我看了你的思路,你的用户量现在达到什么量级?

关于你说到扩散写的问题:这差别主要体现在群聊上,这个一般在整个应用中群聊很多、单群人数很多的情况下,离线消息的扩散写还是很恐怖的。建议分步处理:1)优先考虑扩散读,2)然后再考虑分表。扩散读只是技术实现上稍繁琐一点,但从im的这个技术点上来说,算是个最佳实践。默认的实现完全是为了简单,没想搞复杂,否则有很多人别说去扩展,有可能是看不懂的,必竟用这份代码的,多数是im外行。

关于你全量拉取优化的问题:你的思路很对,如果能实现,还是比较优雅的。默认版本这一块没有太多复杂逻辑,计划在接下来的版本里,将这一块的逻辑做复杂,做全面一些。
楼主几亿的数据?
是几天的数据量?
用户规模达到多少了?
签名: 秋天到了,终于凉快了
楼主关于全量拉取的这个思路很实用,也容易实现,顶楼主
引用:JackJiang 发表于 2020-11-11 23:06
我看了你的思路,你的用户量现在达到什么量级?

关于你说到扩散写的问题:这差别主要体现在群聊上,这个 ...

嗯 正如大佬所说 扩散写终究不能做最终方案,看到论坛有一篇扩散读的方案,今天研究下
引用:clark.li 发表于 2020-11-11 23:10
楼主几亿的数据?
是几天的数据量?
用户规模达到多少了?

如1楼所说 用户量没多少 单日活跃用户100-200  群聊10来个 单群500人左右  所以产生了大量离线 分区分表只是临时方案 目前正在研究记录单条的方案
引用:天黑请闭嘴 发表于 2020-11-11 23:17
楼主关于全量拉取的这个思路很实用,也容易实现,顶楼主

嗯 多谢关注
引用:jnckj 发表于 2020-11-12 10:20
如1楼所说 用户量没多少 单日活跃用户100-200  群聊10来个 单群500人左右  所以产生了大量离线 分区分表 ...

按理说,这个量不算大,你离线消息量这么大,你这个APP是哪一类?
是不是跟那种9块9的特价群一样,频繁刷屏新消息的那种?
引用:JackJiang 发表于 2020-11-12 11:04
按理说,这个量不算大,你离线消息量这么大,你这个APP是哪一类?
是不是跟那种9块9的特价群一样,频繁 ...

感慨大佬这么有经验,单群单日3000条消息左右  很恐怖的 因此扩散读的方案迫在眉睫,找到两篇有价值的帖子
IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?
http://www.52im.net/forum.php?mo ... hlight=%C0%A9%C9%A2
IM开发干货分享:我是如何解决大量离线消息导致客户端卡顿的
http://www.52im.net/forum.php?mo ... hlight=%C0%EB%CF%DF
原来两年前已经在讨论这个话题了
引用:jnckj 发表于 2020-11-12 11:27
感慨大佬这么有经验,单群单日3000条消息左右  很恐怖的 因此扩散读的方案迫在眉睫,找到两篇有价值的帖 ...

我槽,一个群单日3000条消息,正常聊天群很少会有这么活跃。。。(按照正常人的作息,假设群的活跃时间是8小时,每小时就是375条消息,每分钟6.25条。。。。 这手机上要是多关注几个群,那手机得烧掉。。。
你这一个群按500人离线算,扩散写的话,一天就是150万条,这存储压力太大了。。。
必须改成扩散读。。
你这是什么样的app?很好奇
引用:JackJiang 发表于 2020-11-12 11:31
我槽,一个群单日3000条消息,正常聊天群很少会有这么活跃。。。
你这一个群按500人离线算,扩散写的话 ...

是的  目前只敢保留7天的离线 虽然对业务没影响 但总感觉有点XX  
引用:jnckj 发表于 2020-11-12 11:38
是的  目前只敢保留7天的离线 虽然对业务没影响 但总感觉有点XX

嗯 你改完一对比,估计就很有成就感了
存储方面你可以考虑考虑hbase这种分布式数据库。 我们用的阿里的表格存储,性能完全没问题。 钉钉用的都是它。
引用:徐洋 发表于 2020-11-14 21:06
存储方面你可以考虑考虑hbase这种分布式数据库。 我们用的阿里的表格存储,性能完全没问题。 钉钉用的都是 ...

嗯 多谢建议  目前就分布式感觉杀鸡用牛刀了  目前正在做方案调整成记录一条的方式
引用:JackJiang 发表于 2020-11-11 23:06
我看了你的思路,你的用户量现在达到什么量级?

关于你说到扩散写的问题:这差别主要体现在群聊上,这个 ...

我觉得你应该搞一个同步库 ,一个储存库 , 同步库(redis)存3天的聊天数据,应该很少有人去翻一天以前的数据 ,历史数据通过储存库去拿这里建议用tidb或者hbase

用户上线的时候就把同步库里面的数据全给拉下去,同步库可以记录消息id,也就说可以通过id来判断那些数据已经获取
签名: 我想要金币
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部