LMTS · System Design Round 2(缓存 / 高性能架构)

Salesforce 高吞吐缓存层:热键、分片、一致性与逐出

Salesforce LMTS 系统设计第二轮明确考类似 Redis 的缓存层;本文围绕 key、TTL/LRU/LFU、多节点失效、数据库一致性及热键扩容做完整取舍。

题目重点:Salesforce LMTS 系统设计第二轮明确考类似 Redis 的缓存层;本文围绕 key、TTL/LRU/LFU、多节点失效、数据库一致性及热键扩容做完整取舍。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练场景为多租户 CRM 对象详情读取,数据库是权威数据源,缓存只存可重建的读模型;具体业务、容量和数字不是题目条件。
  • 示例目标为每秒 10 万读、每秒 1000 写、95% 命中率、允许一般字段短暂陈旧但权限变更需要更严格失效;这些是为了比较策略的训练假设。
  • key 至少包含 tenant_id、对象 ID、schema/version 与影响响应的权限维度,值带生成时间和失效版本;敏感数据不允许跨租户共用同一个 cache key。

解题路线

  1. 先定访问路径:read 用 cache-aside,命中返回;未命中从 DB 读并填充短 TTL,写操作先提交 DB,再发布带版本的失效事件。DB 是事实源,缓存更新/失效失败要靠 TTL 兜底与对账,不能让缓存成为不可恢复的主数据。
  2. 逐出拆两层:TTL 控制最长陈旧时间,内存压力下 LRU 适合近期热点、LFU 更偏长期稳定热点。不能把 TTL 当内存容量策略,也不能假设 LRU/LFU 对所有负载都最优;按对象大小、命中率与工作集漂移实测。
  3. 节点使用一致性哈希或虚拟分片把 key 映射到持有节点,副本用于节点故障读服务。失效事件按 key/version 幂等应用,旧版本事件不能抹掉新值;节点掉线或消费者积压时缩短 TTL、旁路读 DB 或批量重建,明确读陈旧的业务边界。
  4. 热键会把一个分片打满,不能只靠增加普通分片解决。可对热点做多副本读、进程本地极短缓存、请求合并与抖动过期;miss 风暴用 single-flight 和限流保护 DB。对于权限/撤权等强约束数据,考虑不缓存、同步版本校验或短 TTL,而非沿用普通对象缓存策略。
  5. 观测按租户、分片和 key 分布记录命中率、p50/p99 延迟、驱逐率、内存碎片、失效积压、DB 回源 QPS、热点占比和版本落后;压测命中/未命中、节点故障、批量过期和写入风暴。

手动走一遍

训练例:tenant A 的对象 42 热度突然占读量 20%。该 key 在单分片上造成 p99 上升;先用 per-key 指标确认热点,再短期启用请求合并和本地 1 秒缓存,并对该 key 做多副本读。对象更新时 DB 提交版本 18,失效消息把各副本的版本 17 清除;若版本 16 事件晚到,不应错误覆盖已缓存的 18。

规模与取舍

示例 10 万读/秒且 95% 命中时,理论上仍有约 5000 次/秒回源,未计写入、过期尖峰和热点;命中率掉到 80% 时变成约 2 万次/秒回源。容量按工作集对象数×平均对象字节数,再加索引、复制和碎片余量估算。分片数由内存、单节点 QPS、网络和故障恢复时间共同限制,不能只按平均流量分配。

易错点与追问

容易失分的边界

  • key 不含 tenant 或权限维度,导致跨租户/越权缓存污染。
  • 只设 TTL 却声称删除后立即不可见;严格撤权需要更强失效或绕过缓存。
  • 把失效消息当作绝不丢失,缺少 TTL 兜底、版本校验和对账。
  • 扩普通分片来解决单个 hot key;同一个 key 仍映射到一个持有分片。
  • 缓存全体同时过期导致 DB 雪崩,没有过期抖动、请求合并和回源限流。

继续深挖

  • 如何处理多区域缓存与跨区写入?先定义写主、传播延迟和读一致性,再决定是否允许旧版本。
  • 若缓存值大小悬殊,单纯按条数 LRU 会怎样影响容量?可增加字节预算和大对象保护。
  • 若某些读取必须 read-your-writes,如何在提交后绕过缓存、同步更新或携带最低版本?
  • 节点扩缩容时如何迁移虚拟分片并限速预热,避免瞬间回源峰值?
✓已复制微信号!