Skip to content

Redis 缓存

Redis 是一种高性能的内存数据库,它常用于缓存、会话管理、消息队列等场景。本文将介绍 Redis 的核心概念和使用方法。

1. 基本概念

什么是 Redis

Redis (Remote Dictionary Server) 是一种开源的内存数据结构存储系统,它可以用作数据库、缓存和消息中间件。Redis 支持多种数据结构,如字符串、哈希、列表、集合、有序集合等。

核心特性

  • 内存存储:数据存储在内存中,读写速度快
  • 持久化:支持 RDB 和 AOF 持久化
  • 多种数据结构:支持字符串、哈希、列表、集合、有序集合等
  • 发布/订阅:支持消息发布和订阅
  • 事务:支持原子性操作
  • Lua 脚本:支持执行 Lua 脚本
  • 集群:支持高可用和水平扩展

2. 安装与配置

安装 Redis

Windows

  1. 访问 Redis 官网
  2. 下载 Windows 版本的 Redis
  3. 解压并运行 redis-server.exe

macOS

  1. 使用 Homebrew 安装:brew install redis
  2. 启动 Redis 服务:brew services start redis

Linux

  1. 使用包管理器安装:
    • Ubuntu/Debian:sudo apt install redis-server
    • CentOS/RHEL:sudo yum install redis
  2. 启动 Redis 服务:sudo systemctl start redis

配置 Redis

Redis 的配置文件通常位于:

  • Windows:redis.windows.conf
  • macOS:/usr/local/etc/redis.conf
  • Linux:/etc/redis/redis.conf

3. 数据结构

字符串 (String)

字符串是 Redis 最基本的数据结构,它可以存储任何类型的数据,如文本、数字等。

bash
# 设置字符串
SET key value

# 获取字符串
GET key

# 递增数字
INCR key

# 递减数字
DECR key

# 追加字符串
APPEND key value

# 获取字符串长度
STRLEN key

哈希 (Hash)

哈希是键值对的集合,它适合存储对象。

bash
# 设置哈希字段
HSET key field value

# 获取哈希字段
HGET key field

# 获取所有哈希字段
HGETALL key

# 获取哈希字段数量
HLEN key

# 检查哈希字段是否存在
HEXISTS key field

# 删除哈希字段
HDEL key field

列表 (List)

列表是有序的字符串集合,它可以在两端进行操作。

bash
# 在列表左侧添加元素
LPUSH key value1 value2 ...

# 在列表右侧添加元素
RPUSH key value1 value2 ...

# 在列表左侧弹出元素
LPOP key

# 在列表右侧弹出元素
RPOP key

# 获取列表长度
LLEN key

# 获取列表元素
LRANGE key start stop

集合 (Set)

集合是无序的字符串集合,它不允许重复元素。

bash
# 添加元素到集合
SADD key member1 member2 ...

# 从集合中删除元素
SREM key member1 member2 ...

# 检查元素是否在集合中
SISMEMBER key member

# 获取集合中的所有元素
SMEMBERS key

# 获取集合大小
SCARD key

# 集合交集
SINTER key1 key2 ...

# 集合并集
SUNION key1 key2 ...

# 集合差集
SDIFF key1 key2 ...

有序集合 (Sorted Set)

有序集合是有序的字符串集合,它每个元素都有一个分数,用于排序。

bash
# 添加元素到有序集合
ZADD key score1 member1 score2 member2 ...

# 从有序集合中删除元素
ZREM key member1 member2 ...

# 获取有序集合中的元素
ZRANGE key start stop [WITHSCORES]

# 获取有序集合中的元素(按分数从大到小)
ZREVRANGE key start stop [WITHSCORES]

# 获取有序集合大小
ZCARD key

# 获取元素的分数
ZSCORE key member

# 按分数范围获取元素
ZRANGEBYSCORE key min max [WITHSCORES]

4. 持久化

RDB 持久化

RDB 是 Redis DataBase 的缩写,它是一种快照持久化方式,将 Redis 在内存中的数据以快照的形式保存到磁盘。

bash
# 手动触发 RDB 持久化
SAVE

# 后台触发 RDB 持久化
BGSAVE

AOF 持久化

AOF 是 Append Only File 的缩写,它是一种日志持久化方式,将 Redis 的所有写操作追加到文件中。

bash
# 开启 AOF 持久化
# 在 redis.conf 中设置 appendonly yes

# 手动触发 AOF 重写
BGREWRITEAOF

持久化配置

conf
# RDB 配置
save 900 1      # 900秒内至少1个键被修改
save 300 10     # 300秒内至少10个键被修改
save 60 10000   # 60秒内至少10000个键被修改

# AOF 配置
appendonly yes
appendfsync everysec  # 每秒同步一次

5. 事务

Redis 支持事务,它可以将多个命令打包执行,保证原子性。

bash
# 开始事务
MULTI

# 执行命令
SET key1 value1
SET key2 value2

# 提交事务
EXEC

# 取消事务
DISCARD

6. 发布/订阅

Redis 支持发布/订阅模式,它可以用于消息传递。

bash
# 发布消息
PUBLISH channel message

# 订阅频道
SUBSCRIBE channel1 channel2 ...

# 订阅模式
PSUBSCRIBE pattern1 pattern2 ...

7. 过期时间

Redis 可以为键设置过期时间,过期后键会被自动删除。

bash
# 设置键的过期时间(秒)
EXPIRE key seconds

# 设置键的过期时间(毫秒)
PEXPIRE key milliseconds

# 设置键的过期时间戳(秒)
EXPIREAT key timestamp

# 设置键的过期时间戳(毫秒)
PEXPIREAT key milliseconds-timestamp

# 获取键的剩余过期时间(秒)
TTL key

# 获取键的剩余过期时间(毫秒)
PTTL key

# 移除键的过期时间
PERSIST key

8. 与 Node.js 集成

安装 Redis 客户端

bash
npm install redis

基本操作

javascript
const redis = require('redis');

// 创建客户端
const client = redis.createClient({
  url: 'redis://localhost:6379'
});

// 连接到 Redis
client.connect().then(() => {
  console.log('Connected to Redis');
});

// 字符串操作
client.set('name', 'John Doe').then(() => {
  return client.get('name');
}).then(value => {
  console.log('Name:', value);
});

// 哈希操作
client.hSet('user:1', 'name', 'John Doe').then(() => {
  return client.hSet('user:1', 'email', 'john@example.com');
}).then(() => {
  return client.hGetAll('user:1');
}).then(user => {
  console.log('User:', user);
});

// 列表操作
client.lPush('tasks', 'Task 1').then(() => {
  return client.lPush('tasks', 'Task 2');
}).then(() => {
  return client.lRange('tasks', 0, -1);
}).then(tasks => {
  console.log('Tasks:', tasks);
});

// 集合操作
client.sAdd('tags', 'javascript', 'node.js', 'redis').then(() => {
  return client.sMembers('tags');
}).then(tags => {
  console.log('Tags:', tags);
});

// 有序集合操作
client.zAdd('scores', { score: 90, value: 'John' }, { score: 85, value: 'Jane' }).then(() => {
  return client.zRange('scores', 0, -1, { WITHSCORES: true });
}).then(scores => {
  console.log('Scores:', scores);
});

// 过期时间
client.set('key', 'value').then(() => {
  return client.expire('key', 60);
}).then(() => {
  return client.ttl('key');
}).then(ttl => {
  console.log('TTL:', ttl);
});

9. 缓存策略

缓存模式

  • Cache-Aside:应用先从缓存读取数据,如果缓存不存在,则从数据库读取并写入缓存
  • Read-Through:缓存代理从数据库读取数据并写入缓存
  • Write-Through:应用写入缓存,缓存代理写入数据库
  • Write-Back:应用写入缓存,缓存异步写入数据库

缓存失效策略

  • LRU (Least Recently Used):淘汰最近最少使用的缓存
  • LFU (Least Frequently Used):淘汰最不经常使用的缓存
  • FIFO (First In First Out):淘汰最早进入的缓存

缓存穿透

问题:查询不存在的数据,导致请求直接访问数据库 解决方案

  • 缓存空值
  • 使用布隆过滤器

缓存击穿

问题:热点数据过期,导致大量请求访问数据库 解决方案

  • 设置热点数据永不过期
  • 使用互斥锁

缓存雪崩

问题:大量缓存同时过期,导致大量请求访问数据库 解决方案

  • 随机过期时间
  • 分层缓存
  • 预热缓存

10. 集群

主从复制

主从复制是 Redis 高可用的基础,它可以将主节点的数据复制到从节点。

bash
# 在从节点上执行
SLAVEOF host port

哨兵

哨兵是 Redis 高可用的解决方案,它可以监控主节点的状态,并在主节点故障时自动进行故障转移。

集群

Redis 集群是 Redis 水平扩展的解决方案,它可以将数据分布到多个节点。

11. 最佳实践

键命名规范

  • 使用冒号分隔命名空间:user:1:name
  • 使用小写字母和数字
  • 避免使用特殊字符
  • 保持键名简洁

内存管理

  • 设置最大内存:maxmemory <bytes>
  • 设置内存淘汰策略:maxmemory-policy allkeys-lru
  • 定期清理过期键
  • 避免存储大型对象

性能优化

  • 使用管道:减少网络开销
  • 使用批量命令:如 MSETMGET
  • 避免使用 KEYS 命令:它会阻塞 Redis
  • 使用 SCAN 命令代替 KEYS
  • 合理设置过期时间

安全

  • 设置密码:requirepass <password>
  • 限制访问 IP:bind 127.0.0.1
  • 禁用危险命令:rename-command FLUSHALL ""
  • 使用 ACL:Redis 6.0+ 支持访问控制列表

12. 工具推荐

管理工具

  • Redis CLI:命令行工具
  • RedisInsight:官方 GUI 工具
  • Another Redis Desktop Manager:开源 GUI 工具

监控工具

  • Redis Exporter:Prometheus 导出器
  • Grafana:可视化监控
  • Redis Sentinel:高可用监控

客户端库

  • Node.js:redis
  • Python:redis-py
  • Java:Jedis
  • PHP:phpredis

13. 常见问题与解决方案

内存不足

问题:Redis 内存使用过高 解决方案

  • 设置最大内存
  • 调整内存淘汰策略
  • 清理过期键
  • 分片

性能下降

问题:Redis 性能下降 解决方案

  • 检查是否有慢查询
  • 优化命令
  • 检查网络延迟
  • 考虑使用集群

数据丢失

问题:Redis 数据丢失 解决方案

  • 启用持久化
  • 使用主从复制
  • 使用哨兵或集群
  • 定期备份

连接问题

问题:无法连接到 Redis 解决方案

  • 检查 Redis 服务是否运行
  • 检查连接字符串是否正确
  • 检查防火墙设置

14. 总结

Redis 是一种高性能的内存数据库,它具有速度快、功能丰富等优点。通过学习 Redis 的基本概念和使用方法,我们可以有效地使用 Redis 作为缓存、会话管理、消息队列等。

Redis 的核心特性包括:

  • 多种数据结构
  • 持久化
  • 事务
  • 发布/订阅
  • 过期时间
  • 集群

通过合理的使用和优化,Redis 可以为各种应用场景提供高性能、可靠的缓存服务。