约束即立场:必须二选一、理由扣背景、要边界
你是不是见过这样的回答:”A 有这些优点,B 有那些优点,具体选哪个,要看你的业务场景。”——正确,但没用。你拿着它去评审会,跟没说一样。
今天这一讲,咱们就治这个”和稀泥”(hedging)。
问题一:它真的爱和稀泥吗?
我做选型实验的时候,预期是这样的:朴素提示词一问,它就会”各有优缺点,看场景”。结果呢?它开场就是一句:「结论:优先选 Redis。」连什么时候该换 Memcached 都说了。
翻车的是我的预期,不是模型。所以这一讲也得把丑话说前面:和稀泥不是它每次都会犯的病,是我们得防的病。
那既然它敢选,问题还成立吗?成立,只是换了个位置。你仔细看它给的东西:一张教科书式的对比表(数据模型、线程模型、持久化……),然后才夹一点场景分析。评审会上,别人一问”这跟我的 500 万订单有什么关系”,这张表就废了。
它敢选了,但它给的还是”通用答案”,不是”你的答案”。这才是今天要解决的真问题。
问题二:怎么把”通用答案”逼成”你的答案”?
我的工程化提示词加了三条:
① 必须二选一,给明确答案,不许说”看场景”;
② 给三条决定性理由——每条理由必须扣着我给的背景说(订单量、读写比、团队规模),不要放之四海皆准的对比;
③ 说清楚什么时候不成立——如果我的业务变成什么样,就该换另一个。
它的输出,每条理由开头就是”扣日订单 500 万””扣读写比 20:1″”扣团队 5 个后端”:
「扣”日订单 500 万”:500 万日订单会自然长出用户订单列表、状态分页、按时间排序等读路径。Redis 可以用 Hash 存订单详情、ZSet 存用户订单列表……Memcached 只有 KV,遇到这些场景要么大量回源,要么应用层做复杂拼装。」
看到差别没有?对比表谁都会给,扣背景的理由才是选型。第 ② 条提示词是整个案例的灵魂——你不把背景给它,它就只好给你教科书。
展开看实测原文(朴素 vs 工程化,沈剑2026-09-20实测:deepseek-flash,可复现,均为独立session以排除上下文影响)
朴素提示词
我们的订单查询系统要加缓存,Redis 和 Memcached 哪个好?给我个对比。
背景:日订单 500 万,读多写少(读写比约 20:1),现有 MySQL 主从。高峰期查询 p99 800ms,要加一层缓存。团队 5 个后端。
朴素输出(开场就选 Redis+通用对比表+附赠落地架构)
**结论:优先选 Redis。**
你们这个量级(日订单 500 万、读写比 20:1)Redis 和 Memcached 在性能上都扛得住,关键差异不在“能不能扛 QPS”,而在**数据结构、高可用、集群、一致性辅助能力、运维生态**。订单查询系统通常需要缓存详情、用户订单列表、状态计数、幂等/锁等,Redis 更合适。5 人后端团队也建议优先云托管 Redis,少自建复杂集群。
## Redis vs Memcached 对比
| 维度 | Redis | Memcached |
|---|---|---|
| 数据模型 | String/Hash/List/Set/ZSet/Bitmap/HLL/Stream 等 | 纯 KV |
| 线程模型 | 命令执行单线程,6+ 多线程 IO;可多实例/Cluster 扩展 | 多线程,单机多核利用好 |
| 持久化 | RDB/AOF,可重启恢复 | 无,重启全丢 |
| 高可用 | 主从、Sentinel、Cluster | 无原生复制,靠客户端分片 |
| 集群分片 | 原生 Redis Cluster | 客户端一致性哈希 |
| 过期/淘汰 | TTL、LRU/LFU、定期+惰性删除 | TTL、LRU |
| 原子能力 | 事务、Lua、WATCH、SETNX 等 | CAS、incr/decr 有限 |
| 内存效率 | 对象开销较高,但结构灵活 | slab 预分配,简单 KV 内存效率高 |
| 运维生态 | 成熟,云托管多,资料多 | 简单但生态弱,云服务逐渐减少 |
| 适合场景 | 复杂缓存、锁、计数、队列、会话、排行榜 | 简单 KV、小对象、纯缓存 |
## 结合你的场景
日订单 500 万,读写比 20:1:
- 读请求约:500 万 × 20 = 1 亿/天
- 平均读 QPS:约 1150
- 平均写 QPS:约 58
- 总平均 QPS:约 1200
- 高峰按 10 倍算:约 1.2 万 QPS
这个量级 Redis 单实例都能轻松处理,Memcached 也没问题。所以选型重点不是性能,而是:
1. **订单查询通常不是单一 KV**
可能按订单号查详情、按用户查订单列表、按状态分页、计数等。Redis 的 Hash/List/ZSet 更自然。Memcached 只能自己做序列化,复杂结构支持弱。
2. **高可用要求高**
缓存挂了不能把 MySQL 打崩。Redis 有 Sentinel/Cluster,Memcached 节点挂掉后通常部分缓存失效,容易回源雪崩。
3. **更新一致性更容易做**
读多写少,适合 Cache Aside:读缓存未命中查 MySQL 回填;写 MySQL 成功后删缓存。Redis 可配合 Lua、分布式锁、binlog/Canal 异步删缓存。Memcached 能力更弱。
4. **团队 5 人,运维成本要低**
Redis 云托管成熟,监控、扩容、备份、告警都更方便。Memcached 自建客户端分片和扩容更麻烦。
5. **容量估算**
假设一条订单缓存 1KB,日新增约 5GB。缓存最近 7 天约 35GB,30 天约 150GB,列表/索引还会更多。Redis Cluster 可水平扩展;Memcached 也能分片,但高可用和扩容体验差。
## 推荐落地架构
- 选 **Redis 7.x,云托管集群版优先**。数据量小于 32GB 可先主从+Sentinel;更大或要水平扩展用 Redis Cluster,3 主 3 从起步。
- Key 设计示例:
- `order:detail:{orderId}` → Hash/String
- `user:orders:{userId}:{status}:page:{page}` → List/ZSet
- TTL 设 5~30 分钟,加随机抖动,避免雪崩。
- 更新策略:
- 先更新 MySQL,再删除缓存。
- 更稳的方式:订阅 binlog/Canal 异步删缓存,TTL 兜底。
- 防护:
- 空值缓存防穿透;
- 布隆过滤器防不存在订单;
- singleflight/互斥锁防击穿;
- 热点 key 可加本地缓存。
- 监控:
- 命中率、p99、内存、大 key、热 key、慢查询、连接数。
- 目标:缓存命中率 >90%,命中路径 p99 通常 <10ms。
- 注意:Redis 持久化不能替代 MySQL,缓存只做加速。
## 什么时候才选 Memcached?
只有满足这些条件才考虑 Memcached:
- 只做极简 KV 缓存;
- 对象小且固定;
- 不需要复制、持久化、数据结构、Lua、分布式锁;
- 团队已有成熟 Memcached 客户端分片和运维经验;
- 能接受节点故障后缓存大面积失效、回源压力上升。
否则,订单查询系统建议直接上 **Redis**。
工程化提示词
背景:日订单 500 万,读多写少(读写比约 20:1),现有 MySQL 主从。高峰期查询 p99 800ms,要加一层缓存。团队 5 个后端。
请帮我做缓存选型:Redis 还是 Memcached?
要求:
1. 必须二选一,给明确答案,不许说"看场景";
2. 给三条决定性理由——每条理由必须扣着我给的背景说(订单量、读写比、团队规模),不要放之四海皆准的对比;
3. 再说清楚:我这个选择什么时候会不成立?(如果我的业务变成什么样,就该换另一个)
工程化输出(三条理由明标扣背景+边界)
结论:**选 Redis,不选 Memcached。**
### 三条决定性理由
1. **扣“日订单 500 万”:订单缓存不是单纯 order_id 查详情,Redis 的数据结构更匹配。**
500 万日订单会自然长出用户订单列表、状态分页、待支付/待发货聚合、按时间排序等读路径。Redis 可以用 Hash 存订单详情、ZSet 存用户订单列表/时间线,列表和分页不必拆成大量 Memcached key 再在应用层拼装。Memcached 只有 KV,遇到这些场景要么大量回源 MySQL,要么应用层做复杂拼装,缓存收益会被吃掉。
2. **扣“读写比 20:1 + 高峰 p99 800ms”:核心风险是热点 key 失效/击穿,Redis 更能防回源雪崩。**
日订单 500 万、读写比 20:1,平均读约 1000+ QPS,峰值通常也就几千到万级,Redis 单实例/主从足够,Memcached 的多线程吞吐优势在这个量级用不上。但 p99 800ms 说明 MySQL 已经很紧,一旦热门订单 key 失效,必须能单飞重建、互斥回源、逻辑过期。Redis 有 TTL、Lua、SET NX PX 等能力;Memcached 的 CAS/incr 只能解决单 key,跨 key 原子和锁要应用层硬补,高峰期更容易把 MySQL 打穿。
3. **扣“团队 5 个后端”:人手有限,不能为缓存再养第二套中间件。**
订单业务除了缓存,通常还会需要状态变更锁、防重复支付/提交、限流计数、超时关单延迟队列等。Redis 可以顺手承接这些,避免“先上 Memcached,后面再补 Redis”变成双栈。对 5 个后端来说,双栈意味着双客户端、双监控、双故障排查、双容量管理,不划算。选 Redis 是用一个组件覆盖更多订单场景,降低总运维复杂度。
### 什么时候这个选择不成立,该换 Memcached?
如果业务退化成:**订单读路径只剩纯单 key 对象缓存**,只按 order_id/user_id 取整块 JSON;不需要用户订单列表、排序、聚合、原子多 key、分布式锁、计数、延迟队列、持久化;缓存全丢也能平滑回源;并且团队已有成熟 Memcached 平台,或者 QPS 高到要极致利用多核做纯 KV 吞吐、成本极度敏感——这时才该换 **Memcached**。
否则,以你现在“500 万日订单 + 20:1 读多写少 + 5 个后端 + MySQL p99 800ms”的背景,明确选 **Redis**。
问题三:不许它干什么,比让它干什么更重要?
第 ① 条「必须二选一,不许说看场景」,是这门课反复出现的招式:显式禁止默认模式。
回顾一下前面两讲它都是怎么被治住的:
第 1 讲的评审案例里,我说”不要使用’整体不错”思路清晰’这类开场白”——恭维就被禁掉了(点开看那次实测原文)。
第 2 讲的读代码案例里,我说”不要逐行翻译代码——我识字”——逐段翻译就被禁掉了。
发现规律了吗?模型的默认行为是省力路径,你光说”要什么”它还可能绕道,你直接说”别走这条路”,它反而就乖了。先说不要的,再说要的——这是本课最值得抄走的一句话。
带团队也一样:光说”要质量”没人理你,你说”不许直接合 master”,大家反而知道了边界。禁止,是最清晰的约束。
问题四:为什么”什么时候不成立”比”为什么”更值钱?
最后说第 ③ 条的另一半:要边界。
任何选型都有适用边界。你问”为什么选 Redis”,它能给你一百个理由;你问”什么时候不该选 Redis”,才看得出它是真懂还是背书。我的工程化输出把边界写得明明白白:
「如果业务退化成:订单读路径只剩纯单 key 对象缓存,不需要列表、排序、聚合、分布式锁、持久化……缓存全丢也能平滑回源;并且团队已有成熟 Memcached 平台——这时才该换 Memcached。」
立场 + 边界,才是一个完整的选型。只有立场没有边界,是迷信;只有边界没有立场,是和稀泥。
脱离业务的架构都是耍流氓。脱离边界的选型,也是。
实操演练
必做部分 + 一步加餐。准备一个你日常在用的 AI 助手。
检验一下
①你的立场型提示词 + 边界清单:用实操的选型,把提示词定稿(必须二选一 + 理由扣背景 + 显式禁止和稀泥),实测后记录:三条理由里有几条真扣了你的背景?它给的边界里,有没有一条是你不认同的?
这是资产库的第三格。
本讲实测来自沈剑的案例库 003(deepseek-flash,2026-09-20,独立会话,复现脚本和原始输出存档)。
(沈剑注:这一讲我尤其想说的是”要边界”。这么多年做架构评审,我看一个方案靠不靠谱,从来不是听它好在哪,是问它什么时候不行。)
但还有一个没解决的问题:它敢选边了,理由也扣背景了——可万一它”编”呢?给的 API 不存在、给的理由没根据,你看得出来吗?——第 4 讲,我们讲怎么让它别瞎编。
知其然,知其所以然。思路比结论更重要。
Anthropic 官方提示工程文档:Prompting best practices——「Be clear and direct」是本讲「约束即立场」的官方源头表述,值得对照原文精读。