Redis
Redis(Remote Dictionary Server)是开源的内存数据结构存储,2009 年由 Salvatore Sanfilippo 创建。Redis 可用作数据库、缓存和消息队列,以其极高的性能(单节点 10 万+ QPS)和丰富的数据结构著称。
适用场景:热点数据缓存、分布式锁、实时计数器、轻量级消息队列、排行榜、分布式 Session、限流、位图统计。当需要持久化、丰富的数据结构或单线程原子性保证时,Redis 优于 Memcached。
核心机制
数据结构
Redis 支持五种核心数据结构:String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Sorted Set(有序集合)。每种数据结构都有对应的底层实现和典型应用场景。
String 是最基础的数据结构,用于缓存、计数器、分布式锁等场景。Hash 适合存储对象类型数据。List 支持两端操作,可用于消息队列。Set 支持集合运算,适合去重、标签等场景。Sorted Set 按分数排序,天然适合排行榜。
持久化机制
Redis 提供 RDB 和 AOF 两种持久化方式。RDB 在某个时间点将数据写入临时文件,适合容灾恢复,启动效率高。AOF 记录所有写操作命令,数据安全性更高,支持 always、everysec、no 三种刷盘策略。
数据重要时建议同时开启 RDB 和 AOF,使用 AOF 恢复数据。
淘汰策略
当 Redis 内存使用达到上限时,会触发淘汰策略。常用策略包括 volatile-lru(淘汰有过期时间的最近最少使用数据)、allkeys-lru(淘汰任何最近最少使用数据)、volatile-ttl(淘汰即将过期的数据)等。
数据呈幂律分布推荐 allkeys-lru,设置键的过期时间本身也消耗内存,因此 allkeys-lru 比 volatile-lru 更省内存。
集群架构
主从复制
配置主从复制实现读写分离,主服务器创建 RDB 文件传输到从服务器加载到内存。
哨兵(Sentinel)
自动故障恢复系统,监控主服务器状态,自动进行主从切换。
集群(Cluster)
Redis 3.0+ 引入的分布式方案,使用 CRC16 算法将数据分片存储在 16384 个槽位中。每个节点负责一部分槽位,支持自动故障转移和数据自动分片。
Redis 并不能保证数据的强一致性,集群节点间使用异步复制。
配置管理
配置 提供了 Redis 配置文件的完整参考,包括网络配置、持久化配置、内存配置、安全配置、集群配置等。
关键配置项:
maxmemory:最大内存限制maxmemory-policy:淘汰策略选择appendfsync:AOF 刷盘策略cluster-enabled:集群模式开关
客户端使用
Java 客户端
生产环境推荐使用 Redisson,它封装了完善的分布式锁逻辑,支持 watchdog 自动续期。Jedis 是较基础的客户端,提供较全面的 Redis 命令支持。
与 Memcached 对比
Redis 相比 Memcached 的主要优势:
- 支持更丰富的数据结构(5 种 vs 只有 String)
- 支持数据持久化
- 支持主从复制和集群
- 单核性能更高(小数据场景)
Memcached 的优势在于多核性能(大数据场景)和更简单的架构。
常见问题处理
缓存穿透
查询数据库中不存在的数据,每次都绕过缓存直击数据库。解决:缓存空值(短 TTL)或布隆过滤器拦截。
缓存击穿
热点 key 过期瞬间,大量并发涌入数据库。解决:互斥锁(仅允许一个线程重建缓存)或热点数据永不过期。
缓存雪崩
大量 key 同时过期,大量请求打到数据库。解决:随机化 TTL + 多级缓存 + Redis 高可用。
内存溢出
- 检查
maxmemory配置是否合理 - 使用
INFO memory查看内存使用情况 - 配置合适的淘汰策略
大 Key 问题
单个 key 的 value 过大(如超过 10KB)会导致 Redis 阻塞。使用 redis-cli --bigkeys 扫描大 key,将大 key 拆分为多个小 key 或使用 Hash 分片存储。
热点 Key 问题
单个 key 被高频访问导致单节点过载。解决:本地缓存 + Redis 多级缓存、使用读写分离分散压力、key 拆分到多个 slot。