3.10 Redis 缓存服务安装与配置
预计阅读时间:18 分钟
📖 目录
学习目标
学完本章后,你将能够:
- 安装并配置 Redis 服务器
- 使用五种核心数据结构完成常见场景操作
- 理解 RDB 与 AOF 持久化的差异和适用场景
- 配置内存淘汰策略和过期时间
- 使用 Redis 实现缓存、计数器、队列等典型模式
核心知识
- Redis——高性能键值内存数据库,支持多种数据结构,常作缓存、会话存储、消息队列使用
- 字符串(String)——最基础类型,可存储字符串/整数/浮点数,最大 512MB
- 哈希(Hash)——键值对集合,适合存储对象(如用户信息)
- 列表(List)——按插入顺序排序的字符串集合,适合消息队列
- 集合(Set)——无序唯一字符串集合,支持交/并/差运算
- 有序集合(Sorted Set)——带分数的有序唯一集合,适合排行榜
- RDB 持久化——按间隔生成全量快照,文件紧凑但可能丢数据
- AOF 持久化——追加写操作日志,数据更安全但文件更大
- 内存淘汰(Eviction)——内存满时按策略移除键,常见策略 LRU、TTL
知识关联
- 前置知识:基本命令行操作、3.6:MySQL 数据库 MySQL/MariaDB 或 3.7:PostgreSQL 数据库 PostgreSQL(理解数据库概念)
- 对比技术:Redis 是内存 NoSQL 数据库,适合缓存/队列/计数器等场景,不适合持久化存储
- 配套使用:Web 应用中常用 PostgreSQL/MySQL + Redis 组合(持久层 + 缓存层)
- 后续影响:6.4:消息队列入门 消息队列入门(Redis Stream 做消息队列)、4.6:Linux 性能调优 性能调优(Redis 缓存命中率是关键指标)
原理讲解
为什么 Redis 这么快?
Redis 的单线程模型是设计核心——所有操作在单线程中顺序执行,避免了锁竞争和线程切换开销。配合纯内存操作和非阻塞 I/O(epoll),Redis 可以轻松达到数万 QPS。单线程也意味着每个命令都应快速执行(O(1) 或 O(log N)),KEYS、SMEMBERS 等 O(N) 命令可能阻塞其他操作。
为什么 Redis 用内存存储而不是磁盘?
Redis 的核心设计目标是极致的读写速度。内存的随机访问延迟约 100 纳秒,而 SSD 磁盘约 100 微秒——差了 1000 倍。对于缓存、会话存储、实时排行榜这类场景,延迟是第一优先级。Redis 把数据全部放在内存中,用单线程避免锁竞争,用 epoll 处理网络 I/O,三者叠加实现了微秒级的响应时间。
但这不意味着 Redis 不关心数据安全。RDB 和 AOF 持久化机制把内存数据异步写入磁盘,确保重启后数据不丢失。Redis 的定位是快速的数据结构服务器,而非通用数据库——它不支持复杂的 JOIN 查询、不支持事务回滚到任意时间点,这些由 MySQL/PostgreSQL 负责。典型架构是"Redis 做缓存 + 关系数据库做持久层"。
Redis vs Memcached:为什么 Redis 胜出?
| 维度 | Redis | Memcached |
|---|---|---|
| 数据结构 | String/Hash/List/Set/ZSet + 高级结构 | 仅 String(Key-Value) |
| 持久化 | RDB + AOF,支持重启恢复 | 无持久化,纯内存 |
| 集群 | Redis Cluster(原生分片) | 客户端分片 |
| 线程模型 | 单线程(6.0 起网络 I/O 多线程) | 多线程 |
| 内存效率 | 较高(小对象压缩编码) | 较高(slab 分配器) |
| 适用场景 | 缓存、队列、排行榜、分布式锁、计数器 | 纯缓存(如 HTML 片段、数据库查询结果) |
选型结论:如果只需要简单的 Key-Value 缓存,Memcached 够用且多线程性能好。如果需要复杂数据结构、持久化、发布订阅等功能,Redis 是不二之选。新项目几乎都选 Redis——它的功能是 Memcached 的超集。
RDB 与 AOF 的本质区别
RDB 是时间点快照——在某个时刻把整个内存数据集序列化到磁盘。优点是文件紧凑、恢复快;缺点是两次快照之间的数据可能丢失。AOF 是操作日志——把每条写命令追加到文件末尾。优点是最坏情况只丢 1 秒数据(appendfsync everysec);缺点是文件大、恢复慢(需要重放所有命令)。
生产环境推荐两者并用:AOF 保数据安全,RDB 做快速重启和冷备份。Redis 4.0+ 的混合持久化进一步优化:把 RDB 快照作为 AOF 文件的开头,兼顾了 AOF 的安全性和 RDB 的恢复速度。
Redis 数据结构详解
五种核心数据结构是 Redis 的立身之本。选型口诀:对象用 Hash、排队用 List、去重用 Set、排行用 ZSet、其余用 String。把 JSON 拼进 String 存对象、用 List 做去重,都是新手最常见的错误用法。
String(字符串)
最通用的类型,支持文本、整数、浮点与二进制数据(最大 512MB),并提供原子自增自减。典型命令:SET/GET、MSET/MGET(批量)、SETNX(不存在才设置)、INCR/DECR/INCRBY(计数)、APPEND(追加)、GETRANGE(截取)。
# 原子计数器(多进程并发调用也不会重复计数)
INCR article:1024:views
GETRANGE article:1024:views 0 4 # 截取前 5 位用于展示
# 分布式锁:SETNX + EXPIRE 合并为一条原子命令(Redis 2.6.12+ 支持)
SET lock:order:1001 token123 NX EX 10 # 抢锁成功返回 OK
DEL lock:order:1001 # 业务完成后释放
# 位图统计:SETBIT/GETBIT,1 亿用户日活统计仅需约 12MB 内存
SETBIT online:2026-07-30 user_1001 1
Hash(哈希)
键值对集合,适合存储对象:一次 HGETALL 取回整个对象,HGET 只取单个字段,比把整个对象序列化进 String 更省内存、更灵活。典型命令:HSET/HGET/HGETALL、HDEL、HLEN、HINCRBY(字段级计数)。
# 商品详情:字段多、需要局部更新的场景
HSET product:1024 name "机械键盘" price 399 stock 200
HINCRBY product:1024 stock -1 # 下单减库存(原子操作)
HGETALL product:1024
List(列表)
按插入顺序排列的双端队列,两端都可以 push/pop,复杂度 O(1)。典型命令:LPUSH/RPUSH、LPOP/RPOP、LRANGE、LTRIM(裁剪)、BRPOP(阻塞弹出)。
# 最新消息列表:LPUSH + LTRIM 只保留最近 100 条
LPUSH news:list "标题1" "标题2"
LTRIM news:list 0 99
LRANGE news:list 0 9 # 取最新 10 条
# 任务队列:BRPOP 阻塞等待,客户端不用空转轮询
BRPOP task:queue 0 # 0 = 无限等待
Set(集合)
无序、元素唯一,天然支持交/并/差运算——这是关系数据库做起来非常昂贵的操作。典型命令:SADD/SREM、SISMEMBER、SCARD、SINTER/SUNION/SDIFF。
# 共同关注:SINTER 一行命令完成
SADD user:1:follow "bob" "alice" "tom"
SADD user:2:follow "bob" "tom" "jerry"
SINTER user:1:follow user:2:follow # 交集:bob tom
# 抽奖去重:SADD 重复抽中无效,SCARD 统计参与人数
Sorted Set(有序集合)
每个元素带一个分数(score),按分数排序,同时保留 Set 的去重能力。典型命令:ZADD、ZINCRBY、ZRANGE/ZREVRANGE、ZRANK(查询排名)、ZSCORE、ZREMRANGEBYSCORE。
# 排行榜:分数实时变化,排名自动维护
ZADD leaderboard 100 "player1" 200 "player2" 150 "player3"
ZINCRBY leaderboard 30 "player1" # 加分后自动重排
ZREVRANGE leaderboard 0 2 WITHSCORES # 前三名
ZRANK leaderboard "player1" # 查询某玩家当前排名(从 0 开始)
# 延时队列:用时间戳当 score,ZRANGEBYSCORE 批量取到期任务
RDB vs AOF 持久化
| 特性 | RDB(快照) | AOF(追加日志) |
|---|---|---|
| 数据完整性 | 可能丢失两次快照间的数据 | 最多丢失 1 秒数据(appendfsync everysec) |
| 文件大小 | 紧凑(压缩的二进制) | 较大(文本日志,可重写压缩) |
| 恢复速度 | 快(直接加载到内存) | 慢(重放所有操作) |
| 对性能影响 | BGSAVE fork 子进程可能消耗内存 | 写时追加,影响较小 |
| 推荐场景 | 允许少量数据丢失、快速重启 | 数据安全性要求高 |
RDB 触发机制与 AOF 同步策略
RDB 快照有三种触发方式:save 规则(时间 + 改动次数双条件)、手动 BGSAVE、关闭服务时的自动保存。注意 save 900 1 不是"每 900 秒存一次",而是"900 秒内至少发生 1 次写才触发"。
# /etc/redis/redis.conf
save 900 1 # 900 秒内 ≥1 次写 → 快照
save 300 10 # 300 秒内 ≥10 次写 → 快照
save 60 10000 # 60 秒内 ≥10000 次写 → 快照
save "" # 用空值覆盖默认规则即可关闭 RDB
dir /var/lib/redis
dbfilename dump.rdb
rdbcompression yes # 快照压缩,默认开启;CPU 紧张可关闭换空间
appendfsync 三个选项的本质是"性能 vs 数据安全"的权衡:
| 策略 | 行为 | 风险 | 适用 |
|---|---|---|---|
always | 每次写命令都 fsync 到磁盘 | 最安全,但吞吐明显下降(可能损失 50%+ 性能) | 财务、交易类强一致场景 |
everysec | 每秒批量 fsync 一次(默认) | 最多丢 1 秒数据 | 绝大多数生产环境 |
no | 交给操作系统决定落盘时机 | 可能丢数秒到数十秒数据 | 只追求写入性能、可接受丢失 |
Redis 4.0 起支持混合持久化(aof-use-rdb-preamble yes):把 RDB 快照作为 AOF 文件的开头,重写后的 AOF 体积小、加载快。生产环境的推荐组合是AOF 保数据 + RDB 做快速重启 + 定时把 AOF 同步到异地。
缓存三大问题:穿透、击穿、雪崩
缓存不是"加上就万事大吉",错误的使用方式会在高并发下放大故障。这是面试必考、线上必踩的三类问题:
1. 缓存穿透(查不存在的数据)
请求一个数据库中也不存在的 Key(如恶意构造的 user:-1),缓存永远不命中,所有请求直接打到数据库。攻击者可以用大量随机 ID 拖垮数据库。
# 方案一:缓存空值(简单有效,但空值要设较短 TTL)
# 伪代码:查库发现不存在时,也写一条短 TTL 的缓存
# value = db.query(key)
# if value == null:
# cache.set(key, "NULL", 60) # 空值缓存 60 秒,挡住后续同类请求
# 方案二:布隆过滤器(先判断"可能存在"再放行查库)
# 100 万数据量下布隆过滤器仅占约 1MB 内存,误判率 1% 左右,
# 误判只会多查一次库,不会漏掉真实数据
2. 缓存击穿(热点 Key 过期瞬间)
某个热点 Key(如秒杀商品)恰好过期,同一瞬间成千上万的请求同时回源数据库。与穿透的区别:数据存在,只是缓存恰好失效。
# 方案一:互斥锁(只允许一个请求重建缓存,其余等待)
SET lock:hot:1024 token NX EX 5 # 抢锁成功才查库
# 抢到锁的线程查库并写缓存,其余线程 sleep 一小段后重读缓存
# 方案二:逻辑过期(Key 不真正过期,值里带过期时间戳,
# 命中时返回旧值并触发异步刷新)
# 方案三:热点数据设置极长 TTL,由定时任务后台主动更新
3. 缓存雪崩(大量 Key 同时过期)
大量 Key 设置了相同的过期时间(如整点 0 点过期),集中失效导致数据库压力瞬间打满。影响面比击穿大得多。
# 方案一:过期时间加随机抖动,错峰失效
# SETEX cache:key (3600 + random(0..300)) "value"
# 方案二:多级缓存(本地缓存 Caffeine/Guava + Redis 兜底)
# 方案三:服务降级——缓存失效时返回旧值或默认数据,
# 对数据库调用做熔断限流,避免被打垮
示例代码
1. 安装与基础连接
# 安装 Redis
sudo apt update && sudo apt install redis-server -y
# 检查服务状态
sudo systemctl status redis-server
# 输出: ● redis-server.service - Advanced key-value store
# Active: active (running)
# 测试连接
redis-cli ping
# 输出: PONG
# 连接并选择数据库(默认 16 个,编号 0-15)
redis-cli -n 1
2. 五种数据结构操作
# 字符串(String)
SET name "Alice"
GET name # "Alice"
SET session:abc "logged_in" EX 3600 # 带过期时间(秒),SETEX 仍可用,但推荐使用 SET key value EX seconds 替代
INCR counter # 1(计数器自增)
INCRBY counter 10 # 11
TTL session:abc # 剩余生存时间(秒)
# 哈希(Hash)—— 适合存储对象
HSET user:1 name "Alice" age "25" city "Beijing"
HGET user:1 name # "Alice"
HGETALL user:1 # 所有字段
HINCRBY user:1 age 1 # 26(年龄自增)
# 列表(List)—— 消息队列
LPUSH queue task1 # 左侧推入
LPUSH queue task2
RPOP queue # 右侧弹出(FIFO队列):"task1"
LLEN queue # 列表长度
# 集合(Set)
SADD tags linux devops database
SISMEMBER tags linux # 1(存在)
SMEMBERS tags # 所有元素
SINTER tags1 tags2 # 交集
# 有序集合(Sorted Set)—— 排行榜
ZADD leaderboard 100 "player1" 200 "player2" 150 "player3"
ZREVRANGE leaderboard 0 2 WITHSCORES # 前三名
# 输出: 1) "player2" 2) 200 3) "player3" 4) 150 5) "player1" 6) 100
3. 持久化配置
# /etc/redis/redis.conf 配置
# RDB 快照(默认启用)
save 900 1 # 900 秒内至少 1 次修改触发保存
save 300 10 # 300 秒内至少 10 次修改
save 60 10000 # 60 秒内至少 10000 次修改
# AOF 持久化(推荐生产环境启用)
appendonly yes
appendfsync everysec # 每秒 fsync,平衡性能与安全
# 手动触发保存
redis-cli BGSAVE # 后台 RDB 保存
redis-cli BGREWRITEAOF # 重写 AOF 文件(压缩体积)
4. 内存淘汰策略
# redis.conf 配置:
maxmemory 2gb # 最大内存(2GB)
maxmemory-policy allkeys-lru # 淘汰策略
# 常见淘汰策略:
# noeviction — 不淘汰,写操作返回错误(默认)
# allkeys-lru — 移除最近最少使用的键(最常用)
# volatile-lru — 只在设置了 TTL 的键中移除 LRU
# allkeys-random — 随机移除键
# volatile-ttl — 移除 TTL 最小的键(即将过期)
# 查看当前淘汰策略
redis-cli CONFIG GET maxmemory-policy
# INFO 监控
redis-cli INFO memory # 内存详情
redis-cli INFO stats # 统计信息(命中率等)
redis-cli SLOWLOG GET 5 # 最近 5 条慢查询
redis-cli MONITOR # 实时监控所有命令(慎用)
5. 主从复制与 Sentinel 高可用
# 从库配置(/etc/redis/redis.conf)
replicaof 192.168.1.10 6379 # 指定主库地址和端口
replica-read-only yes # 从库只读,读流量分流到从库
# 主库开启密码后,从库必须配置:
requirepass your_strong_password
masterauth your_strong_password
# 启动从库后验证主从状态
redis-cli INFO replication
# 输出: role:slave
# master_host:192.168.1.10
# master_link_status:up
# Sentinel(生产至少 3 台,避免脑裂):
# /etc/redis/sentinel.conf
sentinel monitor mymaster 192.168.1.10 6379 2 # 2 = 判定下线所需票数
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel auth-pass mymaster your_strong_password
# 启动 Sentinel 并查看主库状态
redis-sentinel /etc/redis/sentinel.conf
redis-cli -p 26379 SENTINEL masters
# 输出: 1) 1) "name" 2) "mymaster"
# 3) "ip" 4) "192.168.1.10" 5) "port" 6) "6379"
# 7) "flags" 8) "master"
主从复制采用全量同步 + 增量同步:首次连接或断连太久时做全量(传输 RDB 文件),正常运行后主库把写命令放进 backlog 增量推给从库。Sentinel 负责监控与自动故障转移——主库挂掉后,Sentinel 会从从库中选出一个新主库,并把其余从库指向它;客户端只需要配置 Sentinel 地址,无需感知 IP 变化。
6. 性能调优:maxmemory 策略与内存优化
# maxmemory 必须设置!否则内存耗尽后系统开始 swap,Redis 性能雪崩
maxmemory 2gb
maxmemory-policy allkeys-lru
# 内存使用诊断
redis-cli INFO memory
redis-cli MEMORY USAGE user:1001:profile # 查看单个 Key 占用字节
redis-cli MEMORY DOCTOR # 内存健康体检
redis-cli --bigkeys # 扫描大 Key(低峰期执行)
| 淘汰策略 | 作用范围 | 特点 | 适用场景 |
|---|---|---|---|
noeviction | — | 不淘汰,写操作直接报错 | 不允许丢数据的场景(默认) |
allkeys-lru | 全部键 | 淘汰最久未使用的键 | 纯缓存(最常用) |
allkeys-random | 全部键 | 随机淘汰 | 缓存数据无访问热度差异 |
volatile-lru | 带 TTL 的键 | 只淘汰设了 TTL 的键 | 缓存 + 持久数据混用 |
volatile-ttl | 带 TTL 的键 | 优先淘汰即将过期的 | 过期时间有业务意义的场景 |
内存优化三板斧:① 用 Hash 代替大量 String——100 万个字段的 Hash 比 100 万个独立 Key 节省 90% 以上内存;② 开启 zset-max-ziplist-entries 等小对象压缩(把小的 ZSet/List/Hash 编码成紧凑格式);③ 大 Key 拆小——单个 Key 超过 100KB 就该警惕,--bigkeys 扫描可以帮助定位。
常见错误
| 错误表现 | 根因 | 正确做法 |
|---|---|---|
MISCONF Redis is configured to save RDB snapshots... | RDB 保存失败(磁盘满或权限问题),Redis 拒绝写操作 | 检查磁盘空间和 Redis 数据目录权限;或执行 CONFIG SET stop-writes-on-bgsave-error no |
(error) OOM command not allowed when used memory > 'maxmemory' | 内存超出限制且淘汰策略为 noeviction | 将 maxmemory-policy 改为 allkeys-lru |
Could not connect to Redis at 127.0.0.1:6379: Connection refused | Redis 未运行或绑定了非回环地址 | systemctl status redis 检查服务;确认 bind 127.0.0.1 或 0.0.0.0 |
使用 KEYS * 导致 Redis 阻塞 | KEYS 遍历所有键,O(N) 复杂度,生产环境不可用 | 用 SCAN 0 MATCH pattern* 代替(游标迭代,不阻塞) |
最佳实践
| 实践 | 原理 | 示例 |
|---|---|---|
| 始终设置 TTL(过期时间) | 防止缓存数据永不失效,撑爆内存 | SET cache:key "value" EX 3600 或 Redis 客户端设置默认 TTL |
生产环境禁用 KEYS、FLUSHALL、MONITOR | 这些命令会阻塞 Redis,影响线上业务 | 用 SCAN 替代 KEYS;清库用 FLUSHALL ASYNC(注意 FLUSHDB 只清当前库,语义不同) |
| 使用连接池 | 减少频繁创建/断开连接的开销 | Python redis-py 用 redis.ConnectionPool,Java 用 JedisPool |
| 键名用冒号分隔的命名空间 | 避免键冲突,便于按模式查找 | user:1001:profile、session:abc123 |
| 持久化选 AOF + 定时 RDB | AOF 保证数据安全,RDB 便于快速重启 | 启用 AOF,同时保留默认 RDB 配置 |
练习题
- (概念)Redis 的五种核心数据结构分别是什么?每种举一个典型的使用场景。
- (概念)RDB 和 AOF 两种持久化方式的根本区别是什么?各自的适用场景是什么?
- (实操)安装 Redis,使用哈希存储 3 个用户的个人信息(name、age、email),用
HGETALL获取所有用户数据。使用INCR实现一个页面访问计数器,用EXPIRE设置每天重置。 - (实操)使用有序集合实现一个游戏排行榜:插入 5 个玩家及其分数,按分数从高到低取前三名。用
ZINCRBY增加一个玩家的分数并验证排名变化。 - (🔍 挑战)在 Web 应用环境中模拟缓存穿透场景:大量请求查询一个不存在的 Key,导致请求穿透到数据库。设计解决方案(使用布隆过滤器或缓存空值),并在 Redis 中实现
SET cache:empty_key "NULL" EX 60空值缓存方案,通过脚本模拟压力测试验证效果。
点击查看答案
- (概念)五种核心数据结构:String(缓存 HTML、计数器)、Hash(用户信息/商品详情)、List(消息队列/最新消息列表)、Set(标签/去重/共同好友)、Sorted Set(排行榜/延时队列)。
- (概念)RDB 是定时全量快照(dump.rdb),体积小、恢复快,但可能丢失最近一次快照之后的数据。AOF 是追加式操作日志,可配置 everysec/always/no 同步策略,数据安全性更高但文件更大、恢复更慢。生产环境通常 RDB + AOF 并用。
- (实操)
HSET user:1 name "Alice" age 30 email "alice@test.com"(3 个用户)→HGETALL user:1。计数器:SET page:visits:2026-07-30 0→ 每次访问INCR page:visits:2026-07-30→EXPIRE page:visits:2026-07-30 86400设置 24 小时后自动过期。注意 Key 的设计模式:对象类型:ID:字段。 - (实操)
ZADD leaderboard 100 "Alice" 85 "Bob" 70 "Charlie" 60 "David" 45 "Eve"→ZREVRANGE leaderboard 0 2 WITHSCORES取前三名(Alice/Bob/Charlie)。ZINCRBY leaderboard 20 "Charlie"后再次ZREVRANGE查看排名变化。注意ZREVRANGE是从高到低,ZRANGE是从低到高。 - (🔍 挑战)缓存穿透模拟:大量请求查询
GET product:notexist,Redis 未命中→压力全到数据库。解决方案:① 缓存空值:SET product:notexist "NULL" EX 60,后续请求命中空缓存直接返回。② 布隆过滤器:先判断 Key 是否存在,不存在直接返回。压力测试脚本可用redis-benchmark或简单for循环 +ab观察有/无防护时的 QPS 差异。
学习检查点
学完本章后,请检验自己是否掌握以下内容:
| 检查项 | 自测问题 | 验证方法 |
|---|---|---|
| 概念理解 | 能用自己的话解释 Redis 的数据结构和适用场景 | 尝试向他人讲解 |
| 命令操作 | 能不查文档完成 Redis 数据类型操作、持久化配置 | 在终端实际执行 |
| 原理掌握 | 能说出 Redis 的 RDB 和 AOF 持久化机制区别 | 画出流程图 |
| 故障排查 | 能独立排查 Redis 连接错误、内存不足、主从同步问题 | 模拟故障并修复 |
| 最佳实践 | 能说明为什么需要为 Redis 配置内存限制和过期策略 | 对比不同方案 |
本章总结
Redis 以简单的设计(单线程 + 纯内存 + 丰富的数据结构)实现了极致的性能。五种核心数据结构各有所长:String 用于缓存和计数,Hash 用于对象存储,List 用于消息队列,Set 用于标签和去重,Sorted Set 用于排行榜。持久化方面,AOF 比 RDB 更安全但重启更慢,生产环境通常两者并用。内存淘汰策略必须配置,否则 Redis 会在内存满时拒绝写操作。
速查表
| 命令 | 数据结构 | 用途 |
|---|---|---|
SET/GET/DEL | String | 缓存/存储 |
SET key value EX ttl | String | 带过期时间的缓存 |
INCR/DECR | String | 计数器 |
HSET/HGET/HGETALL | Hash | 对象存储 |
LPUSH/RPOP/LLEN | List | 消息队列 |
SADD/SMEMBERS/SINTER | Set | 标签/交集 |
ZADD/ZREVRANGE/ZINCRBY | Sorted Set | 排行榜 |
TTL/EXPIRE | 通用 | 查看/设置过期时间 |
SCAN 0 MATCH pat | 通用 | 游标遍历键(替代 KEYS) |
INFO memory/stats | 管理 | 内存/统计监控 |
学习路径建议
- Redis 深入可看《Redis 设计与实现》或官方文档
- 实际应用可结合 3.6:MySQL 数据库 MySQL/3.7:PostgreSQL 数据库 PostgreSQL 理解缓存+持久层搭配
延伸阅读
- Redis 官方文档
- Redis 持久化详解
- Redis 内存淘汰策略
- 推荐书籍:《Redis 设计与实现》