当前位置:首页>排行榜>晚上十点,你的微信运动排行榜是怎么“算”出来的?

晚上十点,你的微信运动排行榜是怎么“算”出来的?

  • 更新时间 2026-10-25 09:47:42
晚上十点,你的微信运动排行榜是怎么“算”出来的?

每天晚上十点刚过,手机准时弹出一条微信运动的消息:你今天走了多少步,在好友里排第几。这个看似轻巧的推送,背后其实藏着一道相当棘手的工程题。先算一笔账:假设日活一亿,希望所有提醒在一分钟内发完,平均每秒就是一百六十多万条推送落地。如果所有任务都卡在十点整那一秒触发,压力还要再翻六十倍。所以真正难的从来不是“发一条消息”,而是让一亿条消息在可控的时间里、以可控的成本各就各位。

第一道坎是调度。最朴素的做法是一张任务表,定时扫一遍到点的用户挨个发,但单机每秒几千条的速度,发完可能天都亮了,机器中途还不能挂。更合理的思路是把“什么时候发”和“怎么发”拆开:调度器到点只负责把一批用户塞进队列,发送交给消费者按自己的能力慢慢拉。队列在这里不是简单的解耦,而是缓冲——上游一次性灌进来,下游按节奏消化,高峰先涨后落,系统才不会被瞬时流量冲垮。

第二道坎是排行榜本身。每个用户的好友圈都不一样,排名天然是千人千面。如果给每个人都预计算一份有序集合,平均两百个好友看着不多,放大到全量就是TB级的内存常驻,而且步数是白天持续上报的,每变一次就要改他所有好友榜里的那一条,写放大惊人。反过来,查询时实时排序,拿好友列表批量取步数再排,一次查询毫秒级,写入几乎零成本。选哪条路,关键看好友数k和访问频率f的乘积值不值得存一份结果,而且要看k的分布——好友上限能到一万,长尾很长,按平均值设计,碰上大号读成本直接翻几十倍。

第三道坎是“真的需要提前算吗”。提醒里如果只写“你今天走了八千步”,根本不需要排名;要显示“好友里排第七”,排序也完全可以等用户点开再做。假设只有一成的用户会点开,那就是一千万次排序,比给一亿份都算一遍少一个数量级,没点开的那九成一次都没算。但按需计算不是白赚的,它把压力从发送侧搬到了读取侧:推送后几分钟集中点开形成读洪峰,缓存冷启动第一批请求全部回源,一次请求还要读好友列表再批量取步数。所以优化的重点不在排序本身,而在排序之前那两处读取。

说到底,这类系统的核心设计思想是同一个:最有效的优化,往往不是让计算更快,而是让不需要的计算根本不发生。一亿次计算提速十倍,和只算一千万次,省下的是同一个量级,但后者还省机器、省钱。当然,每一种优化都换来额外的复杂度——队列要运维,缓存会不一致,按需计算要处理冷启动和降级。一万用户的时候,一个定时任务加一次内存排序就够了,多一层队列反而是负担;到了一亿,前面每一步的复杂度又都省不掉。技术方案没有绝对的好坏,只有规模和场景是否匹配。

随机文章