温馨提示:文本由机器自动转译,部分词句存在误差,以视频为准
00:00
支持百万人超大群聊的web端iim架构设计与实践群聊消息的分发模式。上图展示了它们的区别,区别就在于消息是写一次还是写N次以及如何读取。一读扩散就是所有群成员共用一个群信箱,当一个群产生一条消息时,只需要写入这个群的信箱即可,所有群成员从这一个信箱里读取群消息。二线扩散就是每个群成员拥有独立的信箱,每产生一条消息,需要写入所有群成员信箱,群成员各自从自己的信箱内读取群消息。所以当单群成员在万级以上时,用血扩散就明显不太合适了。写入效率太低,而且可能存在很多无效写入不活跃的群成员也必须得有信箱,存储成本是非常大的,因此采用读扩散是比较合适的。先来看看群聊的架构设计图,如上图所示。
01:03
从用户登录到发送消息再到群,用户收到这条消息的系统流程如上图所示,1、用户登录通过负载均衡与连接服务建立web socketit长连接。2在本地内存里使用哈希表存储key为group ID value we list, 同一个群的用户可能会在不同的集群服务器上上报群组路由。这里需要二种同步策略并行,保证群组路由信息的准确性A。在用户建立断开长连接时,即刻上报B,定时上报乱序现象。假设群里有用户A、用户B、用户C、用户D,下面以ABCD代替。假设A发送了三条消息,顺序分别是MMRG1 MSG2、MGD3,但BCD看到的消息顺序不一致,如上图所示,这时BCD肯定会觉得A在胡言乱语了,这样的产品用户必定是不喜欢的,因此必须要保证所有接收方看到的消息展示顺序是一致的。所以这里采用推拉结合方式来解决这个问题。举例,上图表示服务端的消息顺序。
02:21
上图表示用户端拉取消息时本地消息队列和提醒队列的变化逻辑。1T时刻用户本地最新的完整消息是NGE1及,这条消息已经完整展示给用户。2T20刻收到服务端推送的mgche三星消息提醒,放到提醒队列,此时用户看不到这条消息。3T30刻向服务端拉取消息详情,将消息详情同步写入到消息队列,此时用户可以看到刷新出3条消息。4T4时刻,用户还会收到MSGMSG4的新消息,提醒用户端校验消息队列已经存在MSGRNG4的详情,忽略该新消息,提醒用户已读消息存储表设计如上图所示。
03:15
但是事情并没这么简单。很明显,这个SQL的耗时波动很大,取决于offset的位置,如果很靠后,SQL执行时间会非常长。笔者通过二个策略来优化这个场景,1、调整产品设计,2、合理利用数据结构。如上图所示,每个群都会构建一个长度为10SCORE和member都是消息ID,可以通过z re rank命令得到某个offset的排名值,该值可以换算成未读数。
我来说两句