分布式缓存技术深度解析:Redis vs Memcached

Executive Summary

核心观点(金字塔原理)

结论先行: 在分布式缓存选型中,Redis因其丰富的数据结构、持久化能力和原生集群支持,更适合作为主流缓存方案;Memcached则在纯KV场景下凭借多线程模型具有更高的吞吐量优势。

支撑论点:

  1. 架构差异:Redis采用单线程IO复用模型保证原子性,Memcached采用多线程模型提升并发处理能力
  2. 功能边界:Redis支持5+数据结构、持久化、事务;Memcached仅支持KV且无持久化
  3. 扩展方案:Redis Cluster原生支持分布式,Memcached依赖客户端一致性哈希

SWOT 分析

维度 Redis Memcached
S 优势 丰富数据结构、持久化、原生集群、事务支持 多线程高吞吐、内存管理无碎片、协议简单
W 劣势 单线程CPU计算阻塞、内存碎片问题 无持久化、数据结构单一、客户端分布式复杂
O 机会 适合复杂业务场景、可作为消息队列/存储使用 简单KV缓存场景、Session存储
T 威胁 大Key阻塞、全量同步资源消耗大 冷启动数据丢失、Slab空间浪费

适用场景

  • 选择Redis:需要复杂数据结构、数据持久化、分布式锁、排行榜、实时消息等场景
  • 选择Memcached:纯KV缓存、极致吞吐量、短期Session存储等简单场景

缓存基础

缓存适用场景

  • 性能优化:减少后端计算和IO压力
  • 资源占用:降低数据库连接数和查询频率

缓存分类

进程内缓存

  • ConcurrentHashMap
  • LRUMap
  • Ehcache
  • GuavaCache
  • Caffeine

分布式缓存

  • Memcached:吞吐量较大,只支持key-value数据结构,并且不支持持久化
  • Redis:支持丰富的数据结构,读写性能很高,但是数据全内存,必须要考虑资源成本,支持持久化
  • Tair:支持丰富的数据结构,读写性能较高,部分类型比较慢,理论上容量可以无限扩充

缓存常见问题

问题 描述 解决方案
缓存穿透 查询不存在的数据,请求直达DB 布隆过滤器、空值缓存
缓存击穿 热点Key过期瞬间大量请求 互斥锁、永不过期+异步更新
缓存雪崩 大量Key同时过期 过期时间随机化、多级缓存
缓存污染 冷数据占用热数据空间 LRU/LFU淘汰策略
数据不一致 缓存与DB数据不同步 更新串行化、延迟双删

数据一致性详解:缓存更新与删除的并发可能会出现脏数据,如果能保证更新/删除的一致性,就能解决问题。想要做到缓存更新一致性,只要做到更新串行化即可。通常client路由到指定节点进行操作,保证串行化,比如根据key hash。对同一个缓存key,进行串行化更新。跨机房情况,由更新server同步更新所有机房数据,不依赖replica机制,能避免延迟导致的脏数据。


Redis vs Memcached 深度对比

网络模型

Redis

  1. 单线程IO复用模型:封装AeEvent事件处理框架,主要实现了epoll、kqueue和select
  2. 性能特点:单线程保证原子性,但CPU密集型计算(排序、聚合等)会阻塞整体IO调度

Memcached

  1. 多线程非阻塞IO复用模型:Master主线程 + Worker子线程架构
  2. 性能特点:更好利用多核CPU,但带来数据一致性和锁同步问题(如stats命令需要加锁)

数据类型

Redis

  • String、List、Set、ZSet(Sorted Set)、Hash
  • 附加功能:Pub/Sub、Transactions

Memcached

  • 仅支持Key-Value形式
  • 内存中维护巨大的HashTable,查询时间复杂度O(1)

数据持久化

Redis

支持两种持久化方式:

  1. RDB(快照):将某一时刻的所有数据写入硬盘
  2. AOF(只追加文件):执行写命令时,将命令复制到硬盘

Memcached

  • 不支持持久化:所有数据以in-memory形式存储

数据一致性

Redis

  • 不提供CAS命令,但通过事务保证原子性
  • 事务命令:MULTIDISCARDEXECWATCHUNWATCH
  • 事务特性:满足原子性、一致性、隔离性,不满足持久性
  • 注意:Redis不提供事务回滚机制

Memcached

  • 提供CAS命令,保证并发访问同一数据的一致性

内存管理

Redis

  • 通过zmalloc.hzmalloc.c实现内存管理
  • 分配内存时将size存入内存块头部,便于释放
  • 使用数组zmalloc_allocations记录各大小内存块分配情况
  • Virtual Memory:内存不足时可将冷数据swap到磁盘
  • 特点:简单的malloc/free包装,可能产生内存碎片

Memcached

  • Slab Allocation机制
    • 预分配大块内存,分割成不同尺寸的Chunk
    • 相同尺寸的Chunk组成Slab Class
    • Growth Factor控制Chunk大小递增
  • 优点:无内存碎片,分配效率高
  • 缺点:固定Chunk大小导致空间浪费

集群管理

Redis

  • Redis Cluster:原生分布式支持
    • 去中心化架构,节点间二进制协议通信
    • 16384个哈希槽(非4096),算法:crc16(key) % 16384
    • Master-Slave结构保证高可用
    • 自动故障转移:Master宕机时Slave自动提升

Memcached

  • 本身不支持分布式
  • 依赖客户端实现一致性哈希分布

Redis 高可用架构

主从复制(replication.c)

同步方式

  1. 全同步(SYNC):首次连接或无法增量同步时
  2. 部分同步(PSYNC):断线重连后的增量同步

全同步流程

1. 从节点 → SYNC → 主节点
2. 主节点执行 BGSAVE 生成 RDB
3. 主节点发送 RDB 文件流
4. 从节点清空缓存,载入 RDB
5. 主节点发送 Buffer 中的写命令

关键配置参数

参数 说明 建议值
repl-timeout 复制超时时间 根据RDB大小调整,默认60s
client-output-buffer-limit replica 复制缓冲区限制 256m 64m 60
repl-disable-tcp-nodelay TCP延迟控制 no(低延迟)/ yes(省带宽)

全同步资源消耗

阶段 资源消耗
BGSAVE生成RDB CPU(Fork子进程)
Copy-on-Write 内存(页面复制)
RDB持久化 磁盘IO
RDB传输 网络带宽
RDB加载 从节点阻塞

部分同步条件

  1. 复制积压缓冲区:FIFO环形队列,默认1MB
  2. 复制偏移量:主从各自维护
  3. 主节点runId:标识主节点身份

参考资料

  • Redis源码:https://github.com/redis/redis
  • Redis 3.0注释版:https://github.com/huangz1990/redis-3.0-annotated
  • Memcached LRU机制:http://timyang.net/data/Memcached-lru-evictions/