Redis

1. Redis 简介

Redis 是完全开源的,遵守 BSD 协议,是一个高性能的 key-value 数据库。

1.1 Redis三大特点

  1. 持久化:可将内存中的数据保存在磁盘中,重启时加载使用。
  2. 丰富的数据结构:不仅支持简单的 key-value,还支持 list、set、zset、hash 等。
  3. 数据备份:支持 master-slave 模式的数据备份。

1.2 Redis 优势

  • 性能极高:10万~100万+ QPS,微秒级响应。
  • 丰富的数据类型:Strings、Lists、Hashes、Sets、OrderedSets。
  • 原子性:所有操作都是原子性的,支持事务(MULTI / EXEC)。
  • 丰富的特性:支持 publish/subscribe、通知、key 过期等。

1.3 与其他 key-value 存储的不同

  • 更复杂的数据结构,并提供原子性操作。
  • 内存操作,内部复杂性高,但磁盘格式紧凑、追加方式产生。

2. Redis 数据类型

类型 说明
string 最基本类型,二进制安全,最大 512MB
hash 键值对集合,适合存储对象
list 简单字符串列表,按插入顺序排序,可重复
set 无序集合,元素唯一
zset (sorted set) 有序集合,每个元素关联一个分数(score)

3. 哈希槽(Redis Cluster)

  • 槽的数量:16384 个(0 ~ 16383),固定数量。
  • 映射规则HASH_SLOT = CRC16(key) mod 16384
  • 数据分布:每个集群节点负责一部分槽。支持动态迁移与扩容。

4. Redis 常见应用场景

场景 说明
热点数据缓存 Cache-Aside 模式,设置合理 TTL
分布式锁 SETNX + Lua 脚本,设置过期时间
计数器与限流 INCR 原子递增,过期时间实现限流
排行榜系统 SortedSet 按分数排序
分布式会话 集中存储用户会话信息
消息队列 List 的 LPUSH / BRPOP,简单队列
位图应用 签到、活跃用户统计
地理信息存储 GEO 数据结构,LBS 场景

5. Redis 特性

  • 速度快:10W QPS,基于内存,C 语言实现
  • 单线程(6.0 版本前)
  • 持久化:RDB 和 AOF
  • 支持多种数据结构
  • 功能丰富:Lua 脚本、发布订阅、事务、Pipeline
  • 简单:单机核心代码约 23000 行
  • 主从复制
  • 高可用和分布式:哨兵、集群

5.1 单线程模型

Redis 使用单线程处理请求(6.0 前),原因:

  • 操作基于内存,快;数据库访问硬盘,慢
  • 核心功能比数据库简单
  • 避免线程竞争开销
  • 使用 epoll 实现 IO 多路复用

5.2 IO 多路复用(epoll)

  • 一个线程处理多个 socket
  • Linux 提供 select、poll、epoll 三套 API
  • 类似于点餐时“好了叫我”的回调机制

6. 持久化

6.1 RDB(Redis DataBase)

  • 快照方式,保存某个时刻的内存数据到 dump.rdb
  • 触发方式save(同步,阻塞)、bgsave(异步,fork 子进程)
  • 配置触发save 900 1save 300 10save 60 10000
  • 优点:恢复数据快,文件紧凑,适合备份
  • 缺点:可能丢失最近一次快照后的数据,fork 子进程消耗内存

6.2 AOF(Append-only File)

  • 记录每个写操作命令,追加到 appendonly.aof
  • 写入策略
    • always:每个写操作都同步,最安全但慢
    • everysec:每秒同步一次,默认,最多丢 1 秒数据
    • no:由操作系统决定,最快但不安全
  • AOF 重写:压缩命令集,减少文件大小,使用 bgrewriteaof
  • 优点:数据更完整,丢失数据少
  • 缺点:文件大,恢复数据慢

当 RDB 和 AOF 都开启时,Redis 优先使用 AOF 恢复数据。

7. Pipeline 流水线

  • 将一组 Redis 命令打包,一次 RTT 传输,减少网络往返时间。
  • 适用于不支持批量操作的命令(如多次 hgetall)。
  • 网络延迟越大,Pipeline 性能提升越明显。

8. 缓存问题

8.1 缓存穿透

  • 定义:查询不存在的数据(缓存和数据库中都没有),请求直接打到数据库。
  • 解决方案
    • 接口层校验
    • 缓存空结果(短 TTL)
    • 布隆过滤器

8.2 缓存击穿

  • 定义:热点 key 过期瞬间,大量并发请求同时打到数据库。
  • 解决方案
    • 加锁排队
    • 热点 key 设置为永不过期(需主动更新)

8.3 缓存雪崩

  • 定义:大面积 key 同时过期或 Redis 宕机,所有请求涌入数据库。
  • 解决方案
    • 过期时间加随机值
    • 搭建高可用集群(哨兵、Cluster)
    • 服务限流熔断(Sentinel、Hystrix)
    • 多级缓存(本地缓存 + Redis)

9. 主从复制

  • 目的:数据冗余、读写分离
  • 特点
    • 一个 master 可以有多个 slave
    • 一个 slave 只能有一个 master
    • 数据流向 master → slave 单向
    • master 可读写,slave 只读
  • 工作原理
    1. slave 向 master 发送 sync 命令
    2. master 启动后台存盘进程,收集修改命令
    3. master 传送 RDB 文件给 slave
    4. slave 加载数据完成首次同步
    5. 后续增量同步

10. 哨兵模式(Sentinel)

  • 目的:在主从复制基础上实现自动故障转移(高可用)
  • 核心功能:监控、通知、自动故障转移、配置提供者
  • 故障转移流程
    1. 主观下线(SDOWN)
    2. 客观下线(ODOWN)——多个 Sentinel 确认
    3. 选举 Leader 执行故障转移
    4. 提升最优从节点为新 master
    5. 重配其他从节点
    6. 通知客户端

11. Redis Cluster 集群

  • 目的:解决单机容量、性能、单点故障问题,实现水平扩展
  • 核心特点
    • 无中心架构,数据分片(16384 个哈希槽)
    • 主从复制 + 自动故障转移
    • 节点间通过 Gossip 协议通信
  • 数据映射HASH_SLOT = CRC16(key) mod 16384
  • 故障转移:当 master 宕机,其 slave 自动选举成为新 master
  • 使用场景:海量数据(>100GB)、高并发(QPS ≥ 5万)

集群搭建示例(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

12. 常用命令

命令 说明
INFO 查看服务器状态信息
SELECT <db> 切换数据库(0-15)
KEYS * 查看所有 key(生产环境慎用!)
DBSIZE 当前库 key 数量
FLUSHDB 清空当前库
FLUSHALL 清空所有库
SHUTDOWN 关闭 Redis 服务
CONFIG GET/SET 动态修改配置
SLOWLOG GET/LEN/RESET 慢查询日志

13. 安装(CentOS 7 源码安装)

bash

# 安装依赖
yum install tcl gcc gcc-c++ -y

# 解压
tar zxvf redis-6.2.14.tar.gz -C /usr/local/

# 编译安装
cd /usr/local/redis-6.2.14/
make && make install

# 启动(后台运行)
redis-server redis.conf &

# 客户端连接
redis-cli

14. 配置文件核心参数

参数 说明
bind 127.0.0.1 监听地址,远程访问需改为 0.0.0.0
port 6379 监听端口
daemonize no 是否守护进程
databases 16 逻辑数据库数量
save 900 1 RDB 触发条件
appendonly no 是否开启 AOF
appendfsync everysec AOF 同步策略
requirepass foobared 访问密码
maxclients 10000 最大客户端连接数

15. 消息队列实现

生产者/消费者模式(List)

  • LPUSH + RPOPRPUSH + LPOP
  • 阻塞式:BRPOP / BLPOP

发布者/订阅者模式(Pub/Sub)

  • SUBSCRIBE channel 订阅频道
  • PUBLISH channel message 发布消息

16. Python 连接 Redis 示例

python

import redis

r = redis.Redis(host='192.168.108.172', port=6379, password='123456', db=0)

# 字符串操作
r.set('color1', 'red')
value = r.get('color1')
print(value)

# 列表操作
r.lpush('mylist', 'nihao')
r.lpush('mylist', 'laogao')
print(r.lrange('mylist', 0, -1))

# 哈希操作
r.hset('student', 'name', 'lisi')
r.hset('student', 'age', '18')
print(r.hgetall('student'))
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐