🧠 一、核心工作机制
1. 两阶段哈希(Two-stage Hash)
-
阶段一(客户端):根据 key 和节点列表计算哈希,选择目标 memcached 节点。
-
阶段二(服务端):节点内部再次哈希,定位具体数据项(item)。
-
优点:客户端直接通信,节点间无通信,扩展性强。
2. LRU + 超时失效
-
内存不足时,优先淘汰过期数据,再淘汰最近最少使用的数据。
-
支持设置数据的存活时间(TTL),最长可达 30 天。
⚖️ 二、Memcached 与其他缓存对比
1. vs MySQL Query Cache
| 对比维度 | Memcached | MySQL Query Cache |
|---|---|---|
| 数据格式 | 任意数据结构 | 仅 SQL 查询结果 |
| 失效机制 | 可控,手动或超时 | 表更新即全部失效 |
| 扩展性 | 水平扩展,无锁 | 多核下全局锁,扩展差 |
| 内存使用 | 可集群化,利用多机内存 | 受单机内存限制 |
2. vs Local Cache(如 APC、mmap)
| 对比维度 | Memcached | Local Cache |
|---|---|---|
| 数据共享 | 集群共享,一致性较好 | 每台服务器独立,一致性差 |
| 网络延迟 | 有 | 无 |
| 内存限制 | 可扩展 | 受单机内存限制 |
| 失效机制 | 集群同步失效 | 需手动广播或超时 |
🛡️ 三、容错与冗余
1. 设计哲学:不内置冗余
-
Memcached 是缓存层,不是数据库。
-
节点失效时应从数据源(如数据库)重新加载数据。
2. 节点失效处理策略
-
忽略:暂时由其他节点承担。
-
移除节点:小心!默认哈希算法会导致大量缓存失效。
-
热备节点:接管 IP,避免哈希紊乱。
-
一致性哈希:推荐使用,节点变化时影响最小。
-
两次哈希:节点宕机时客户端重新哈希选择节点,但可能产生脏数据。
🚫 四、不支持的功能与限制
1. 身份验证
-
无内置身份验证机制。
-
依赖防火墙或 Unix Domain Socket 进行访问控制。
2. 批量导入导出
-
不推荐使用,可能引起服务暂停或数据不一致。
-
推荐使用 MogileFS + Memcached 或 MySQL 作为持久层。
3. 数据大小限制
-
Key 长度:≤ 250 字符。
-
Value 大小:≤ 1MB。
-
过期时间:最长 30 天。
🧩 五、内存管理与多线程
1. Slab 内存分配
-
内存被划分为不同大小的 chunk,按 slab 组织。
-
避免内存碎片,但可能造成内部浪费。
2. 多线程模式
-
1.2 版本后支持多线程,充分利用多核 CPU。
-
目前仍存在全局锁,未来优化方向是减少锁竞争。
✅ 六、适用场景与最佳实践
✅ 适合使用 Memcached 的场景:
-
高频读取、低频更新的数据。
-
需要水平扩展的缓存层。
-
可接受缓存丢失(非持久化)。
❌ 不适合的场景:
-
需要持久化存储的数据。
-
数据大于 1MB。
-
需要复杂查询或事务支持。
七、Memcached 常见问题及解决方案
1. 缓存雪崩
-
问题:大量缓存同时失效,导致请求直接打到数据库,造成数据库压力过大。
-
解决方案:
-
设置不同的过期时间,使缓存失效时间点均匀分布。
-
使用持久化存储(如数据库)的限流和降级策略。
-
使用锁或队列来控制读数据库和写缓存的线程数量。
-
2. 缓存穿透
-
问题:查询一个不存在的数据,由于缓存中没有,每次都会查询数据库。
-
解决方案:
-
布隆过滤器(Bloom Filter)快速判断数据是否存在。
-
将不存在的数据也缓存起来(设置较短的过期时间),避免频繁查询数据库。
-
3. 缓存击穿
-
问题:某个热点数据失效,大量请求同时访问这个数据,导致数据库压力过大。
-
解决方案:
-
设置热点数据永不过期。
-
使用互斥锁(mutex),在第一个请求去查询数据库时加锁,其他请求等待,直到缓存被重建。
-
4. 数据一致性
-
当数据库更新时,如何保证缓存与数据库的数据一致?
-
更新数据库后,删除缓存(先更新数据库,再删除缓存,避免并发问题)。
-
使用消息队列异步更新缓存。
-
设置缓存的过期时间,保证最终一致性。
-
📋 八、Memcached 面试题卡
🔵 基础概念类
1. Memcached 的工作原理是什么?
-
采用两阶段哈希机制
-
客户端根据节点列表选择目标节点(阶段一)
-
服务端内部哈希定位具体数据(阶段二)
-
无阻塞、基于事件驱动的架构
2. Memcached 的主要优势有哪些?
-
极佳的水平扩展性
-
节点间无通信,不会增加额外负载
-
轻量级,部署简单
-
高性能,支持多线程
3. Memcached 的缓存淘汰机制?
-
LRU(最近最少使用)算法
-
超时失效机制
-
内存不足时:过期数据 → 最老未使用数据
🔵 技术对比类
4. Memcached vs MySQL Query Cache
bash
# Memcached
✅ 任意数据结构
✅ 水平扩展
✅ 手动控制失效
❌ 需要应用层集成
# MySQL Query Cache
✅ 自动缓存SQL结果
❌ 表更新即全部失效
❌ 多核扩展性差
❌ 受单机内存限制
5. Memcached vs Local Cache
bash
# Memcached
✅ 集群数据一致
✅ 内存可扩展
❌ 有网络延迟
# Local Cache
✅ 无网络延迟
✅ 访问速度极快
❌ 数据不一致问题
❌ 单机内存限制
🔵 架构设计类
6. Memcached 如何实现高可用?
-
不内置冗余机制
-
节点失效时从数据源重新加载
-
推荐使用一致性哈希减少节点变化影响
-
可配置热备节点接管IP
7. 一致性哈希在Memcached中的作用?
-
节点增删时最小化缓存失效
-
避免传统哈希算法的"哈希紊乱"
-
大多数现代客户端库已支持
🔵 限制与约束类
8. Memcached 的主要限制有哪些?
bash
Key长度: ≤ 250字符
Value大小: ≤ 1MB
过期时间: ≤ 30天
身份验证: 无内置
数据持久化: 不支持
9. 为什么单个item限制为1MB?
-
内存分配器基于slab机制
-
不同slab的chunk大小按因子增长
-
1MB以上会导致内存利用率显著下降
🔵 实战场景类
10. 什么场景适合使用Memcached?
bash
✅ 高频读取、低频更新
✅ 需要水平扩展的缓存层
✅ 可接受缓存丢失
✅ 数据量 < 1MB
11. 什么场景不适合Memcached?
bash
❌ 需要持久化存储
❌ 数据 > 1MB
❌ 复杂查询需求
❌ 强一致性要求
📊 九、Memcached 技术对比表格
缓存方案选择矩阵
| 特性 | Memcached | Redis | MySQL Query Cache | Local Cache |
|---|---|---|---|---|
| 数据模型 | 键值对 | 丰富数据结构 | SQL结果集 | 任意数据 |
| 持久化 | 无 | 支持 | 无 | 无 |
| 集群支持 | 客户端分片 | 原生集群 | 无 | 无 |
| 内存限制 | 可扩展 | 可扩展 | 单机限制 | 单机限制 |
| 网络延迟 | 有 | 有 | 无 | 无 |
| 数据一致性 | 最终一致 | 可配置 | 强一致 | 难保证 |
| 适用规模 | 大规模 | 各种规模 | 小规模 | 单机应用 |
🎯 十、高级面试问题
架构设计题
1. 如何设计一个基于Memcached的缓存架构?
-
确定缓存策略:读穿透/写穿透/写回
-
设计键命名规范(如
type:id:field) -
选择哈希算法(一致性哈希)
-
规划缓存失效策略
-
设计监控和降级方案
2. 缓存雪崩/穿透/击穿的解决方案?
bash
# 雪崩 - 大量缓存同时失效
✅ 设置随机过期时间
✅ 永不过期 + 后台更新
# 穿透 - 查询不存在数据
✅ 布隆过滤器
✅ 缓存空值
# 击穿 - 热点key失效
✅ 互斥锁更新
✅ 永不过期热点数据
性能优化题
3. 如何监控和优化Memcached性能?
bash
监控指标:
- 命中率 (hit rate)
- 内存使用情况
- 网络流量
- 连接数
优化方向:
- 调整slab增长因子
- 优化key设计(短key省内存)
- 批量操作减少网络开销
- 合理设置过期时间
💡 十一、面试实战技巧
回答框架建议
STAR法则在缓存问题中的应用:
bash
S (Situation): 描述业务场景和缓存需求
T (Task): 明确缓存要解决的具体问题
A (Action): 采取的技术方案和设计决策
R (Result): 达到的性能提升和业务价值
常见陷阱提醒
-
不要过度依赖缓存 - 缓存是优化手段,不是核心逻辑
-
考虑缓存一致性 - 更新数据库时要同步更新缓存
-
准备降级方案 - 缓存集群故障时系统要能正常运行
-
监控是关键 - 没有监控的缓存等于盲人摸象
📚 十二、延伸学习资源
推荐阅读
实践建议
-
在本地搭建Memcached环境进行测试
-
尝试使用不同语言的客户端库
-
模拟节点故障,观察系统行为
-
使用监控工具分析缓存性能