一、关系型数据库与 NoSQL 数据库
数据库主要分为两大类:关系型数据库 与NoSQL 数据库。
1.1 关系型数据库 vs NoSQL
- 关系型数据库:建立在关系模型基础上,借助集合代数等数学概念处理数据。主流产品包括 MySQL、Oracle、MS SQL Server、DB2 等。
- NoSQL 数据库:全称 Not Only SQL,意为"不仅仅是 SQL"。它适用于关系型数据库不适用或性能不足的场景,提供更灵活的数据存储方案。
1.2 为什么需要 NoSQL?
随着互联网数据量爆炸式增长,传统关系型数据库面临单机性能瓶颈 和扩展困难 的问题。NoSQL 数据库在云计算时代具备简单、易于大规模分布式扩展、读写性能高等优势,能够更好地应对海量数据和高并发场景。
1.3 NoSQL 主要分类
- 临时性键值存储:如 Memcached、Redis
- 永久性键值存储:如 ROMA、Redis
- 面向文档的数据库:如 MongoDB、CouchDB
- 面向列的数据库:如 Cassandra、HBase
二、Redis 简介
2.1 什么是 Redis?
Redis(Remote Dictionary Server)是一个开源的、遵循 BSD 协议的、基于内存的键值数据库(key-value database)。它由意大利开发者 Salvatore Sanfilippo 于 2009 年发布,现已成为国内外众多互联网公司(如阿里、百度、新浪微博、知乎、GitHub、Twitter 等)广泛使用的 NoSQL 数据库。
相比 Memcached,Redis 提供了数据持久化、多种数据结构支持、主从复制、高可用和分布式等更丰富的功能。
2.2 Redis 核心特性
- 高性能:基于内存操作,可达 10W QPS(每秒查询率)
- 单线程模型:避免线程切换和竞态条件,开发简单
- 持久化支持:支持 RDB 快照和 AOF 日志两种持久化方式
- 丰富的数据结构:支持字符串、列表、集合、有序集合、哈希、位图等
- 多语言支持:提供 Java、Python、PHP、Go 等多种客户端
- 功能丰富:支持 Lua 脚本、发布订阅、事务、Pipeline 等
- 主从复制与高可用:支持哨兵模式和集群模式
单线程为何如此快?
- 纯内存操作
- 非阻塞 I/O 多路复用
- 避免线程切换和锁竞争开销
2.3 Redis 应用场景
- Session 共享:Web 集群中的 Session 集中存储
- 缓存:热点数据缓存,如商品信息、新闻内容
- 计数器:访问排行榜、商品浏览数等统计场景
- 社交功能:共同好友、粉丝数、关注、点赞评论
- 消息队列:ELK 日志缓存、业务订阅发布系统
- 地理位置:基于 GEO 实现摇一摇、附近的人、外卖等功能
2.4 缓存实现流程
数据更新操作流程:先更新数据库,再删除缓存(或更新缓存)
数据读取操作流程:先查缓存,命中则返回;未命中则查数据库,写入缓存后返回
三、Redis 安装部署
3.1 RPM 包安装
bash
# CentOS/RHEL 系统
dnf install redis -y
systemctl start redis
systemctl enable redis
3.2 源码编译安装
bash
# 解压源码包
tar zxf redis-7.4.0.tar.gz
cd redis-7.4.0
安装编译工具
dnf install make gcc initscripts -y
编译安装
make
make install
运行安装脚本
cd utils/
./install_server.sh
按提示配置端口、配置文件、日志文件、数据目录等
3.3 配置修改
bash
# 修改配置文件允许远程访问
vim /etc/redis/6379.conf
# 将 bind 127.0.0.1 改为 bind 0.0.0.0 或 bind * -::*
# 关闭保护模式(生产环境需谨慎)
protected-mode no
重启服务
/etc/init.d/redis_6379 restart
四、Redis 基本操作
4.1 连接与配置查看
bash
# 连接 Redis
redis-cli
查看配置
127.0.0.1:6379> CONFIG GET bind
127.0.0.1:6379> CONFIG GET *
4.2 键值操作
bash
# 设置键值(带过期时间)
127.0.0.1:6379> SET name lee
127.0.0.1:6379> SET name lee EX 5 # 5秒后过期
获取值
127.0.0.1:6379> GET name
查看所有键
127.0.0.1:6379> KEYS *
选择数据库(Redis 有 0-15 共16个数据库)
127.0.0.1:6379> SELECT 1
127.0.0.1:6379[1]> SELECT 0
移动键到其他数据库
127.0.0.1:6379> MOVE name 1
重命名键
127.0.0.1:6379> RENAME name id
设置过期时间
127.0.0.1:6379> EXPIRE name 3
删除键
127.0.0.1:6379> DEL name
判断键是否存在
127.0.0.1:6379> EXISTS name
清空当前数据库
127.0.0.1:6379> FLUSHDB
清空所有数据库
127.0.0.1:6379> FLUSHALL
五、Redis 主从复制
5.1 主从复制原理
Redis 主从复制通过以下步骤实现数据同步:
- Slave 节点发送 SYNC 命令到 Master 节点
- Master 节点执行 BGSAVE 生成 RDB 快照文件
- Master 将 RDB 文件发送给 Slave 节点
- Slave 节点加载 RDB 文件进行数据恢复
- Master 将后续的写命令通过复制缓冲区发送给 Slave
5.2 主从配置
Master 节点配置:
bash
# 修改配置文件
vim /etc/redis/6379.conf
# 关闭保护模式
protected-mode no
重启服务
/etc/init.d/redis_6379 restart
Slave 节点配置:
bash
vim /etc/redis/6379.conf
# 指定主节点
replicaof 172.25.254.100 6379
重启服务
/etc/init.d/redis_6379 restart
5.3 验证主从同步
bash
# 在 Master 节点写入数据
127.0.0.1:6379> SET name lee
在 Slave 节点读取数据
127.0.0.1:6379> GET name # 应返回 "lee"
六、Redis Sentinel(哨兵)高可用
6.1 Sentinel 工作原理
Redis Sentinel 是 Redis 的高可用解决方案,主要功能:
- 监控:定期检查 Master 和 Slave 节点状态
- 通知:当被监控的 Redis 实例出现问题时,向管理员发送通知
- 自动故障转移:当 Master 节点失效时,自动将某个 Slave 提升为新的 Master
- 配置提供者:客户端连接时,提供当前可用的 Master 地址
6.2 Sentinel 三个定时任务
- 每10秒:每个 Sentinel 对 Master 和 Slave 执行 INFO 命令,发现 Slave 节点并确认主从关系
- 每2秒:每个 Sentinel 通过 Master 节点的频道交换信息,交互对节点的"看法"和自身信息
- 每1秒:每个 Sentinel 对其他 Sentinel 和 Redis 节点执行 PING 命令,进行心跳检测
6.3 Sentinel 配置示例
bash
# 复制 Sentinel 配置文件
cp sentinel.conf /etc/redis/
编辑配置文件
vim /etc/redis/sentinel.conf
主要配置项:
protected-mode no
port 26379
daemonize no
pidfile /var/run/redis-sentinel.pid
loglevel notice
sentinel monitor mymaster 172.25.254.100 6379 2
sentinel down-after-milliseconds mymaster 10000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
启动 Sentinel
redis-sentinel /etc/redis/sentinel.conf
6.4 脑裂问题与解决方案
问题:当 Master 和 Slave 网络分区时,Sentinel 可能将原 Master 降级为 Slave,导致网络恢复后数据丢失。
解决方案 :配置 min-slaves-to-write 和 min-slaves-max-lag 参数,确保 Master 至少有指定数量的 Slave 连接且延迟不超过指定时间才允许写入。
七、Redis Cluster 集群
7.1 Cluster 工作原理
Redis Cluster 是无中心化的分布式解决方案:
- 所有节点通过 PING 机制互联
- 节点失效判定需要集群中超过半数的节点确认
- 客户端直接连接任意节点,无需代理
- 数据分片到 16384 个槽位(slot)中
- 每个节点负责一部分槽位,实现数据分布式存储
7.2 Cluster 部署步骤
bash
# 1. 修改所有节点配置文件
vim /etc/redis/6379.conf
cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000
2. 重启所有 Redis 服务
systemctl restart redis
3. 创建集群(3主3从示例)
redis-cli --cluster create
172.25.254.10:6379 172.25.254.20:6379 172.25.254.30:6379
172.25.254.110:6379 172.25.254.120:6379 172.25.254.130:6379
--cluster-replicas 1 -a 123456
7.3 集群状态检查
bash
# 查看集群信息
redis-cli -a 123456 --cluster info 172.25.254.10:6379
检查集群状态
redis-cli -a 123456 --cluster check 172.25.254.10:6379
集群内部信息
redis-cli -a 123456 cluster info
7.4 集群数据操作
bash
# 写入数据(会自动重定向到正确的节点)
127.0.0.1:6379> SET key1 value1
# 如果 key 的槽位不在当前节点,会返回 MOVED 重定向信息
7.5 集群扩容与缩容
添加 Master 节点:
bash
redis-cli -a 123456 --cluster add-node \
172.25.254.40:6379 172.25.254.10:6379
重新分配槽位:
bash
redis-cli -a 123456 --cluster reshard 172.25.254.10:6379
添加 Slave 节点:
bash
redis-cli -a 123456 --cluster add-node \
172.25.254.140:6379 172.25.254.10:6379 \
--cluster-slave --cluster-master-id <master-node-id>
删除节点:
bash
# 先迁移槽位,再删除节点
redis-cli -a 123456 --cluster del-node \
172.25.254.10:6379 <node-id>
八、Redis 性能优化与监控
8.1 内存优化
- 使用适当的数据结构(如使用 Hash 代替多个 String)
- 设置合理的过期时间,避免内存泄漏
- 使用内存淘汰策略(maxmemory-policy)
- 启用内存碎片整理(activedefrag)
8.2 持久化配置
- RDB:定时快照,恢复速度快,但可能丢失最后一次快照后的数据
- AOF:记录每个写操作,数据更安全,但文件更大恢复较慢
- 混合持久化:RDB + AOF,兼顾性能和数据安全
8.3 监控指标
- 内存使用:used_memory、used_memory_rss
- 连接数:connected_clients
- 命中率:keyspace_hits、keyspace_misses
- 网络流量:total_connections_received、total_commands_processed
- 持久化状态:rdb_last_save_time、aof_current_size
九、Redis 常见问题与解决方案
9.1 缓存穿透
问题:查询不存在的数据,请求直接打到数据库
解决方案:
- 布隆过滤器过滤非法请求
- 缓存空对象(设置较短的过期时间)
- 接口层增加校验
9.2 缓存击穿
问题:热点 key 过期,大量请求同时访问数据库
解决方案:
- 设置热点数据永不过期
- 互斥锁,只允许一个线程重建缓存
- 提前续期,在过期前异步更新
9.3 缓存雪崩
问题:大量 key 同时过期或 Redis 宕机
解决方案:
- 设置不同的过期时间(加随机值)
- Redis 集群,避免单点故障
- 限流降级,保护数据库
- 多级缓存架构
十、Redis 最佳实践
10.1 键名设计规范
- 使用统一的命名空间,如
user:1001:profile、order:20240819:list - 使用冒号分隔层级,保持结构清晰
- 避免使用特殊字符和空格
- 控制键名长度,不宜过长
- 使用有意义的名称,便于维护和理解
10.2 数据结构选择原则
- 字符串(String):缓存简单值、计数器、分布式锁
- 哈希(Hash):存储对象属性,如用户信息、商品详情
- 列表(List):消息队列、最新动态、时间线
- 集合(Set):标签系统、共同好友、去重集合
- 有序集合(Sorted Set):排行榜、带权重的队列
- 位图(Bitmap):用户签到、活跃用户统计
- HyperLogLog:基数统计,如 UV 统计
- 地理空间(GEO):附近的人、位置服务
10.3 内存管理与优化
- 合理设置
maxmemory参数,避免内存溢出 - 根据业务场景选择合适的淘汰策略(
maxmemory-policy):volatile-lru:从已设置过期时间的键中淘汰最近最少使用的allkeys-lru:从所有键中淘汰最近最少使用的volatile-random:从已设置过期时间的键中随机淘汰allkeys-random:从所有键中随机淘汰volatile-ttl:淘汰剩余生存时间最短的键noeviction:不淘汰,返回错误(默认)
- 定期监控内存碎片率(
mem_fragmentation_ratio) - 启用内存碎片整理(
activedefrag yes) - 使用
MEMORY USAGE命令分析键的内存占用
10.4 持久化策略选择
- RDB 快照:
- 适合备份和灾难恢复
- 配置
save规则,如save 900 1、save 300 10、save 60 10000 - 使用
bgsave后台保存,避免阻塞
- AOF 日志 :
- 提供更好的数据安全性
- 配置
appendfsync策略:always:每个写命令都同步,最安全但性能最低everysec:每秒同步一次,平衡安全与性能(推荐)no:由操作系统决定,性能最好但可能丢失数据
- 定期执行
BGREWRITEAOF重写 AOF 文件
- 混合持久化 (Redis 4.0+):
- 结合 RDB 和 AOF 优点
- 配置
aof-use-rdb-preamble yes
10.5 高可用与集群部署建议
- 单机场景:主从复制 + 哨兵模式
- 中小规模集群:3主3从 Redis Cluster
- 大规模集群:多分片 Redis Cluster,每个分片主从
- 跨机房部署:主从跨机房,注意网络延迟
- 监控告警 :
- 监控节点状态、内存使用、连接数、命中率
- 设置慢查询日志(
slowlog-log-slower-than) - 配置 Sentinel 或 Cluster 的故障自动切换
10.6 客户端使用规范
- 使用连接池,避免频繁创建连接
- 合理设置连接超时和读写超时
- 使用 Pipeline 批量操作减少网络往返
- 避免大 Key(单个 Key 值过大)和热 Key(访问过于频繁)
- 使用 Lua 脚本保证原子性操作
- 合理使用事务(MULTI/EXEC),注意事务中的命令不会回滚
- 监控客户端连接数,避免连接泄漏
10.7 安全配置建议
- 设置强密码(
requirepass) - 绑定特定 IP(
bind),限制访问来源 - 禁用危险命令(
rename-command):FLUSHALL、FLUSHDB:清空数据CONFIG:修改配置KEYS:阻塞式遍历所有键
- 启用 TLS/SSL 加密传输(Redis 6.0+)
- 定期审计访问日志
- 使用 ACL(访问控制列表,Redis 6.0+)细化权限控制
10.8 备份与恢复策略
- 定时备份:
- RDB 文件备份到远程存储
- AOF 文件实时同步到备份服务器
- 使用
redis-cli --rdb在线备份
- 恢复测试:定期演练数据恢复流程
- 灾难恢复 :
- 主从切换 + Sentinel 自动故障转移
- Cluster 节点故障自动迁移槽位
- 跨机房容灾部署
10.9 性能调优要点
- 调整
tcp-keepalive减少连接开销 - 合理设置
timeout释放空闲连接 - 调整
maxclients限制最大连接数 - 启用
lazyfree-lazy-eviction异步释放内存 - 监控慢查询(
slowlog get)优化耗时命令 - 使用
INFO命令定期检查运行状态 - 根据业务峰值调整内存和连接数配置
10.10 生产环境检查清单
- ✅ 密码认证已启用
- ✅ 绑定 IP 限制访问范围
- ✅ 持久化策略已配置(RDB/AOF)
- ✅ 内存上限和淘汰策略已设置
- ✅ 主从复制或集群部署完成
- ✅ 监控告警系统已接入
- ✅ 备份机制已就绪
- ✅ 危险命令已禁用或重命名
- ✅ 连接池和超时配置合理
- ✅ 防火墙和安全组规则正确
十一、总结
本文系统性地介绍了 Redis 这一高性能内存数据库的核心知识体系。我们从数据库分类入手,明确了 Redis 在 NoSQL 数据库中的定位,随后深入探讨了 Redis 的核心特性、应用场景以及缓存实现的基本流程。
在实践层面,我们详细讲解了 Redis 的安装部署、基本操作命令,以及三种核心的高可用与分布式方案:
- 主从复制:实现数据冗余和读写分离的基础。
- 哨兵模式(Sentinel):提供自动故障转移的高可用解决方案。
- 集群模式(Cluster):实现数据分片和水平扩展的分布式架构。
此外,文章还涵盖了性能监控、常见缓存问题(穿透、击穿、雪崩)的解决方案,并最终汇总了覆盖键名设计、数据结构选择、内存管理、持久化策略、高可用部署、客户端规范、安全配置、备份恢复及性能调优等全方位的生产环境最佳实践与检查清单。
掌握 Redis 不仅需要理解其命令和数据结构,更需要根据业务场景合理选择部署架构、配置持久化与内存策略、实施监控告警,并遵循安全规范。希望本指南能帮助您构建更健壮、高性能的 Redis 应用。