高并发系统设计 40 问
唐扬
美图公司技术专家
49013 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 49 讲
高并发系统设计 40 问
15
15
1.0x
00:00/00:00
登录|注册

38 | 计数系统设计(二):50万QPS下如何设计未读数系统?

未读数系统设计
通用计数系统设计
计数系统设计

该思维导图由 AI 生成,仅供参考

你好,我是唐扬。
在上一节课中我带你了解了如何设计一套支撑高并发访问和存储大数据量的通用计数系统,我们通过缓存技术、消息队列技术以及对于 Redis 的深度改造,就能够支撑万亿级计数数据存储以及每秒百万级别读取请求了。然而有一类特殊的计数并不能完全使用我们提到的方案,那就是未读数。
未读数也是系统中一个常见的模块,以微博系统为例,你可看到有多个未读计数的场景,比如:
当有人 @你、评论你、给你的博文点赞或者给你发送私信的时候,你会收到相应的未读提醒;
在早期的微博版本中有系统通知的功能,也就是系统会给全部用户发送消息,通知用户有新的版本或者有一些好玩的运营活动,如果用户没有看,系统就会给他展示有多少条未读的提醒。
我们在浏览信息流的时候,如果长时间没有刷新页面,那么信息流上方就会提示你在这段时间有多少条信息没有看。
那当你遇到第一个需求时,要如何记录未读数呢?其实,这个需求可以用上节课提到的通用计数系统来实现,因为二者的场景非常相似。
你可以在计数系统中增加一块儿内存区域,以用户 ID 为 Key 存储多个未读数,当有人 @ 你时,增加你的未读 @的计数;当有人评论你时,增加你的未读评论的计数,以此类推。当你点击了未读数字进入通知页面,查看 @ 你或者评论你的消息时,重置这些未读计数为零。相信通过上一节课的学习,你已经非常熟悉这一类系统的设计了,所以我不再赘述。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

这篇文章深入探讨了设计高并发未读数系统的原理和解决方案。首先介绍了未读数系统的常见应用场景,如微博系统中的未读@、评论、系统通知以及信息流未读数。作者指出通用计数系统无法满足未读数系统的需求,并提出了针对系统通知和全量用户打点场景的解决方案。针对信息流未读数系统的设计,作者建议记录用户关注人的博文数快照,并通过简单的全内存操作来计算未读数。文章强调了缓存的重要性以及围绕系统设计的关键困难点寻找解决办法的重要性。总的来说,本文对于需要设计高并发未读数系统的技术人员具有一定的参考价值。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《高并发系统设计 40 问》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(30)

  • 最新
  • 精选
  • 小可
    这三个方案都很“硬核”,不过最最重要的,不要照搬硬套,还是要根据实际场景分析问题的难点,找准关键点,制定应对方案,谢谢老师。

    作者回复: 谢谢~

    2019-12-20
    7
  • 阿土
    考试你好,我有两个问题 第一:关注的人删除了博文,记录的博文数要不要相应减少?快照里面的数据要不要减少? 第二:如果一个人关注的人很多,比如有一千个,那么它每次过去未读数就就要读取1001次缓存,能够支持50w并发,性能上是如何优化的?

    作者回复: 1. 博文数要减少,快照不能减少,所以不是很精确,不过应该可以接受 2. 不需要1001次哦,如果有四个缓存节点,就读四次,每次是批量获取的,就是算好哪些数据存储在哪个缓存节点上

    2019-12-20
    5
    7
  • 大龄程序员在线治掉发
    统计这个 ID 之后有多少条消息,这就是未读数了 我这里有个疑问,如果用户有10条未读,他直接读第五条消息,那么10-5 = 5 , 就是5个未读,实际上是9条,这样未读就不对了?

    作者回复: 这个场景在读的时候只能把之前未读的消息都读了

    2020-01-07
    2
    6
  • Jone_乔泓恺
    总是担心 redis 这种内存型数据库会因为服务器故障导致数据的丢失

    作者回复: 主从+主备就好了

    2020-03-26
    3
  • Geek_219216
    老师 未读数还会落地到数据库吗

    作者回复: 不会的,直接用redis

    2020-01-13
    3
  • longslee
    打卡。感谢老师实战经验,眼界开阔了许多。 有一个疑问,这些方案,是老师你们独特想到的,还是业界通用做法呢,如果是业界通用的,业界都是从哪里最先开始获取到理论支持的呢?

    作者回复: 其实方案是理论的实践,理论是通用的,方案是独特的

    2020-01-09
    3
  • Bravery168
    我之前在实现红点消息和未读数也采用的是时间戳偏移计算的思路,当然数据规模没有微博这么大。这里用到通用计数器和快照比较得出未读数的思路挺好,任何实现方案还是要紧密结合应用场景来做精心设计,在存储,读写性能等维度上达到一个平衡。

    作者回复: 是的

    2020-03-16
    2
  • zk_207
    扬哥你好,请教个问题,如果接口QPS到达20w甚至是50w级别,只靠缓存能承受得了吗?Redis并发到了10w级好像性能就不行了,请求解答,谢谢

    作者回复: 可以用多个节点来扛呀:)

    2020-03-05
    2
    2
  • 陈琪
    是否可以按大V和非大V结合处理的方式: 推拉结合 1. 发文的时候,如果这个人粉丝数少,直接推送到他每个粉丝数的 "普通未读数计数", 2. 如果这个人是大V,就不推。 3. 用户获取未读数 = (他关注的大V里总数-快照数) + “普通未读数计数” 需要考虑的就是一个用户从普通V变成了大V。 这种总体读写性能都能比较好平衡,老师觉得呢

    作者回复: 粉丝数其实就是大v和非大v的区分

    2020-04-01
    2
    1
  • Geek_42f729
    如果有多个组件需要展示红点,是不是需要根据不同的组件给用户创建多个不同的时间戳来进行比较呢?

    作者回复: 是的

    2020-01-06
    1
收起评论
显示
设置
留言
30
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部