P55 项目场景面试:评论盖楼系统架构设计与性能优化
面试题:评论区"盖楼"(楼中楼回复)怎么设计?几百万评论怎么保证性能?
1. 数据模型
方案一:parent_id 邻接表(简单通用)
text
comment(id, post_id, user_id, content, parent_id, root_id, level, create_time)parent_id:回复的父评论(楼中楼直接回复);root_id:所属根评论(一楼),用于分页加载整栋楼;level:层级限制(如最多 3 层,防止无限嵌套)。
方案二:冗余路径/预排序
大数据量下用 path(如 root_id:parent_id:child_id)存完整路径,一次查询拿整棵树。
2. 核心优化
① 冷热分离 + 两级缓存
- 热帖评论:Redis(String 存整页 JSON 或 ZSet 按时间/点赞排序)+ 本地缓存(Caffeine);
- 冷帖评论:从 DB 读,回填缓存;
- 缓存一致性:新评论/删除评论时淘汰或增量更新缓存。
② 分页与深翻页
- 盖楼分页用游标式(按 create_time/id 定位),不用大 OFFSET;
- 二级回复默认折叠(只看前 N 条,点开加载更多),减少首屏数据量。
③ 读写分离 + 分库分表
- 评论写多读多,按
post_id分片(同一帖子的评论在同一分片); - 读走从库/缓存,写走主库;
- 帖子评论量巨大时按时间归档冷数据。
④ 计数与热评
- 评论数、点赞数用 Redis 计数(INCR),异步同步 DB;
- 热评榜用 ZSet 按点赞排序。
⑤ 异步化
- 发表评论:先写缓存/发 MQ,异步落库 + 更新计数 + 通知;
- 敏感词过滤、垃圾评论识别异步处理。
3. 加分点
- 说清为什么 limit 层级:无限递归查询和展示成本高,主流产品都限制楼层深度;
- 提到评论的幂等(同一条评论重复提交防重);
- 防刷屏:频次限制 + 内容审核;
- 追问"怎么保证缓存和 DB 一致":Cache-Aside(先更新 DB 再删缓存)+ 延迟双删。
一句话总结
评论盖楼用 parent_id + root_id + level 建模,热帖走本地缓存+Redis、冷帖读 DB,游标分页 + 二级回复折叠控制量,写路径异步落库,按 post 分片和读写分离扛住百万级评论。