面试官:百万人同时点赞怎么设计
你有没有想过,当你在看一场百万人级别的直播时,屏幕上那些疯狂滚动的爱心,背后藏着怎样的技术秘密?每秒钟,可能有上百万次点赞同时涌入,而你手机上的动画却依然丝滑流畅。
今天,我们就用一张张横向流程图,完整地走一遍“一个点赞”从你的指尖出发,到最终被亿万观众看到的奇妙旅程。我们将看到,支撑这一切的,是每秒百万次的写入能力、50毫秒的极致响应、处理百亿级推送的智慧,以及高达四个九的系统可用性。
要实现这个目标,我们首先面临四大核心挑战:
第一,极高的写入压力:顶级主播一声令下,点赞请求会像洪水一样涌来。
第二,海量的读取放大:想象一下,一个点赞,需要推送给一百万个观众,这就是百万倍的读取放大,系统根本无法承受。
第三,极致的实时体验:从你点击到看到爱心飞出,整个过程必须感觉是“零延迟”的。
最后,成本的平衡:我们不能为了性能,无限制地堆砌服务器。
那么,架构师们是如何应对这些看似无解的难题的呢?
答案就藏在这四大设计原则里,它们是我们整个架构的基石。
从左到右看:
彻底异步化:将核心操作和非核心操作分开,主路永远保持轻快。
最终一致性:我们不要求数据在每一瞬间都完全同步,但保证它在短暂延迟后,最终会达到正确状态。
多级缓存:让数据尽可能地靠近用户,这是提升速度最有效的方法。
数据分层:根据数据的冷热程度,用不同的策略去处理,好钢用在刀刃上。
接下来,让我们从流程的起点——客户端,也就是你的手机开始。
当你的手指在屏幕上疯狂点击时,手机APP并不会把每一次点击都发送出去。它会做两件非常聪明的事:
乐观UI:它会立即在本地播放点赞动画,让你感觉“零延迟”,非常爽快。
客户端节流:同时,它会在一个极短的时间窗口内,比如150毫秒,把你所有的点击聚合成一个请求,比如{count: 15},然后只发送这一次。
这样,第一道“过滤网”就完成了,请求量被削减了90%以上。
这些从不同用户手机上发来的聚合请求,会到达我们的API网关。
网关会进行第二次聚合。它会把在同一个时间窗口内、发往同一个直播间的所有请求,再次打包成一条更大的消息。比如,这里A、B、C三个用户的请求,就被合并成了一条{total: 16}的内部消息。请求量再次被压缩。
现在,这条聚合后的消息来到了我们整个架构的“心脏”——消息队列,你可以把它想象成一个巨大的“蓄水池”。
接入服务把消息扔进这个“池子”后,就可以立刻返回,告诉客户端“我收到了”,这保证了上游链路的极速响应。而下游的消费服务,则可以根据自己的处理能力,不慌不忙地从池子里取消息进行处理。这个“蓄水池”完美地“削峰填谷”,隔离了上游的流量洪峰,是整个系统稳定性的定海神针。
消息被取出后,首先要做的就是更新屏幕上那个实时变化的点赞总数。这里我们采用了三级缓存策略。
L1本地缓存:对于最热门的直播间,计数直接在服务节点的内存里完成,速度是纳秒级的。
L2 Redis缓存:如果本地缓存没有命中,我们会去访问Redis。它通过原子自增操作,也能达到毫秒级的超高性能。
L3 数据库:最后,数据会异步地、批量地写入数据库,完成最终的持久化。
通过这套组合拳,我们用离用户最近、最快的方式响应了计数请求。
解决了写入,那“读取放大”的问题怎么办?我们不可能把每个赞都推送给所有观众。
这里的核心武器,就是智能采样。
海量的点赞事件,会经过一个“采样器”。它就像一个筛子,只按一个极小的比例,比如1%,随机地让部分事件通过。然后,我们只把这些被“抽中”的幸运事件,推送给直播间里的所有观众。
这样既能营造出点赞不断的热烈氛围,又将推送成本降低了99%,堪称“降维打击”。
现在,让我们把所有环节串起来,这就是我们完整的横向架构图。
数据从左侧的客户端发起,经过API网关的聚合,进入消息队列这个蓄水池。出队后,兵分三路:一路去计数服务更新缓存,一路去持久化服务写入数据库,最后一路通过推送服务进行采样和分发。整个流程清晰、解耦,并且可以无限水平扩展。
总结一下,这个高并发架构的精髓在于:
层层过滤:在客户端和网关持续聚合请求,化整为零。
异步解耦:用消息队列作为缓冲,让系统从容应对流量冲击。
数据分层:用多级缓存分离热点数据,实现极致性能。
智能降维:用采样巧妙地解决了读取放大的世纪难题。
通过这一系列精心设计的“有序混沌”,我们最终实现了在不确定性的流量冲击下,构建一个具有确定性服务能力的稳定系统。
我的分享就到这里,谢谢大家!现在是提问环节。