大家发现了吧,现在面试八股文好像问的少了,反倒是场景题多了起来,毕竟现在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 的集群节点,就能轻松扛住;
-
低成本:不用复杂的分布式事务,不用实时计算框架,用最基础的中间件就能实现,开发和维护成本都低。
写在最后
其实很多高并发场景,比如点赞、评论、秒杀,核心思路都是异步解耦 + 缓存兜底。
面试官考察的不是你知道多少冷门技术,而是你能不能看透问题本质,用户要的是 体验 和 成功,不是 实时准确。
不过,这套方案看似简单,但覆盖了 “削峰、缓存、异步、最终一致性” 等核心考点,面试时把这个逻辑讲清楚,再结合 Kafka 的消息可靠性、Redis 的高性能、定时任务的批量处理,面试官起码会觉得你 懂行。
如果实际业务中,赞数延迟要求极高(比如直播场景,需要实时显示赞数),也可以把定时同步改成 Kafka 消费后实时更新 Redis,数据库异步同步,本质还是换汤不换药~