强曰为道
与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

Memcached 完全指南 / 第 1 章:Memcached 简介

第 1 章:Memcached 简介

1.1 历史起源

Memcached 最初由 Brad Fitzpatrick 于 2003 年为 LiveJournal 开发,目的是解决高并发读取场景下的数据库压力问题。

发展时间线

时间事件
2003Brad Fitzpatrick 为 LiveJournal 开发初版
2004开源发布,迅速被 Facebook、YouTube、Twitter 等采用
2008Facebook 部署超过 28 台 Memcached 服务器,缓存 28TB 数据
2009Memcached 1.4 发布,引入二进制协议
2012引入多线程支持(-t 参数)
2017Memcached 1.5 引入 LRU 维护(lru_maintainer
2020Memcached 1.6 引入 meta 协议、TLS 支持
2024持续维护,广泛部署于全球各大互联网公司

核心设计理念

Memcached 的设计哲学可以用三个词概括:简单快速分布式

┌─────────────────────────────────────────────┐
│              Memcached 设计原则              │
├─────────────────────────────────────────────┤
│  1. K/V 存储:只做一件事,做到极致           │
│  2. 内存优先:数据只存在内存中,重启即丢失   │
│  3. 无持久化:不做 RDB/AOF,简化设计         │
│  4. 客户端分片:服务端无中心,客户端路由     │
│  5. O(1) 复杂度:所有操作常数时间            │
│  6. 懒惰删除:过期数据不立即回收,按需清理   │
└─────────────────────────────────────────────┘

1.2 核心特性

特性概览

特性说明
存储模型Key-Value,Value 最大 1MB(可配置)
数据类型仅 String(二进制安全)
持久化无,纯内存
集群方案客户端一致性哈希分片
线程模型多线程(主从 Reactor)
协议文本协议 / 二进制协议 / Meta 协议
过期策略惰性删除 + LRU 淘汰
原子操作incr / decr / CAS
内存管理Slab Allocator

为什么选择 Memcached?

场景一:纯粹的缓存层

如果你的需求是"查询 → 缓存 → 返回",不需要复杂数据结构,Memcached 是最佳选择:

# 典型缓存流程
Client → 查询 Memcached
  ├── 命中 → 直接返回(< 1ms)
  └── 未命中 → 查数据库 → 写入缓存 → 返回

场景二:大规模分布式缓存

Memcached 的客户端分片架构天然支持水平扩展:

                    ┌─── Memcached Node 1 (2GB)
Client ──哈希路由──┼─── Memcached Node 2 (2GB)
                    ├─── Memcached Node 3 (2GB)
                    └─── Memcached Node N (2GB)

1.3 适用场景

非常适合的场景

场景说明示例
数据库查询缓存缓存 SQL 查询结果,降低 DB 压力用户信息、商品详情
Session 存储分布式会话管理PHP Session Handler
页面片段缓存缓存渲染后的 HTML 片段导航栏、侧边栏
计数器/限流利用 incr/decr 原子操作API 限流、文章阅读量
Token 缓存短期 Token 存储JWT 黑名单、验证码
热点数据高频读取的小数据配置项、排行榜快照

不适合的场景

场景原因推荐方案
需要持久化数据重启丢失Redis / MySQL
复杂数据结构只支持 StringRedis(Hash/List/Set)
大 Value 存储默认最大 1MBRedis / 本地文件
发布订阅不支持 Pub/SubRedis / RabbitMQ
数据分析无聚合能力Redis / ClickHouse
事务操作无 MULTI/EXECRedis

1.4 Memcached vs Redis

这是最常被问到的问题。两者都是优秀的内存缓存,但定位不同。

架构对比

Memcached 架构:                    Redis 架构:
┌──────────────┐                   ┌──────────────┐
│   Client     │                   │   Client     │
│ (一致性哈希) │                   │              │
└──┬───┬───┬───┘                   └──────┬───────┘
   │   │   │                              │
   ▼   ▼   ▼                              ▼
┌──┐ ┌──┐ ┌──┐                    ┌──────────────┐
│N1│ │N2│ │N3│  ← 无中心          │ Redis Server │ ← 有中心
└──┘ └──┘ └──┘                    │  (主从/集群)  │
                                  └──────────────┘

功能对比表

维度MemcachedRedis
数据结构String OnlyString / Hash / List / Set / ZSet / Stream
持久化RDB + AOF
集群客户端分片Redis Cluster / Sentinel
多线程原生多线程6.0+ 多线程 I/O
内存效率更高(Slab 预分配)较低(jemalloc 碎片)
单 Value 限制1MB(可调)512MB
原子操作incr/decr/CAS丰富(Lua/Transaction)
发布订阅不支持支持
Lua 脚本不支持支持
过期策略惰性 + LRU惰性 + 定期
协议复杂度简单RESP 协议
运维复杂度中高(集群模式)
内存开销/Key~70 bytes~100+ bytes
适用规模超大规模缓存中大规模 + 业务逻辑

性能对比(单节点,小 Value)

操作MemcachedRedis备注
GET (100B)~200K QPS~180K QPS同等硬件
SET (100B)~180K QPS~160K QPS同等硬件
内存效率1x1.2-1.5xMemcached 更省
延迟 P99< 1ms< 1ms无显著差异
连接数上限数万数万取决于配置

注意:以上数据为参考值,实际性能受硬件、网络、Value 大小、并发量等因素影响。

选型决策树

需要持久化?
  ├── 是 → Redis
  └── 否 → 需要复杂数据结构?
              ├── 是 → Redis
              └── 否 → 需要发布订阅/Lua 脚本?
                          ├── 是 → Redis
                          └── 否 → 纯缓存 + 大规模 + 高吞吐?
                                      ├── 是 → Memcached ✓
                                      └── 否 → 两者均可(团队熟悉度决定)

1.5 谁在使用 Memcached?

大规模部署案例

公司规模用途
Facebook数万台,PB 级缓存社交图谱、News Feed
Twitter数千台Timeline 缓存
YouTube数千台视频元数据
Wikipedia数百台页面缓存
Slack数百台会话与消息缓存
GitHub内部使用API 结果缓存

Facebook 的经典架构

Facebook 在 2013 年的 USENIX 论文《Scaling Memcache at Facebook》中描述了其架构:

用户请求
    │
    ▼
┌─────────┐     ┌──────────┐     ┌───────────┐
│ Web 层  │────▶│ McRouter  │────▶│ Memcached │
│ (PHP)   │     │ (代理层)  │     │  集群     │
└─────────┘     └──────────┘     └───────────┘
    │                                  │
    ▼                                  ▼
┌─────────┐                    ┌───────────┐
│ MySQL   │◀────── 失效通知 ───│ 集群间    │
│ 集群    │                    │ 复制      │
└─────────┘                    └───────────┘

1.6 Memcached 的局限性

了解局限性同样重要:

已知限制

限制项说明解决方案
无持久化重启数据丢失上层补偿(DB 回源)
单线程命令执行命令串行处理1.6+ 改进
最大 Key 长度250 字节合理设计 Key
最大 Value1MB(默认)拆分或外部存储
无集群管理需客户端/MC Router使用代理层
LRU 全局Slab 级别 LRUlru_maintainer
无访问控制无 ACLSASL / 网络隔离

1.7 本教程路线图

基础篇(第 1-5 章)
  ├── 了解 Memcached(你在这里)
  ├── 安装与部署
  ├── 架构原理
  ├── 核心命令
  └── 数据类型与序列化

进阶篇(第 6-10 章)
  ├── Slab 分配器详解
  ├── LRU 淘汰策略
  ├── 一致性哈希
  ├── 多线程模型
  └── 通信协议

运维篇(第 11-14 章)
  ├── 安全加固
  ├── 监控与告警
  ├── 性能优化
  └── Docker 部署

实战篇(第 15-16 章)
  ├── 多语言客户端
  └── 生产最佳实践

1.8 快速体验

如果等不及看完全部教程,可以先用 Docker 快速体验:

# 启动 Memcached
docker run -d --name mc-test -p 11211:11211 memcached:1.6-alpine

# 安装命令行客户端
sudo apt-get install -y libmemcached-tools  # Debian/Ubuntu
# 或
brew install libmemcached                     # macOS

# 使用 telnet 连接(最简单的方式)
telnet localhost 11211

# 尝试基本操作
set mykey 0 3600 5       # 设置 Key,Flags=0,TTL=3600秒,5字节
hello                     # 值
STORED                    # 返回结果

get mykey                 # 获取
VALUE mykey 0 5           # 返回
hello
END

quit                      # 退出

扩展阅读

小结

要点内容
本质简单、快速的分布式内存 K/V 缓存
最大优势极致简单 + 极致性能 + 原生多线程
最大局限无持久化、仅 String、无集群管理
选型建议纯缓存场景优先考虑 Memcached