《互联网产品的服务端架构·内容、社交与实时互动》附录 B Feed 与 IM 参数表

把卷二各章的阈值、窗口、上限与默认值集中成表:内容分层、审核时限、推拉门槛、排序权重、频控窗口、评论折叠、消息去重、在线判定、推送降级与搜索滞后各自给出起点值与标定方法,并标明哪些是代码常量、哪些是案例假设,附不同规模下的调整趋势与监控指标对应表。

本附录把卷二出现的阈值集中在一处。使用前请先看两句话:

  • 标「代码常量」的值,来自实验工程,可以直接在对应包中找到;它们是演示用的起点,不是生产建议。
  • 标「案例假设」的值,是为让成本计算可以算一遍而设定的数量级,换产品要重新标定。

任何参数都不该在没有基线的情况下上线。先有指标,再调参数;否则调完之后没人能证明变好还是变坏。

内容分层参数

第 1 章的 content.TierOf 用访问行为而不是创建时间决定存储层。

参数值类型含义
热层天数7 天代码常量最近 7 天读过即 hot
热层次数30 天内 10 次代码常量高频访问也进 hot
温层天数90 天代码常量90 天内读过进 warm
冷层其余代码常量长期未访问进 cold

这两个条件取「或」:只要满足其中一个就进热层。原因是内容的热度有两种形态,一种是最近被读,一种是被反复读。只看其中一个,会漏掉另一种。

分层的目的是控制存储成本与读取延迟,不是给内容贴标签。如果冷层存储和热层成本差不多,就不值得做分层;先算一遍「迁移节省的存储费」是否大于「迁移任务的开发与运维成本」。

审核时限参数

第 2 章的审核链路有几个时间上限,它们直接影响用户体验。

参数建议起点类型说明
机审超时2 秒案例假设超时按「转人审」处理,不直接拒绝
人审 SLA30 分钟案例假设高峰期可放宽到 2 小时,但要告知用户
申诉时限7 天案例假设从拒绝时间起算
复审抽样率1%案例假设按审核员与内容类型分层抽样
审核结论缓存24 小时案例假设同一作者同一类型短期重复内容可复用

机审超时不能设得太短。设成 200 毫秒,会把大量正常内容推给人审,人审队列立刻积压;设成 10 秒,用户发布等待时间不可接受。2 秒是一个常见折中,但要用自己的机审 p99 来定。

申诉时限的意义不是「让用户申诉」,而是「让误判有出口」。时限太短,用户来不及反应;太长,审核团队要维护大量历史记录。7 天是多数内容产品的常见值。

Feed 推拉选择参数

第 3 章的 feed.Choose 按粉丝数选择默认策略。

参数值类型含义
推模式上限粉丝 < 1000代码常量小账号写扩散
拉模式下限粉丝 > 100000代码常量大账号读聚合
混合区间1000–100000代码常量一半推、一半拉
写成本0.5 毫秒/份案例假设单次收件箱写入
读成本0.2 毫秒/源案例假设单次来源合并

这三个门槛是案例假设,不是行业标准。真实选择要看三个量:粉丝数分布、刷新频率、存储成本。如果产品里 90% 的用户粉丝数小于 100,推模式的总写入量可能完全可以接受;如果头部作者粉丝数达到百万,推模式的写入放大就会失控。

FanoutCost 给出的成本是线性估算,忽略了批量写入、管道、缓存命中等优化。它的用途是比较数量级,不是预测真实延迟。

Feed 排序参数

第 4 章的 rank.Score 用四类信号加权,时间按 1/(1+ageHours) 衰减。

信号权重起点类型说明
时间1.0案例假设衰减项,1 小时内容得 0.5
点赞0.02案例假设50 赞约等于 1 个时间单位
评论0.05案例假设评论比点赞重,但权重不能过高
亲和0.5案例假设作者与读者的历史互动强度,取值 0–1

权重之和必须为正,单项必须非负。代码会拒绝全零权重,因为那会让所有内容同分,排序退化成随机。

调权重时一次只动一个,并且先定评价指标。常见的指标是「完读率」「互动率」「次日留存」,三个指标往往互相冲突:提高时间权重会让新内容更多,但可能降低互动率;提高亲和权重会让熟人内容更多,但可能降低新作者的曝光。

没有实验分桶能力时,不要凭感觉调权重。第 4 章讲过,分桶要稳定、指标要预先定义、观察期要覆盖至少一个完整周期。

关系与互动参数

第 5、6 章涉及的阈值主要影响体验与成本。

参数建议起点类型说明
关注上限5000案例假设超过后提示「先取关」
好友上限1000案例假设双向关系,成本更高
拉黑上限500案例假设防止滥用,也控制判定链长度
点赞频控60 次/分钟案例假设按用户维度
评论频控20 次/分钟案例假设按用户 + 内容维度
计数漂移容忍5%案例假设counter.Evaluate 的 tolerance 上限为 1

频控用滑动窗口,不用固定分桶。固定分桶在窗口边界会放过两倍流量:用户在 59 秒和 61 秒各发 60 次,固定分钟桶会全部放行。

计数漂移容忍度取决于指标。点赞数漂移 5% 用户几乎感知不到;收藏数漂移 5% 可能影响用户决策;金额类计数不能有漂移,必须强一致。

评论折叠参数

第 7 章的 comment.FoldRule 控制折叠,不删除。

参数建议起点类型说明
折叠起始深度3代码常量(可配)根评论深度 0,回复从 1 起
深层保留点赞数5代码常量(可配)达到深度且点赞不足则折叠
最大展示深度5案例假设超过后显示「展开更多」
单页评论数20案例假设按内容与排序方式调整

折叠规则要满足两个条件:根评论永不折叠(否则用户看不到讨论的起点);折叠不删除节点(否则被折叠者的申诉无从查起)。

BlockedAuthors 用于把被拉黑作者的非根评论连同子树一起折叠。这个名单应该在查询时实时计算,而不是缓存太久;用户解除拉黑后,折叠状态要能恢复。

IM 消息参数

第 8、9 章的参数决定消息能不能被正确排序、去重与补偿。

参数建议起点类型说明
群成员上限500案例假设超过后改用频道模型
消息去重 TTL300 秒案例假设delivery.Window.TTL,单位秒
在线心跳 TTL90 秒案例假设超过视为离线
已读上报节流2 秒案例假设避免高频写已读表
消息保留期180 天案例假设到期归档,不物理删除
单次拉取条数50案例假设漫游分页上限

去重 TTL 要大于「客户端重发 + 网关重试 + 消费重试」的最大时间跨度。设成 30 秒,一次网络抖动后的重发就可能绕过窗口;设成 24 小时,窗口内存或存储成本会很高。5 分钟是常见折中。

在线心跳 TTL 要与客户端心跳间隔配合。客户端 30 秒一次心跳,服务端 TTL 设 90 秒,可以容忍两次丢包。TTL 设得比心跳间隔还短,会把正常连接判成离线。

已读序号按设备存,读时取最大值。不要按设备求和,也不要在客户端做合并;多端合并的逻辑必须在一个地方,否则每个端都会写出自己的版本。

推送参数

第 10 章的推送链路有几个硬约束来自渠道,不是产品能随便定的。

参数建议起点类型说明
APNs 包体上限4 KB渠道约束超过会被拒收
FCM 包体上限4 KB渠道约束数据消息另有上限
小程序订阅消息按模板字段渠道约束不能自由拼接长文本
营销推送频控3 条/天案例假设按用户维度
事务通知频控不限制条数案例假设但要聚合同一会话
重试次数3 次案例假设指数退避,间隔 1/5/30 秒
降级链推送 → 站内信 → 短信案例假设短信只用于高优先级

渠道包体上限是硬约束,不是建议。模板渲染后要按渠道裁剪,而不是把一套长文案发给所有渠道。小程序订阅消息尤其严格:模板字段、字数、跳转路径都要提前申请。

事务通知不限制条数,但必须聚合。用户收到「A 评论了你」「B 评论了你」「C 评论了你」三条推送,体验远差于一条「3 人评论了你」。聚合窗口建议 5–15 分钟,太短起不到聚合作用,太长会让用户觉得通知延迟。

搜索与推荐参数

第 11、12 章的参数主要影响一致性与兜底。

参数建议起点类型说明
索引滞后预算60 秒案例假设超过后告警
删除生效目标5 分钟案例假设写进产品文案
召回条数500案例假设排序前候选集
排序返回条数20案例假设首屏
推荐兜底链个性化 → 热榜 → 最新案例假设每级都有明确触发条件
特征缓存 TTL10 分钟案例假设在线特征
冷启动观察期7 天案例假设新用户/新内容

索引滞后不是 bug,是架构属性。产品预期要写清楚「删除后最长 5 分钟从搜索消失」,而不是承诺「立即消失」。如果业务要求立即消失,读路径要先查主库状态,再展示索引结果。

推荐兜底链的每一级都要有触发条件:个性化返回空、超时、特征缺失、新用户。没有触发条件的兜底等于没有兜底,因为没人知道什么时候该用。

容量换算

把参数代进容量公式时,注意单位。

量换算常见错误
1 天86400 秒用 100000 秒近似
1 TB1024 GB与十进制 TB 混用
峰值系数3–5 倍均值用均值做容量规划
写放大粉丝数 × 每份字节忽略副本与索引
读放大来源数 × 每次查询忽略缓存未命中

峰值系数是最容易被低估的参数。内容社区的流量高峰通常出现在晚间和突发事件,峰值可能是均值的 3–5 倍。按均值规划容量,高峰一定撑不住。

写放大要算三部分:收件箱条目、索引文档、缓存副本。只算收件箱,会低估一半以上的存储。

参数标定流程

参数不是拍脑袋定的,也不是一次定死的。建议的标定流程是:

  1. 定指标。 这个参数影响哪个指标?延迟、成本、准确率、还是用户体验?
  2. 取基线。 上线前先测一遍当前值,没有基线就没有「变好」。
  3. 小流量验证。 用 1%–5% 流量验证方向,不要一次全量。
  4. 观察完整周期。 至少覆盖一个工作日 + 一个周末,内容产品的周期性强。
  5. 记录取舍。 这个参数调大,什么变好、什么变差,写进决策记录。

第 5 步最容易被跳过。参数调整往往有多目标冲突,只记录「调了之后指标 A 涨了」,不记录「指标 B 跌了」,下次遇到同样问题还会再试一遍。

不同规模下的参数倾向

同一组参数在百万级和千万级产品里往往要往相反方向调。下面这张表给出趋势,不是具体数值。

参数百万级倾向千万级倾向原因
推拉门槛门槛可以低一些门槛必须提高头部粉丝数变大,写扩散成本非线性上升
收件箱写入同步可接受必须异步 + 合并单次发布扩散量超出同步预算
计数更新直接写缓存批量聚合 + 对账高频写会打满热点分片
已读上报每次上报节流 + 合并多端高频写会放大存储压力
审核机审为主分层机审 + 人审抽检内容量超出人工处理能力
搜索同步双写可接受必须走变更日志双写失败会留下长期不一致
推送按事件即时发聚合 + 频控单用户事件量变大,必须合并
通知降级站内信即可分优先级 + 短信不同通知的商业价值差异变大

读这张表时要问自己一个问题:我的瓶颈现在在哪? 如果瓶颈是开发人力,参数应该偏保守,先用简单方案;如果瓶颈是成本,参数应该偏激进,尽早引入合并与分层;如果瓶颈是体验,参数应该偏实时,接受更高的成本。

参数与监控指标的对应

每个参数都应该有至少一个监控指标,否则调了之后无法判断效果。

参数监控指标异常信号
机审超时机审 p99、转人审率p99 接近超时值、转人审率突然上升
人审 SLA审核队列长度、超时率队列持续增长、超时率超过 5%
推拉门槛收件箱写入 QPS、刷新 p99写入 QPS 随发布量线性上涨
排序权重点击率、完读率、多样性单一作者占比过高、内容同质化
频控窗口触发次数、误伤率正常用户被拦截、刷子未被拦截
去重 TTL重复消息率、窗口命中率重复率上升、窗口内存超限
在线 TTL误判离线率、投递失败率正常用户被频繁判离线
推送重试到达率、降级率到达率下降、降级到短信的比例上升
索引滞后同步延迟 p99、删除生效时间延迟持续超过预算、删除后仍可搜到
推荐兜底兜底触发率、兜底点击率兜底触发率上升说明主路径不稳定

指标的选择要能回答问题,而不是「看起来专业」。比如「收件箱写入 QPS」比「系统吞吐」有用,因为它直接对应推模式的成本;「删除生效时间」比「索引延迟」有用,因为它是用户能感知的承诺。

如果某个参数没有对应指标,要么补指标,要么承认它是拍脑袋定的。后者不丢人,但要写进决策记录,方便以后推翻。

参数变更记录模板

每次调整参数,建议在决策记录里留下下面几行。模板很短,但它能避免「半年后没人记得为什么是这个值」。

参数:feed.Choose 推模式下限
旧值:1000 粉丝
新值:3000 粉丝
原因:头部作者占比上升,1000–3000 区间的写扩散成本超过读聚合
影响:小作者内容进入收件箱的延迟从秒级变为刷新时合并
观察指标:收件箱写入 QPS、首页刷新 p99、小作者内容曝光量
回滚条件:刷新 p99 上升超过 20%,或小作者曝光量下降超过 10%
观察期:14 天

记录里最重要的是「影响」和「回滚条件」。只写「因为性能问题调整」,等于没写;没有回滚条件,出问题时只能凭感觉决定是否改回去。

常见参数错误

最后列几个在评审中常见的参数错误。

  • 把超时设成「比下游 p99 大一点」。 下游 p99 会随负载变化,超时应该按「业务能接受的最长等待」定,而不是按下游表现定。
  • 把重试次数设成「越多越可靠」。 重试会放大流量,下游已经过载时,重试会让它彻底崩掉。重试必须有上限、退避和熔断。
  • 把缓存 TTL 设成「越长越省」。 TTL 越长,数据越旧;对可见性、删除、审核状态这类数据,旧数据就是错误数据。
  • 把频控设成「一个全局值」。 营销、事务、互动三类通知的频控逻辑不同,用同一个阈值会误伤。
  • 把分页大小设成「越大越少请求」。 分页越大,单次查询越慢,超时风险越高;深度分页还会拖垮数据库。
  • 把阈值当成永久值。 产品阶段变了,阈值要重标;把一年的旧阈值沿用到新阶段,是最常见的隐性故障源。

这些错误的共同点是:它们都在某个局部看起来合理,但忽略了系统其他部分的变化。参数表的用途不是让你照抄,而是让你知道「这里有一个需要持续标定的决策点」。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「books」更多文章

  1. 《互联网产品的 AI 架构·平台化与治理》附录 C 平台化评审清单
  2. 《互联网产品的 AI 架构·平台化与治理》附录 B 能力目录与配额字段速查
  3. 《互联网产品的 AI 架构·平台化与治理》附录 A 治理角色与职责速查