Redis-基础

Redis

本文使用 Docker 拉取 Redis 镜像并部署运行,整理 Redis 常用数据类型、命令、事务与持久化机制,作为学习和日常查阅笔记。同时,本文中不会介绍所有的指令,而是根据常用性来进行编写。如有遗漏请见谅

目录

  • [一、Docker 部署 Redis](#一、Docker 部署 Redis)
  • [二、进入 Redis CLI](#二、进入 Redis CLI)
  • [三、String 字符串](#三、String 字符串)
  • [四、Hash 哈希](#四、Hash 哈希)
  • [五、List 列表](#五、List 列表)
  • [六、Set 集合](#六、Set 集合)
  • [七、Sorted Set 有序集合](#七、Sorted Set 有序集合)
  • [八、Redis 全局命令](#八、Redis 全局命令)
  • [九、Redis 事务](#九、Redis 事务)
  • [十、Redis 持久化](#十、Redis 持久化)

一、Docker 部署 Redis

1. 拉取镜像

bash 复制代码
docker pull redis

2. 创建并运行容器

bash 复制代码
docker run -d -p 6379:6379 --name test-redis redis

参数说明:

参数 含义
-d 后台运行容器
-p 6379:6379 将宿主机 6379 端口映射到容器 6379 端口
--name test-redis 将容器命名为 test-redis
redis 使用 Redis 镜像创建容器

注意:以上是基础教学部署方式。容器删除或重建时,若没有配置数据卷,容器内的数据可能无法保留。实际使用时应考虑数据持久化和访问安全。

二、进入 Redis CLI

bash 复制代码
docker exec -it test-redis redis-cli

说明:

  • docker exec:在运行中的容器内执行命令。
  • -it:以交互式终端方式运行。
  • test-redis:容器名称。
  • redis-cli:Redis 命令行客户端。

三、String 字符串

String 是 Redis 最基本的数据类型,一个 Key 对应一个字符串值。可用于缓存文本、数字、计数器等数据。

命令 作用
SET key value 设置键值对;Key 已存在时覆盖原值
GET key 根据 Key 获取 Value
GETSET key value 设置新值,并返回旧值(新版本中已标记为弃用,推荐使用 SET key value GET)
SET key value EX seconds 设置键值对,并指定秒级过期时间
SETEX key seconds value 设置键值对,并指定秒级过期时间
TTL key 查看剩余过期时间;-1 表示永不过期,-2 表示 Key 不存在
SETNX key value 仅当 Key 不存在时设置值
INCR key 将数值加 1
DECR key 将数值减 1
INCRBY key num 将数值增加指定整数
APPEND key value 在原字符串末尾追加内容

示例:

redis 复制代码
SET username jack
GET username

SET code 200 EX 60
TTL code

INCR visits
INCRBY visits 10
APPEND username _admin

四、Hash 哈希

Hash 可以理解为一个 Key 对应一组 Field-Value 键值对,适合存储对象类型的数据。

例如:

text 复制代码
user:1001
├── name: jack
├── age: 20
└── city: Beijing

常用命令

命令 作用
HSET key field value [field value ...] 设置一个或多个字段和值
HSETNX key field value 字段不存在时才设置
HGET key field 获取指定字段的值
HMGET key field [field ...] 获取多个字段的值
HGETALL key 获取所有字段和值
HKEYS key 获取所有 Field
HVALS key 获取所有 Value
HDEL key field [field ...] 删除一个或多个字段
HEXISTS key field 判断字段是否存在,存在返回 1,不存在返回 0
HLEN key 获取字段数量
HINCRBY key field num 将指定字段增加一个整数,可为负数
HINCRBYFLOAT key field num 将指定字段增加一个浮点数

示例:

redis 复制代码
HSET user:1001 name jack age 20 city Beijing

HGET user:1001 name
HMGET user:1001 name age
HGETALL user:1001

HINCRBY user:1001 age 1
HDEL user:1001 city

五、List 列表

List 是一个有序的字符串列表,同一个 Key 对应一个列表。可以从列表左侧或右侧插入、弹出元素。

常用命令

命令 作用
LPUSH key value [value ...] 从列表左侧插入一个或多个元素
RPUSH key value [value ...] 从列表右侧插入一个或多个元素
LPOP key 从列表左侧弹出一个元素
RPOP key 从列表右侧弹出一个元素
LRANGE key start stop 获取指定下标范围内的元素,stop = -1 表示到列表末尾
LLEN key 获取列表长度

示例:

redis 复制代码
RPUSH queue task1 task2 task3
LPUSH queue task0

LRANGE queue 0 -1
LLEN queue

LPOP queue
RPOP queue

List 可以用于简单队列等场景。需要可靠消息投递、消费确认等能力时,应进一步学习 Redis Streams 或专业消息队列。


六、Set 集合

Set 是无序、元素唯一的字符串集合。一个 Key 对应一个集合。

常用命令

命令 作用
SADD key member [member ...] 添加一个或多个元素,重复元素不会重复存储
SMEMBERS key 获取集合中的所有元素
SREM key member [member ...] 删除一个或多个指定元素
SPOP key [count] 随机弹出一个或多个元素;不指定数量时默认一个
SCARD key 获取集合元素数量
SISMEMBER key member 判断元素是否存在于集合中

交集、并集与差集

命令 作用
SDIFF key1 key2 返回 key1 中存在、key2 中不存在的元素
SINTER key1 key2 返回两个集合共同拥有的元素
SUNION key1 key2 返回两个集合的所有元素,自动去重

示例:

redis 复制代码
SADD set:A apple banana orange
SADD set:B banana orange grape

SDIFF set:A set:B
SINTER set:A set:B
SUNION set:A set:B

七、Sorted Set 有序集合

Sorted Set 通常简称 ZSet。它与 Set 一样,元素唯一,但每个元素都会关联一个 Score(分数)。

Redis 根据 Score 自动维护元素的排序,默认按照分数从小到大排列。分数相同时,按照成员的字典序排列。

常用命令

命令 作用
ZADD key score member [score member ...] 添加一个或多个元素及其分数
ZINCRBY key increment member 将指定成员的分数增加指定值,可为负数
ZRANGE key start stop 按升序获取指定排名范围内的元素
ZREVRANGE key start stop 按降序获取指定排名范围内的元素
ZRANK key member 获取成员的升序排名,从 0 开始
ZREVRANK key member 获取成员的降序排名,从 0 开始
ZCARD key 获取集合元素数量

ZRANGE 和 ZREVRANGE 均可以追加 WITHSCORES,同时返回元素及其分数。

示例:

redis 复制代码
ZADD ranking 90 jack 85 tom 95 lucy

ZRANGE ranking 0 -1
ZRANGE ranking 0 -1 WITHSCORES

ZREVRANGE ranking 0 -1 WITHSCORES

ZINCRBY ranking 5 tom

ZRANK ranking jack
ZREVRANK ranking jack
ZCARD ranking

Redis 新版本还支持 ZRANGE key start stop REV 等写法,可用于替代部分旧式反向查询命令。


八、Redis 全局命令

全局命令主要用于查询、管理 Key 和数据库。

命令 作用
KEYS pattern 按模式查找 Key
EXISTS key [key ...] 判断一个或多个 Key 是否存在,返回存在的 Key 数量
EXPIRE key seconds 设置 Key 的秒级过期时间
PERSIST key 取消 Key 的过期时间
TTL key 查看 Key 剩余过期时间
SELECT index 切换数据库
MOVE key db 将 Key 移动到指定数据库
RENAME key newkey 重命名 Key
DBSIZE 查看当前数据库的 Key 数量
FLUSHDB 清空当前数据库
FLUSHALL 清空 Redis 中的所有数据库

1. KEYS 模式匹配

redis 复制代码
KEYS *
KEYS *b
KEYS b*
KEYS user:*

常见匹配规则:

  • *:匹配任意数量的字符。
  • ?:匹配任意单个字符。
  • [abc]:匹配指定字符中的任意一个。

注意:KEYS 在生产环境中可能阻塞 Redis,不建议对大量 Key 使用。生产环境遍历 Key 通常优先考虑 SCAN。

2. 数据库操作

Redis 默认提供 16 个逻辑数据库,编号为 0-15,默认使用数据库 0。

redis 复制代码
SELECT 1
DBSIZE

MOVE username 0
RENAME username new_username

3. 清空数据库

redis 复制代码
FLUSHDB

清空当前数据库。

redis 复制代码
FLUSHALL

清空所有数据库。

警告:清空操作具有破坏性,执行前务必确认当前环境和数据范围。


九、Redis 事务

Redis 事务与 MySQL 事务存在明显区别。

MySQL 事务支持通过 ROLLBACK 回滚事务,而 Redis 的 MULTI/EXEC 事务不提供这种回滚能力。

可以将 Redis 事务理解为:先将多条命令放入队列,执行 EXEC 时再按顺序执行。

1. 核心命令

命令 作用
MULTI 开启事务,后续命令进入事务队列
EXEC 执行事务队列中的命令
DISCARD 放弃事务队列
WATCH key [key ...] 监视一个或多个 Key,检测并发修改

2. 基本示例

redis 复制代码
MULTI

HSET test code 200
HSET test info success
HGET test code
HGET test info

EXEC

MULTI 之后,命令先进入队列,并不会立即执行;执行 EXEC 后才会依次执行。

3. 事务中的错误

Redis 事务需要区分两类错误:

  • 入队阶段错误:例如命令语法或参数错误,Redis 会拒绝执行整个事务。
  • 执行阶段错误:例如命令与 Key 的数据类型不匹配,该条命令执行失败,但其他命令仍会继续执行。

因此,Redis 事务不会因为某条命令执行失败,就自动撤销已经成功执行的命令。

4. WATCH 乐观锁

WATCH 用于监视 Key。如果从执行 WATCH 到提交 EXEC 期间,被监视的 Key 被其他客户端修改,那么本次事务不会执行。

redis 复制代码
WATCH money

MULTI
DECRBY money 10
EXEC

如果 money 在此期间被其他客户端修改,EXEC 会放弃执行事务队列。业务程序可以重新读取数据并重试。


十、Redis 持久化

Redis 默认将数据存放在内存中,具有读写速度快的优点,但 Redis 进程退出、服务器断电等异常情况可能导致数据丢失。

Redis 提供三种主要持久化方式:

  • RDB:快照持久化。
  • AOF:追加日志持久化。
  • 混合持久化:结合 RDB 与 AOF。

1. RDB(Redis Database)

RDB 将某个时间点的内存数据生成快照,并保存到磁盘。默认文件名通常为 dump.rdb。

1.1 手动触发

SAVE

redis 复制代码
SAVE
  • 在主进程中同步执行持久化。
  • 执行期间会阻塞 Redis 主线程。
  • 数据量较大时可能造成明显阻塞,生产环境应谨慎使用。

BGSAVE

redis 复制代码
BGSAVE
  • 创建子进程执行 RDB 持久化。
  • Redis 主进程可以继续处理客户端请求。
  • 通过操作系统的写时复制(Copy-On-Write,COW)机制,在生成快照时允许主进程继续修改数据。
1.2 自动触发

通过配置文件中的 save m n 规则设置自动快照:

redis 复制代码
save 60 10

含义:在 60 秒内,至少发生 10 次数据修改,就触发一次 BGSAVE。

这里统计的是数据库的写操作次数,不是修改了 10 个不同的 Key。

可以设置多条规则:

redis 复制代码
save 900 1
save 300 10
save 60 10000

满足其中任意一条规则,就会触发 RDB 快照。

2. AOF(Append Only File)

AOF 的核心思想是记录 Redis 执行的写操作命令,并将这些命令保存到磁盘文件中。

Redis 重启时,通过重新执行 AOF 文件中保存的写命令来恢复数据。

2.1 开启 AOF

在 Redis 配置文件中设置:

redis 复制代码
appendonly yes

关闭 AOF:

redis 复制代码
appendonly no

Redis 7 及以后版本通常采用多文件 AOF 结构,包含基础文件、增量文件和清单文件,不应简单理解为只有一个 appendonly.aof 文件。

2.2 AOF 三种同步策略

通过 appendfsync 配置:

always:每次写操作都请求同步到磁盘

redis 复制代码
appendfsync always
  • 数据安全性较高。
  • 磁盘 I/O 开销较大,性能相对较低。

everysec:每秒同步一次

redis 复制代码
appendfsync everysec
  • 每秒执行一次磁盘同步。
  • 在性能和数据安全性之间取得平衡。
  • 正常情况下,发生故障可能丢失最近约 1 秒的写入数据。

no:由操作系统决定何时同步

redis 复制代码
appendfsync no
  • Redis 不主动控制同步频率。
  • 性能通常较好。
  • 发生故障时可能丢失更多数据。
2.3 AOF 重写机制

随着 Redis 不断运行,AOF 文件可能越来越大。

例如,依次执行:

redis 复制代码
SET age 18
SET age 19
SET age 20
SET age 21

恢复最终状态实际上只需要:

redis 复制代码
SET age 21

因此 Redis 提供 AOF 重写机制,根据当前内存中的数据状态生成更精简的恢复文件。

手动触发:

redis 复制代码
BGREWRITEAOF

作用:

  • 减少冗余命令。
  • 降低 AOF 文件占用空间。
  • 提高 Redis 重启时的恢复效率。

注意:AOF 重写不是简单删除旧日志,而是根据当前数据状态生成新的 AOF 文件。

2.4 AOF 自动重写

可以通过以下配置控制:

redis 复制代码
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

含义:

  • AOF 文件至少达到 64MB。
  • 并且相对于上次重写后的文件大小增长达到 100%。
  • 满足条件后,Redis 自动触发 AOF 重写。

3. 混合持久化(RDB + AOF)

混合持久化将 RDB 和 AOF 两种机制结合起来。

开启配置:

redis 复制代码
aof-use-rdb-preamble yes

基本原理:

  1. 使用 RDB 格式保存基础数据。
  2. 使用 AOF 格式记录后续增量写操作。
  3. Redis 重启时,先加载基础数据,再重放增量命令。

优点:

  • 相比纯 AOF,通常恢复速度更快。
  • 相比单纯 RDB,通常能保留更多近期写入数据。
  • 兼顾恢复效率与数据安全性。

注意:混合持久化主要是在 AOF 文件中采用 RDB 格式保存基础数据,再追加 AOF 格式的增量命令,并不是简单地把两个独立文件拼在一起。

Redis 7 及以后版本使用 Multi-Part AOF(多部分 AOF)结构。

4. 三种持久化方式对比

对比 RDB AOF 混合持久化
保存方式 数据快照 写操作日志 RDB + AOF
文件大小 通常较小 通常较大 兼顾两者
恢复速度 通常较快 通常较慢 通常较快
数据丢失风险 取决于快照间隔 取决于同步策略 取决于同步策略
主要用途 数据备份 数据恢复 兼顾恢复效率和数据安全性

核心记忆:

  • RDB:记录某个时间点的数据状态。
  • AOF:记录数据是如何被修改的。
  • 混合持久化:先保存数据状态,再保存后续修改。

相关推荐
火山引擎开发者社区20 分钟前
案例实践 | 让 Agent 读懂业务口径:ContextSearch 在广告数据查询中的实践
数据库
10年前端老司机2 小时前
Milvus 8种检索能力实践
数据库·python·agent
鶴哥只手遮天2 小时前
《Redis 8.10.3 深度剖析》系列 ·第 10 章 Hash 一:`listpack`、`hashtable` 与 `LISTPACK_EX`
redis·后端·开源
Decay__2 小时前
14_MySQL 高可用与容灾架构 —— MGR / InnoDB Cluster / Keepalived+VIP / 双主 / 读写分离 / 两地三中心
运维·数据库·sql·mysql·架构
freejackman2 小时前
【实战三】撕开脱敏盲区:深度解析 CASE WHEN 与窗口函数血缘
大数据·数据库·sql
codigger4 小时前
线上数据库连接池打满:从应急止损到架构根治的完整方案
数据库·sql·程序员
倔强的石头_4 小时前
集中式与分布式怎么选?我把手头11套系统重新过了一遍秤
数据库
挖掘狂人4 小时前
线上数据库连接池打满:从应急止损到架构根治的完整方案
数据库·sql·程序员