一线大厂面试题-消息推送中的已读消息和未读消息设计难题

“站内信”有两个基本功能:

    1、点到点的消息传送。用户给用户发送站内信 ,管理员给用户发送站内信。

    2、点到面的消息传送。管理员给用户  (指定满足某一条件的用户群)  群发消息

这两个功能实现起来也很简单  {如图}  。

只需要设计一个消息内容表和一个用户通知表,当创建一条系统通知后,数据插入到消息内容表。消息内容包含了发送渠道,根据发送 渠道决定后续动作。

如果是站内渠道 ,在插入消息内容后异步的插入记录到用户通知表。

这个方案看起来没什么问题,但实际上,我们把所有用户通知的消息全部放在一个表里 面 ,如果有 10W 个用户 ,那么同样的消息需要存储 10W 条。

很明显 ,会带来两个问题:

1. 随着用户量的增加,发送一次消息需要插入到数据库中的数据量会越来越大,导致 耗时会越来越长

2. 用户通知表的数据量会非常大 ,对未读消息的查询效率会严重下降

所以上面这种方案很明显行不通 ,要解决这两个问题 ,我有两个参考解决思路。

第一个方式  (如图)  ,先取消用户通知表,    避免在发送平台消息的时候插入大量重复 数据问题。

其次增加一个“ message_offset”站内消息进度表 ,每个用户维护一个消息消费的进 度 Offset。

每个用户去获取未读消息的时候,只需要查询大于当前维护的 msg_id_offset 的数据即 可。

在这种设计方式中 ,即便我们发送给 10W 人 ,也只需要在消息内容表里面插入一条记 录即可。

在性能上和数据量上都有较大的提升。

第二种方式,和第一种方式类似,使用 Redis 中的 Set 集合来保存已经读取过的消息 id。 使用 userid_read_message 作为 key ,这样就可以为每个用户保存已经读取过的所有 消息的 id。

当用户读取了未读消息后,    就直接在 redis 的已读消息 id的 set 中新增一条记录。   这样 ,在已经得知到已读消息的数量和具体消息 id 的情况下 ,我们可以直接使用消息 id 来查询没有消费过的数据。

你们看,一个小小的方案设计的优化,就能带来性能上的巨大提升,这就是为什么很多 企业宁愿多花点钱也要招技术厉害的人的原因了吧。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值