# 十一、Redis梳理
# 1. Redis 基础概念
- Redis:开源的、基于内存的高性能键值对存储数据库,支持多种数据结构。
- NoSQL:与关系型数据库不同,Redis 是非关系型数据库,数据是以键值对的形式存储。
- 单线程模型:Redis 使用单线程处理请求,但由于其基于内存操作、非阻塞 I/O 等机制,性能非常高。
# 2. Redis 数据类型
String(字符串):
- 最基本的数据类型,每个键对应一个字符串值,最大可存储 512MB。
- 常用命令:
SET
、GET
、INCR
、DECR
、MSET
、MGET
。
Hash(哈希表):
- 类似于 Java 中的
HashMap
,用于存储键值对集合。 - 常用命令:
HSET
、HGET
、HGETALL
、HMSET
。
- 类似于 Java 中的
List(列表):
- 双向链表,可以按顺序存储多个字符串,支持从两端操作元素。
- 常用命令:
LPUSH
、RPUSH
、LPOP
、RPOP
、LRANGE
。
Set(集合):
- 无序集合,自动去重,常用于去重操作。
- 常用命令:
SADD
、SREM
、SMEMBERS
、SISMEMBER
。
Sorted Set(有序集合):
- 与
Set
类似,但每个元素关联一个分数,元素按分数排序。 - 常用命令:
ZADD
、ZRANGE
、ZREM
、ZREVRANGE
。
- 与
Bitmaps:
- 基于位操作的存储方式,常用于统计和标记。
HyperLogLog:
- 用于基数统计,支持大规模数据去重,使用少量内存估算独立元素的数量。
# 3. Redis 持久化
RDB(Redis Database Backup):
- 通过快照保存数据到磁盘,定期生成数据副本。
- 优点:备份数据量小,恢复快。
- 缺点:可能会丢失最后一次快照之后的数据。
AOF(Append Only File):
- 记录每次写操作日志,服务器重启时通过重放日志来恢复数据。
- 优点:数据更安全,丢失的风险小。
- 缺点:文件体积大,重放日志速度慢。
持久化策略:
- 可以同时启用 RDB 和 AOF,通过综合使用两者来实现数据的安全性和性能的平衡。
# 4. Redis 事务
- 事务概念:Redis 的事务是一组命令的集合,保证这些命令按照顺序执行。
- 事务的执行:
- 使用
MULTI
开启事务。 - 使用
EXEC
提交事务。 - 使用
DISCARD
取消事务。
- 使用
- 事务的特点:
- Redis 事务不具备真正的隔离性,没有回滚机制,如果其中某个命令出错,其他命令仍会执行。
- 支持乐观锁机制,通过
WATCH
命令实现。
# 5. Redis 发布/订阅(Pub/Sub)
- 发布/订阅模型:支持消息通信模型,一个客户端发布消息,其他订阅相同频道的客户端会接收到消息。
- 命令:
PUBLISH
:发布消息。SUBSCRIBE
:订阅频道。UNSUBSCRIBE
:取消订阅。
# 6. Redis 主从复制
- 主从复制:Redis 支持主从架构,主节点负责写操作,从节点负责读操作,从节点通过同步主节点的数据保持一致。
- 命令:
SLAVEOF
:从节点设置主节点,开始数据同步。PSYNC
:用于增量复制,确保从节点只同步变化的数据。
- 复制的优点:
- 提高可用性,主从切换可以在主节点宕机时迅速恢复服务。
- 提高性能,读写分离使得读操作负载分摊到从节点。
# 7. Redis 哨兵(Sentinel)
- Redis Sentinel:用于实现高可用,监控 Redis 实例,自动进行故障转移。
- 功能:
- 监控主从节点的运行状态。
- 主节点故障时,自动选举新的主节点并进行切换。
- 命令:
SENTINEL MONITOR
:监控主节点。SENTINEL FAILOVER
:手动触发故障切换。
# 8. Redis 集群
- Redis Cluster:分布式方案,允许将数据分布在多个节点上,通过分片(Sharding)实现扩展性。
- 槽(Slot)机制:集群中的每个节点都负责一部分槽,每个槽对应一定范围的键。
- 无中心化:Redis 集群没有中心节点,所有节点彼此平等。
- 故障转移:当节点宕机时,集群会自动进行故障转移。
# 9. Redis 高可用与容灾
- 读写分离:通过主从架构实现读写分离,主节点负责写,从节点负责读。
- 哨兵模式:通过 Redis Sentinel 监控 Redis 实例并进行自动故障转移。
- 集群模式:通过 Redis Cluster 提供分布式存储,避免单点故障。
# 10. Redis 缓存策略
- 缓存穿透:查询不存在的数据时,直接打到数据库上,导致缓存失效。解决办法是对不存在的数据进行缓存,设置一个较短的失效时间。
- 缓存击穿:在热点数据失效的瞬间,大量请求同时打到数据库上。解决办法是给缓存的关键数据设置锁机制或提前更新缓存。
- 缓存雪崩:大批缓存同时失效导致数据库压力陡增。解决办法是错开缓存失效时间,或者采用多级缓存架构。
# 11. Redis 内存淘汰策略
- 当 Redis 内存达到上限时,Redis 会根据配置的策略淘汰部分数据:
- noeviction:不删除数据,新请求直接返回错误。
- allkeys-lru:使用 LRU 算法淘汰最久未使用的键。
- volatile-lru:只淘汰设置了过期时间的键,并使用 LRU 算法。
- allkeys-random:在所有键中随机删除。
- volatile-random:在设置了过期时间的键中随机删除。
- volatile-ttl:优先删除过期时间最短的键。
# 12. Redis 分布式锁
- 原理:通过
SETNX
命令实现,SETNX
保证只有一个客户端可以设置成功。 - 注意事项:
- 设置锁的有效期,避免因客户端崩溃导致死锁。
- 使用
Redlock
算法实现分布式环境下的锁机制,避免单点故障和竞争条件。
# 13. Redis 与其他缓存的比较
- Redis vs Memcached:
- 数据类型:Redis 支持多种数据结构,Memcached 只支持字符串。
- 持久化:Redis 支持 RDB 和 AOF,Memcached 不支持持久化。
- 性能:Redis 在某些场景下性能优于 Memcached,尤其是处理复杂数据结构时。
# 14. Redis 优化与性能调优
- 内存优化:通过合理设置最大内存、使用合适的数据结构、减少内存碎片来优化 Redis 的内存使用。
- 网络优化:使用短连接、减少命令返回的字节数、批量操作等手段优化 Redis 网络性能。
- 并发优化:通过 Redis Cluster 扩展水平性能,或者使用主从复制和读写分离提高并发能力。