一、Redis 简介
Redis(Remote Dictionary Server)是一个完全开源、遵守 BSD 协议的高性能 key-value 数据库。
核心特点
- 数据持久化:可将内存数据保存到磁盘,重启时重新加载
- 丰富的数据结构:支持 string、list、set、zset、hash 等
- 数据备份:支持 master-slave 模式的主从复制
性能优势
- 极高性能:10万~100万+ QPS,微秒级响应(MySQL 通常几千~几万 QPS,毫秒级响应)
- 原子性:所有操作都是原子性的,支持 MULTI/EXEC 事务
- 丰富特性:支持 publish/subscribe、通知、key 过期等
二、Redis 数据类型
Redis 支持五种基本数据类型:
| 类型 | 说明 | 特点 |
|---|---|---|
| string | 基本存储单元,可存字符串、整数、浮点数 | 二进制安全,最多 512MB |
| hash | 键值对集合,可存多个字段 | 无序,适合存储对象 |
| list | 字符串列表,按插入顺序排序 | 有序可重复,支持双向操作 |
| set | 无序集合,不重复 | 无序无重复,支持集合运算 |
| zset | 有序集合,每个元素关联分数 | 按 score 排序,适合排行榜 |
常用命令速查
String:
bash
SET key value [EX seconds] [NX|XX] # 设置键值,可选过期时间(秒)和条件(NX不存在才设,XX存在才设)
GET key # 获取key的值
SETNX key value # 仅当key不存在时设置(分布式锁)
INCR key # key中的数字加1
INCRBY key increment # key中的数字增加指定值
DECR key # key中的数字减1
DECRBY key decrement # key中的数字减少指定值
MSET key1 value1 [key2 value2 ...] # 批量设置键值
MGET key1 [key2 ...] # 批量获取键值
APPEND key value # 追加值到key末尾
STRLEN key # 返回key对应值的字节数
TTL key # 查看key剩余生存时间(秒)
EXPIRE key seconds # 设置key过期时间(秒)
PERSIST key # 移除key的过期时间,使其永不过期
List:
bash
LPUSH key value [value ...] # 从左边插入元素
RPUSH key value [value ...] # 从右边插入元素
LPOP key # 弹出左边第一个元素
RPOP key # 弹出右边第一个元素
LRANGE key start stop # 获取列表指定范围的元素(支持负数索引)
LLEN key # 获取列表长度
LINDEX key index # 获取指定索引的元素
LSET key index value # 修改指定索引的值
LTRIM key start stop # 修剪列表,只保留指定区间内的元素
Set:
bash
SADD key member [member ...] # 添加一个或多个成员
SMEMBERS key # 获取集合所有成员
SISMEMBER key member # 判断成员是否在集合中
SREM key member [member ...] # 删除一个或多个成员
SCARD key # 获取集合成员数量
SINTER key1 [key2 ...] # 求多个集合的交集
SUNION key1 [key2 ...] # 求多个集合的并集
SDIFF key1 [key2 ...] # 求差集(属于key1但不属于key2)
ZSet:
bash
ZADD key score member [score member ...] # 添加带分数的成员
ZRANGE key start stop [WITHSCORES] # 按分数升序返回成员(可带分数)
ZREVRANGE key start stop [WITHSCORES] # 按分数降序返回成员(可带分数)
ZRANK key member # 获取成员的排名(升序)
ZSCORE key member # 获取成员的分数
ZREM key member [member ...] # 删除成员
ZCARD key # 获取成员数量
Hash:
bash
HSET key field value # 设置hash字段的值
HGET key field # 获取hash字段的值
HMSET key field1 value1 [field2 value2 ...] # 批量设置字段(Redis 4.0+推荐用HSET)
HMGET key field1 [field2 ...] # 批量获取字段
HGETALL key # 获取hash中所有字段和值
HDEL key field [field ...] # 删除一个或多个字段
HEXISTS key field # 判断字段是否存在
HKEYS key # 获取所有字段名
HVALS key # 获取所有字段值
常见占位符含义:
key:键名,自己取,如name、user:1value:值,如"张三"、100member:集合/有序集合成员,如"apple"field:哈希字段名,如"age"score:分数,如100index:索引,如0、-1start stop:范围,如0 -1seconds:秒数,如60pattern:匹配模式,如user:*increment/decrement:增减量,如5
实际例子:
bash
SET key value → SET username "张三"
GET key → GET username
SADD key member → SADD fruits "apple"
HSET key field value → HSET user name "张三"
ZADD key score member → ZADD rank 100 "张三"
LPUSH key value → LPUSH list1 "hello"
三、Redis 核心特性
1. 单线程模型
- Redis 6.0 之前一直是单线程处理用户请求
- 原因 :
- 操作访问内存,速度极快
- 核心功能比数据库简单
- 避免线程竞争开销
- 网络 IO 使用 epoll 多路复用
- 注意事项 :
- 一次只运行一条命令
- 避免执行慢命令:
keys *(查看所有key,慎用)、flushall(清空所有数据库)、flushdb(清空当前库)、慢 Lua 脚本等 - 3.0 版本后实际还有其他线程处理特定功能(如 fsync、close fd)
2. IO 多路复用(epoll)
- 一个线程处理多个 socket
- 只有少数 socket 活跃时效率极高
- Linux 提供三套 API:select、poll、epoll
- C++ 可直接使用 epoll API,Java 可使用 NIO
3. 缓存实现
- 计算机三层存储:CPU(20~40ns)→ 内存(100ns)→ 磁盘(3~5ms)
- Redis 作为旁路缓存,需在应用程序中显式调用 GET/SET
- 缓存命中:直接读 Redis
- 缓存缺失:从数据库读取并写入 Redis
4. 缓存类型
- 只读缓存:所有写请求直接发往后端数据库,删改时删除缓存
- 读写缓存 :
- 同步直写:同时写缓存和数据库,优先保证数据可靠性
- 异步写回:先写缓存,淘汰时再写回数据库,优先响应速度
四、缓存三大问题
| 问题 | 定义 | 解决方案 |
|---|---|---|
| 缓存雪崩 | 大面积 key 同时失效或 Redis 宕机,请求全部涌入数据库 | 1. 过期时间加随机值 2. 搭建高可用集群 3. 服务限流熔断 4. 多级缓存 |
| 缓存穿透 | 查询不存在的数据,每次请求都绕过缓存查数据库 | 1. 接口层校验(id<=0 拦截) 2. 缓存空结果(短 TTL) 3. 布隆过滤器 |
| 缓存击穿 | 热点 key 过期,大量并发请求同时打数据库 | 1. 加锁排队 2. 设置永不过期(及时更新) |
区别:雪崩是大面积 key 挂掉;击穿是单个热点 key 挂掉。
五、Pipeline 流水线
- 将一组 Redis 命令组装,通过一次 RTT 传输给 Redis
- 未使用 Pipeline:n 条命令需要 n 次 RTT
- 使用 Pipeline:n 条命令只需 1 次 RTT
- 性能对比:网络延迟越大,性能提升越明显
| 网络延迟 | 非 Pipeline | Pipeline |
|---|---|---|
| 本机 0.17ms | 573ms | 134ms |
| 内网 0.41ms | 1610ms | 240ms |
| 异地 7ms | 80000ms | 1104ms |
六、Redis 安装与配置
CentOS 7 源码安装
bash
yum install tcl gcc gcc-c++ -y # 安装依赖包
tar zxvf redis-6.2.14.tar.gz -C /usr/local/ # 解压Redis安装包到/usr/local/
cd /usr/local/redis-6.2.14/ # 进入解压目录
make && make install # 编译并安装
redis-server redis.conf & # 启动Redis服务并放入后台
CentOS 8 yum 安装
bash
dnf install -y redis # 安装Redis
systemctl enable redis --now # 设置开机自启并立即启动
重要配置项
bash
bind 127.0.0.1 # 监听地址(改为0.0.0.0支持远程)
protected-mode yes # 保护模式
port 6379 # 默认端口(来源:作者用MERZ在手机键盘对应数字)
daemonize no # 是否守护进程
databases 16 # 数据库数量
save 900 1 # 900秒内至少1个key变更则触发RDB
save 300 10 # 300秒内至少10个key变更则触发RDB
save 60 10000 # 60秒内至少10000个key变更则触发RDB
requirepass foobared # 访问密码
maxclients 10000 # 最大连接数
动态修改配置
bash
CONFIG SET requirepass 123456 # 动态设置密码
CONFIG GET requirepass # 查看密码配置
CONFIG GET bind # 查看bind配置
CONFIG SET maxmemory 1G # 设置最大内存为1GB
CONFIG GET maxmemory # 查看最大内存配置
注意:不是所有配置都可以动态修改,且无法持久化保存。
慢查询
bash
slowlog-log-slower-than 10000 # 慢查询阈值,单位微秒(默认10000)
slowlog-max-len 128 # 慢查询日志最多保留条数
SLOWLOG LEN # 查看慢日志的记录条数
SLOWLOG GET # 获取慢日志详情
SLOWLOG RESET # 清空慢日志
七、持久化机制
RDB(Redis DataBase)
- 原理:将某一时刻的内存数据快照保存到磁盘(默认 dump.rdb)
- 触发方式:
bash
SAVE # 同步保存RDB快照(阻塞其他请求)
BGSAVE # 异步保存RDB快照(fork子进程处理)
# 配置文件自动触发:
save 900 1 # 900秒内至少1个key变更则触发
save 300 10 # 300秒内至少10个key变更则触发
save 60 10000 # 60秒内至少10000个key变更则触发
- 优点:恢复快、文件紧凑、对性能影响小
- 缺点:可能丢失数据、SAVE 阻塞、BGSAVE fork 耗时
AOF(Append-only File)
- 原理:记录每次写操作命令,追加到 AOF 文件末尾
- 开启方式:
bash
appendonly yes # 开启AOF持久化
appendfilename "appendonly.aof" # AOF文件名
appendfsync everysec # 写入策略:每秒同步一次
- 写入策略 :
always:每个写操作都保存,最安全但最慢everysec:每秒保存,最多丢失 1s 数据(默认)no:由操作系统决定,最快但不安全
- AOF 重写:
bash
BGREWRITEAOF # 异步重写AOF文件,压缩命令集
- 文件损坏修复:
bash
redis-check-aof --fix appendonly.aof # 修复损坏的AOF文件
- 优点:性能影响小、速度快、内存消耗少
- 缺点:文件大、恢复慢
选择建议
- 两种方式都开启时,Redis 优先使用 AOF 恢复数据(更完整)
- 仅作缓存可不用持久化;作为数据库需认真选择
八、主从复制
特点
- 一个 master 可有多个 slave
- 一个 slave 只能有一个 master
- 数据流向:master → slave(单向)
- master 可读写,slave 只读
实现
bash
# 从节点配置
replicaof 192.168.108.10 6379 # 新版:设置主节点IP和端口
slaveof 192.168.108.10 6379 # 旧版:设置主节点IP和端口
# 取消主从
REPLICAOF NO ONE # 新版:取消主从复制
SLAVEOF NO ONE # 旧版:取消主从复制
验证
bash
info replication # 查看主从复制信息
# master: role:master, connected_slaves:2
# slave: role:slave, master_link_status:up
九、哨兵模式(Sentinel)
核心功能
- 监控:持续检查主从节点健康状态
- 通知:异常时通知管理员
- 自动故障转移:主节点宕机时自动提升从节点
- 配置提供者:客户端通过 Sentinel 获取当前主节点地址
故障转移流程
- 主观下线(Sdown):某 Sentinel 发现主节点无响应
- 客观下线(ODown):多个 Sentinel(≥quorum)达成共识
- 选举 Leader:Raft 算法选举
- 提升新主 :选择最优从节点执行
REPLICAOF NO ONE - 重配从节点:其他从节点指向新主
- 通知客户端:发布/订阅机制
配置
bash
sentinel monitor mymaster 192.168.108.10 6379 2 # 监控主节点,quorum为2
sentinel down-after-milliseconds mymaster 30000 # 超过30秒无响应则主观下线
启动
bash
redis-sentinel sentinel.conf & # 启动哨兵服务并放入后台
注意
- Sentinel 不解决数据分片问题,仅解决单主节点高可用
- 适用于中小规模集群,大规模用 Redis Cluster
十、Redis Cluster(集群)
核心概念
- 哈希槽:16384 个槽(0~16383)
- 映射规则 :
HASH_SLOT = CRC16(key) mod 16384 - 去中心化:节点间通过 Gossip 协议通信
- Gossip 端口:默认 +10000(如 6379 对应 16379)
关键角色
- 主节点(Master):处理读写、管理哈希槽、参与故障投票
- 从节点(Replica):异步复制主节点数据,默认只读
- 节点 ID:每个节点唯一标识
核心特性
- 数据分片:突破单机内存限制
- 高可用:部分节点故障不影响整体
- 线性扩展:加节点即可提升容量与并发
- 自动路由:客户端连接任意节点,自动重定向(MOVED)
故障转移
- 故障检测:多数主节点标记 FAIL
- 从节点选举:发起 FAILOVER 请求
- 投票晋升:主节点投票通过
- 拓扑更新:Gossip 同步新状态
部署(3主3从)
bash
# 所有节点配置
bind 0.0.0.0 # 监听所有地址
cluster-enabled yes # 开启集群模式
# 任意一台创建集群
redis-cli --cluster create 192.168.108.21:6379 192.168.108.22:6379 192.168.108.23:6379 192.168.108.24:6379 192.168.108.25:6379 192.168.108.26:6379 --cluster-replicas 1 # 创建3主3从集群
数据操作
bash
redis-cli -c # 连接集群,支持自动重定向
set name qgd # 若槽不在当前节点,自动重定向到目标节点
get name # 获取key,若槽不在当前节点,自动重定向
集群查看
bash
cluster nodes # 查看集群节点信息
cluster info # 查看集群状态
注意事项
- 至少 6 台(3主3从)
- 主从节点必须部署在不同物理机/可用区
- 不支持多键跨槽操作(如 MSET 不同槽)
- 集群状态为 fail 时,相关槽读写失败
十一、消息队列
两种模式
1. 生产者/消费者模式(List 实现)
- 多个消费者监听同一队列,一条消息只能被一个消费者消费
bash
LPUSH haizeiwang jishu1 # 生产者:从左边插入消息
BRPOP haizeiwang 10 # 消费者:阻塞式从右边弹出消息,超时10秒
LPUSH + BRPOP(左进右阻塞出)RPUSH + BLPOP(右进左阻塞出)- 阻塞式读取节省 CPU 开销
2. 发布者/订阅者模式(Pub/Sub)
- 发布者将消息发布到频道,所有订阅者都能收到
bash
SUBSCRIBE douluodalu # 订阅者:订阅频道douluodalu
PUBLISH douluodalu fuhuoba,wodeairen # 发布者:向频道发布消息
PSUBSCRIBE douluo* # 模式订阅:订阅匹配douluo*的频道
- 适用于群聊、群发、群公告
十二、客户端连接
redis-cli
bash
redis-cli # 默认本机无密码连接
redis-cli -h IP -p PORT -a PASSWORD # 远程连接,指定IP、端口、密码
redis-cli --no-auth-warning # 连接时不显示密码警告
常用命令
bash
INFO [section] # 查看运行状态(可指定section,如Server、Memory)
SELECT dbid # 切换数据库(0~15)
KEYS pattern # 查看所有匹配的key(慎用!)
DBSIZE # 当前库key数量
FLUSHDB # 清空当前库(慎用!)
FLUSHALL # 清空所有数据库(慎用!)
SHUTDOWN # 关闭服务(建议禁用)
Python 连接(redis-py)
python
import redis # 导入redis模块
r = redis.Redis(host='192.168.108.172', port=6379, password='123456', db=0) # 创建连接对象
r.set('color1', 'red') # 设置字符串键值
value = r.get('color1') # 获取字符串值
r.incr('int1') # 自增
r.decr('int1') # 自减
r.lpush('mylist', 'nihao') # 列表左插入
r.hset('student', 'name', 'lisi') # 哈希设置字段
图形工具
- Another Redis Desktop Manager(RDM)
- GitHub: https://github.com/qishibo/AnotherRedisDesktopManager
- 需提前配置 Redis 密码、关闭防火墙、更改 bind 地址
十三、应用场景
| 场景 | 实现方式 |
|---|---|
| 热点数据缓存 | Cache-Aside 模式,设置 TTL,空值缓存防穿透 |
| 分布式锁 | SET key value NX PX 30000(不存在则设置,过期30秒),Lua 脚本解锁 |
| 计数器与限流 | INCR + 过期时间 |
| 排行榜 | ZSet 按 score 实时排序 |
| 分布式会话 | 集中存储 session,设置过期时间 |
| 消息队列 | List 实现简单队列,Pub/Sub 实现发布订阅 |
| 位图应用 | Bitmap 存储签到、活跃用户、权限标记 |
| 地理信息 | GEO 数据结构,附近的人/店铺查询 |
十四、安装程序介绍
| 程序 | 说明 |
|---|---|
redis-server |
服务端主程序 |
redis-cli |
客户端程序 |
redis-benchmark |
性能测试程序 |
redis-check-aof |
AOF 文件检查程序 |
redis-check-rdb |
RDB 文件检查程序 |
redis-sentinel |
哨兵程序(软连接到 redis-server) |
十五、Docker 部署
bash
docker run --name redis -p 6379:6379 -d -v /data/redis:/data redis # 启动Redis容器,映射端口,挂载数据卷
docker exec redis redis-cli info server # 查看Redis服务端信息
docker exec redis redis-cli set name ma # 设置键值
docker exec redis redis-cli save # 保存RDB快照
默认 Redis 容器支持远程连接。
总结
Redis 是一个高性能、多功能的 NoSQL 数据库,核心价值在于:
- 高性能:内存操作,10万+ QPS
- 丰富数据结构:5 种基本类型满足多种场景
- 持久化:RDB + AOF 双机制保障数据安全
- 高可用:主从复制 → 哨兵模式 → Cluster 集群
- 广泛应用:缓存、分布式锁、排行榜、消息队列等
架构演进路径 :
主从复制 → 哨兵模式(自动故障转移)→ Redis Cluster(数据分片 + 高可用)