面试题——全局邮件的设计
和普通邮件有什么不同
普通邮件(读扩散 / Fan-in)
逻辑:邮件存储在发送者的发件箱中。收件人需要查看邮件时,系统去所有发件人的发件箱里“拉取”属于自己的邮件。
类比:像去邮局取信。信都堆在邮局(发送方),你需要自己去查有没有你的信。
面试关键词:收件人主动拉取、按需聚合、读时计算。
全局邮件(写扩散 / Fan-out)
逻辑:发送邮件时,立即将邮件复制到每个收件人的收件箱中。收件人查看时,直接读取自己的收件箱即可。
类比:像快递送货上门。快递员(系统)在发货时直接把信送到你家门口(收件人收件箱)。
面试关键词:发送时预计算、写时分发、空间换时间。
设计思路
全服邮件的核心在于“避免瞬时海量写操作”。
① 数据结构设计(避免循环Insert):
我不会给每个玩家插入一条邮件记录。我会设计一张
global_mail(全服邮件表)和一张user_mail_status(用户邮件状态表)。发邮件时:只往
global_mail插 1条 数据。领奖励时:才去检查这封邮件是否过期,并在
user_mail_status标记已领取。
② 推送机制(懒加载):
- 玩家上线拉取邮件列表时,后端逻辑判断:如果
global_mail里有新邮件,且该玩家没在 user_mail_status里,则动态显示在列表中。不主动推,而是被动查。
③ 异步发放(削峰填谷):
- 如果是给全服发附件(比如钻石),且必须到账。我会把发送任务丢进 消息队列(MQ/Kafka),后台起一个消费者慢慢消费,每处理1000个玩家sleep 1秒,保护数据库。
④ 批量处理优化:
- 如果必须入库(如重要通知),我会使用 Batch Insert(批量插入),一次插入1000条,而不是单条Insert。
