百万人点赞时,如何处理点赞数据激增的情况?

摘要:大家发现了吧,现在面试八股文好像问的少了,反倒是场景题多了起来,毕竟现在AI如此强大,总揪着这点底层基础也没多大意思。 面试官张嘴闭嘴高并发、大数据量倒是真的,别管实际业务是不是高并发,但是你不会是进不来拧螺丝的。 就像之前有同学被问:“某
大家发现了吧,现在面试八股文好像问的少了,反倒是场景题多了起来,毕竟现在AI如此强大,总揪着这点底层基础也没多大意思。 面试官张嘴闭嘴高并发、大数据量倒是真的,别管实际业务是不是高并发,但是你不会是进不来拧螺丝的。 就像之前有同学被问:“某音百万用户同时给一个视频点赞,让你来要怎么设计?”,这类题肯定见过吧。 咱们来简单拆解下这题,我是一个小学习,知识量有限,不喜勿喷。 这道题到底考察什么? 别上来就想用什么技术,先明确面试官的考察点,才能答到点子上: 高并发写入能力:百万人同时操作,瞬间 QPS 能冲到几十万,如何避免数据库被打垮?这是考察你对流量削峰的理解; 数据一致性:用户点赞后必须立刻看到 已赞 状态,点赞数可以有轻微延迟,但不能错、不能丢,这是对最终一致性的考察; 系统可用性:就算后端服务波动,用户点赞操作也得成功,不能出现点了没反应的情况,考察容错和降级思路; 资源优化:百万次请求直接怼数据库肯定不行,如何用缓存、消息队列等中间件减轻压力,考察技术选型能力。 换位思考 很多人一上来就纠结怎么让百万次点赞实时写入数据库,其实跑偏了。 咱们站在用户角度想: 用户点击点赞后,最关心的是有没有点赞成功,而不是当前赞数到底是 10086 还是 10087; 赞数是给所有用户看的公共数据,轻微延迟用户完全感知不到(就算数据丢了,用户也很难发现,只是会想“咦”我之前点赞过一个视频没了,就没然后了); 核心需求是:操作成功率 99% + 客户端状态实时反馈 + 赞数最终准确。 想通这一点,方案就清晰了:把实时写入数据库的压力,转移到中间件上,用异步 + 缓存的思路解决高并发。 选取方案 咱们一步步拆解,从用户点击点赞按钮开始,整个流程是这样的: 1. 用户点赞:先写消息队列,客户端直接反馈成功 用户点击点赞的瞬间,客户端不会直接调用数据库接口,而是做两件事: 向后端发送点赞请求,后端收到后,不操作数据库,直接把用户ID + 视频ID + 点赞状态(赞 / 取消赞)封装成一条消息,写入 Kafka; Reids 记录 用户ID + 视频ID 的点赞状态,增加 视频ID 的赞数量 只要消息成功写入 Kafka,后端就立刻返回点赞成功给前端,客户端马上显示已赞状态。 为啥选 Kafka 我就不说了。 2. 客户端:本地记录状态,避免重复点赞 客户端收到点赞成功后,除了显示已赞,还要在本地存储记录当前用户对该视频已点赞。 这样做的好处是: 防止用户短时间内重复点击点赞,前端直接拦截,减少无效请求; 就算后续缓存没更新,用户自己看到的状态也是准确的,不影响个人体验。 3. 查赞数:直接读 Redis,不用查数据库 其他用户查看视频时,需要显示赞数,这时候客户端会调用查询赞数接口,后端的处理逻辑是: 不查数据库,直接从 Redis 里读取该视频的赞数缓存; Redis 读性能极高,支持每秒几十万次查询,完全能扛住百万用户同时查看的压力; 这里的赞数可能不是实时最新的,但只要延迟在可接受范围内,用户完全没感觉。 4. 后台任务:定时同步 Redis 和数据库,保证最终一致 这一步是兜底,负责把 Kafka 里的点赞消息处理掉,同时更新 Redis 和数据库: 后端持续从 Kafka 里拉取点赞消息; 启动一个定时任务,把 Redis 里所有视频的赞数,批量同步到数据库里; 同步时要注意幂等性:比如用户先赞后取消,最终状态是未赞,避免重复计算导致赞数错误。 批量同步,攒一批数据(比如 1 万条)再批量更新,大大减少数据库的写入压力。 而且定时任务可以根据业务调整频率,比如高峰期每 1 分钟同步一次,低峰期每 10 分钟同步一次,灵活适配流量。 方案优势 这套方案没有复杂的架构,但的确能解决百万级点赞的高并发问题,核心优势在于几种中间件的组合使用: 高可用:Kafka 保证消息不丢失,Redis 保证查询不卡顿,就算数据库暂时挂了,用户点赞和查赞数都不受影响; 易扩展:如果后续点赞量涨到千万级,只需要增加 Kafka 的分区数、Redis 的集群节点,就能轻松扛住; 低成本:不用复杂的分布式事务,不用实时计算框架,用最基础的中间件就能实现,开发和维护成本都低。 写在最后 其实很多高并发场景,比如点赞、评论、秒杀,核心思路都是异步解耦 + 缓存兜底。 面试官考察的不是你知道多少冷门技术,而是你能不能看透问题本质,用户要的是 体验 和 成功,不是 实时准确。
阅读全文