问答平台的流量很少平稳。一场热门赛事、一条被反复转发的科普回答,都可能让某个页面的访问量在短时间内涨好几倍。资源按最高峰值长期备着,闲时就是浪费;只按日常流量配置,热点一来页面就会变慢。弹性计算要解决的,正是这个矛盾。

需要说明的是,这篇文章讲的是问答社区常见的扛流量思路,并非知乎公开披露的内部架构。读的时候把它当作思路参考,具体细节要以各团队自己的系统和压测结果为准。
为什么问答社区的流量难预测
问答社区的内容有两个明显特点。一是访问集中在少数热门问题和高赞回答上,头部很热,长尾很长。二是用户主要在阅读和搜索,读请求远多于写请求。系统压力大多落在读取链路上,缓存、CDN 和可伸缩的计算资源承担了大部分分流工作。
在这种场景里,扩容速度往往比单台机器的性能更关键。如果新增服务器要走采购、上架、部署一整套流程,热点早就过去了。公有云的价值在于,实例可以在分钟级别增加,流量回落后再释放,成本跟着用量走。
热点来时,先看哪里会先撑不住
设想一个场景:某个社会话题引发大量讨论,相关问题在两三个小时内集中涌入,原有服务器集群接近上限。页面打开变慢,部分用户开始刷新失败。这时候如果直接把整个集群扩大一圈,成本会很高,而且未必解决问题,因为瓶颈可能在数据库、搜索或某个共享缓存上。
更稳妥的做法是先看链路,再决定扩哪里。下面是一种比较常见的拆分思路。
一种常见的拆分思路
- 问题详情页中不随用户变化的部分推送到 CDN,减少回源请求。源站的余量留给登录用户和写操作,体验会稳定很多。
- 应用实例放进弹性伸缩组,触发条件同时设置 CPU 使用率和请求数。冷却时间要留够,否则流量抖动时实例会频繁增减,反而不稳。
- 点赞、浏览这类计数操作不必每次都写库,可以先在 Redis 中累加,再定时批量落库。代价是数据会有几秒到几分钟的延迟,产品设计上要提前接受这一点。
- 搜索服务单独限流。搜索请求的资源消耗较重,一旦突发,容易连带占满问答详情页的资源。
方案落地后效果如何,要看指标变化和压测对比,不能只凭感觉。尤其要留意高峰期的平均响应时间和长尾响应时间,两者的差距往往比平均值更能说明问题。
图片、视频和数据库怎么配合
除了计算资源,问答社区的图片、视频和附件同样占用大量带宽。这类文件适合存放在对象存储中,再通过 CDN 分发。但要注意,如果原图直接分发,CDN 只是换了个地方传大文件。上传时做尺寸压缩和格式转换,效果通常更明显。
数据库方面,读写分离可以把查询分散到只读副本,主库专注处理写入。这里有个容易忽略的问题:主从之间存在同步延迟。一条新回答刚发布,从库上可能暂时查不到。发布后的详情页最好直接读主库,或者在发布时主动让对应缓存失效,否则用户会以为自己的回答丢了。
给团队的几条落地建议
- 先拿一周的访问日志,把流量分成热点页、普通页和长尾页三类。三类页面各自设置缓存时长和扩容阈值,不要用同一套规则。
- 弹性规则不要只看 CPU。CPU 不高但连接数已经打满时,页面照样会慢。把响应时间和错误率也放进判断依据,扩容才会在该出手的时候出手。
- 计数类写操作异步化之前,先和产品确认能接受多长的延迟。技术上能做到,不代表业务上可以接受。
- 每次热点过去后做一次复盘,记下哪个环节先触顶、从发现到扩容用了多久、哪条规则误触发了。这些真实记录,比事前写的预案更有参考价值。
基础设施不能替代好的架构设计,也替代不了内容本身。它的作用,是让技术团队在流量不确定时少一些手忙脚乱,把精力放回体验优化上。