一篇题为《In praise of memcached》的技术博客,把一个老工具重新拉回了后端和 SRE 的视野。
有意思的地方不在于 memcached 多新。恰恰相反,它的价值来自“不够强”。当团队只需要 cache.set 和 cache.get 时,功能少的工具,反而更不容易把缓存层养成数据库。
这不是 Redis 不能做缓存。Redis 当然能做缓存,也有丰富数据结构和持久化能力。真正的问题是:很多系统一开始说“只是加个缓存”,后来业务代码却把 Redis 当成必须存在的数据源。
等到迁移、升级、扩容、故障恢复时,运维才发现:这个缓存已经不能随便丢了。
Redis 的风险,是边界太容易被跨过去
Redis 的强,很多时候正是误用的入口。
一个连接串交给业务团队后,set/get 比建表、写迁移脚本、处理约束轻松得多。短期看,这是效率。长期看,缓存层可能开始存会话、状态、配置,甚至一些半持久数据。
这时团队嘴上说它是缓存,系统行为却不承认。
如果 Redis 挂了,服务不能降级;如果数据丢了,业务无法恢复;如果要升级,必须像数据库一样设计窗口、备份和回滚。那它在架构图里叫什么已经不重要了。它事实上就是关键存储。
这不是 Redis 的错。Redis 提供能力,系统设计要承担边界。
对后端工程师和 SRE 来说,动作应该更具体:引入 Redis 前,先问这几个问题——这份数据能不能丢?丢了能不能从数据库重建?缓存未命中时接口能不能接受变慢?如果答案是否定的,就不要把它包装成“缓存需求”。
一个简短对比更直观:
| 维度 | Redis 用作缓存时的常见风险 | memcached 的默认约束 | 对团队的影响 |
|---|---|---|---|
| 持久性 | 可配置持久化,容易被依赖成可靠存储 | 不落盘,重启即丢 | 更强迫团队承认缓存可丢 |
| 功能边界 | 数据结构丰富,容易承载额外业务语义 | 目标单一,主要做对象缓存 | 少一些“顺手存一下”的空间 |
| 集群方式 | 可使用 Redis Cluster 等机制 | 通常由客户端配置节点并按 key 哈希 | memcached 更像无状态组件 |
| 故障处理 | 业务强依赖时,缓存故障会变成核心故障 | 客户端库常把异常转为空值或默认值 | 更容易走回源和降级路径 |
表里最关键的一行,是持久性。
Redis 可以持久化,这是优点。但如果团队没有明确数据责任,它也会放大误会:大家开始相信缓存里的东西“应该还在”。memcached 不给这个幻想。它停了,数据就没了。这个粗糙边界,反而保护了系统设计。
memcached 的价值,是让缓存保持像缓存
memcached 的定位很朴素:分布式内存对象缓存系统,用来减轻数据库负载。
它不落盘,也不试图成为通用数据平台。在典型部署里,客户端配置多个 memcached 节点,再按 key 做哈希选择目标节点。某个节点故障时,客户端可以把它从列表里剔除,过一段时间再尝试重连。
这套模型对 SRE 友好。
节点坏了,可以替换。缓存丢了,可以回源。客户端连接异常,很多库会返回默认值或空值,让应用继续走降级路径。服务可能慢一点,但不应该直接中断。
这就是 memcached 的现实价值:它把“缓存是易失的”写进了工具性格里。
适合它的场景也很清楚:热点对象缓存、页面片段缓存、短期计算结果缓存。数据源仍然是数据库或其他可靠存储,缓存只负责挡一部分重复请求。
但它不是 Redis 的全面替代品。
如果业务需要复杂数据结构、原子计数、队列语义、发布订阅,或者明确需要持久化能力,Redis 仍然可能是更合适的选择。把 memcached 捧成万能解法,和把 Redis 随手当数据库,本质上是同一种偷懒。
对正在做选型的团队,我更建议把决策写成一张检查表,而不是争论品牌:
| 问题 | 更偏向 memcached | 更偏向 Redis 或其他存储 |
|---|---|---|
| 数据能否丢失 | 能,丢了可回源 | 不能丢,或恢复成本高 |
| 需求是否只有 get/set | 基本只有对象缓存 | 需要复杂结构或更多语义 |
| 节点故障时能否降级 | 可以降级,只是变慢 | 不能降级,会影响核心流程 |
| 运维目标 | 少状态、少备份、易替换 | 需要明确持久化和恢复策略 |
这对两类人最直接。
后端工程师如果只是想给慢接口加一层热点缓存,可以优先评估 memcached,少给业务留下误用空间。SRE 如果已经发现 Redis 集群被当成数据库用,就不该只补监控和扩容,还要推动团队重新定义数据归属。
缓存选型前,先确认数据库问题有没有被处理
这篇文章最有用的提醒,其实不止在工具选择。
很多“数据库太慢”的问题,根源不是缺缓存,而是慢查询、缺索引、表结构不合理。缓存能挡住一部分流量,但挡不住错误的查询路径。
如果一个接口每次都扫大表,正确动作应该先看执行计划、补索引、改查询。直接加缓存,只是在命中率高的时候掩盖问题。
等缓存重启、热点变化、节点故障、命中率下降,压力会回到数据库。更麻烦的是,回来的时候往往更集中。
所以接下来该观察的不是 memcached 会不会“复兴”。更该看团队有没有把缓存契约写清楚:
- 哪些数据允许丢?
- 缓存未命中能不能回源?
- 节点故障时服务是变慢,还是直接失败?
- 有没有业务把缓存 key 当成唯一事实来源?
- 慢查询和缺失索引是否已经先处理?
这些问题答不清,换什么工具都只是换风险的名字。
回到开头那个反常点:memcached 重新被夸,不是因为它突然变强了,而是因为它足够克制。缓存之道,贵在可丢。工具越强,越要小心它被拿去承担没有说出口的责任。
