阶段一 · 基础命令与数据结构

基础命令与通用操作

1. 连接与启动

Redis 采用经典的客户端-服务器(Client-Server)架构. 服务端是一个单线程事件循环, 客户端通过 TCP 连接发送命令, 接收响应.

Redis 服务端 = 一家只有一个柜员的银行.
所有客户排队办业务, 柜员处理极快(纯内存操作), 所以队伍推进速度远超预期. 这就是"单线程但高性能"的直觉.

启动服务

# 前台启动(开发调试用)
redis-server

# 指定配置文件启动
redis-server /path/to/redis.conf

# 后台启动(生产环境在 redis.conf 中设置 daemonize yes)
redis-server --daemonize yes

连接服务

# 默认连接 127.0.0.1:6379
redis-cli

# 指定主机和端口
redis-cli -h 192.168.1.100 -p 6380

# 带密码认证
redis-cli -h 192.168.1.100 -a yourpassword

# 连接后测试是否正常
127.0.0.1:6379> PING
PONG

提示

PING 是最简单的健康检查命令. 返回 PONG 说明连接正常, 服务存活.

2. 数据库(Database)切换

Redis 默认提供 16 个逻辑数据库(编号 0~15), 彼此之间键空间隔离. 连接时默认进入 db 0.

SELECT

SELECT

切换到指定编号的数据库. 所有后续命令作用于新选中的数据库.

127.0.0.1:6379> SELECT 1
OK
127.0.0.1:6379[1]> SET hello world
OK
127.0.0.1:6379[1]> SELECT 0
OK
127.0.0.1:6379> GET hello
(nil) ← db0 中没有这个 key

实践建议

生产环境中不建议使用多数据库. 原因:

  1. 单线程模型下所有 db 共享同一个 CPU, 无法隔离负载
  2. Cluster 模式只支持 db0

需要隔离时应使用独立 Redis 实例.

DBSIZE

DBSIZE

返回当前数据库中 key 的总数量. O(1) 复杂度, 内部维护计数器.

FLUSHDB / FLUSHALL

FLUSHDB [ASYNC] / FLUSHALL [ASYNC]

FLUSHDB 清空当前数据库; FLUSHALL 清空所有数据库. 加 ASYNC 可在后台线程异步执行, 避免长时间阻塞. 生产环境极度危险, 务必谨慎.

3. 键的增删查改

Redis 的所有数据都以 key-value 形式存储. key 是字符串(String), value 的类型决定了可用的操作命令. 以下是与 key 本身相关的通用命令--无论 value 是什么类型都适用.

判断键是否存在

EXISTS

EXISTS key [key ...]

返回存在的 key 数量. 可一次传入多个 key 批量检查.

SET name "redis"
EXISTS name → (integer) 1
EXISTS name age → (integer) 1 ← 只有 name 存在
EXISTS nothing → (integer) 0

查看键的类型

TYPE

TYPE key

返回 key 对应 value 的数据类型: string / list / set / zset / hash / stream.

重命名

RENAME / RENAMENX

RENAME key newkey / RENAMENX key newkey

RENAME 强制重命名(newkey 已存在会被覆盖); RENAMENX 仅在 newkey 不存在时才重命名, 更安全.

删除键

DEL / UNLINK

DEL key [key ...] / UNLINK key [key ...]

两者都删除 key. 区别: DEL 同步阻塞删除; UNLINK 先解除键空间关联(O(1)), 实际内存回收交给后台线程, 适合删除大 key.

DEL = 立刻拆房子 -- 你得站在原地等挖掘机干完.
UNLINK = 先摘门牌号 -- 外人再也找不到这栋楼, 施工队后台慢慢拆, 你可以继续做别的事.

4. 生存时间(TTL)与过期

Redis 允许为任意 key 设置生存时间(Time To Live), 到期后自动删除. 这是实现缓存失效的核心机制.

设置过期时间

命令 单位 说明
EXPIRE key seconds 设置相对过期时间
PEXPIRE key ms 毫秒 毫秒精度
EXPIREAT key timestamp Unix 秒 设置绝对过期时间点
PEXPIREAT key ms-timestamp Unix 毫秒 毫秒精度绝对时间

查询剩余时间

命令 返回值
TTL key 剩余秒数. -1 = 永不过期, -2 = key 不存在
PTTL key 剩余毫秒数

移除过期时间

PERSIST

PERSIST key

移除 key 的过期时间, 使其变为永久存在.

SET session:abc "user123"
EXPIRE session:abc 3600 → (integer) 1
TTL session:abc → (integer) 3598 ← 还剩约1小时
PERSIST session:abc → (integer) 1
TTL session:abc → (integer) -1 ← 永久

过期删除策略

Redis 采用惰性删除 + 定期删除双重策略:

  1. 访问 key 时检查是否过期(惰性)
  2. 每秒 10 次随机抽样检查过期 key(定期)

这是在内存回收与 CPU 开销之间的平衡设计.

5. 键遍历: KEYS vs SCAN

KEYS - 简单但危险

KEYS

KEYS pattern

返回所有匹配 pattern 的 key. 支持 glob 风格通配符: *(任意), ?(单个字符), [abc](字符集).

KEYS *           → 所有 key(危险!)
KEYS user:* → 匹配 user: 开头
KEYS session:? → 匹配 session: + 一个字符

生产禁用

KEYS 会遍历整个键空间, O(N) 复杂度. 在 key 数量庞大的实例上执行会阻塞服务数秒甚至更久, 导致所有客户端超时. 生产环境应使用 SCAN 替代.

SCAN - 渐进式遍历

SCAN

SCAN cursor [MATCH pattern] [COUNT hint] [TYPE type]

基于游标的增量迭代. 每次返回一批 key + 下一个游标, 游标为 0 时遍历结束. 不会长时间阻塞.

# 第一次: cursor=0 开始
SCAN 0 MATCH user:* COUNT 100
→ 1) "17" ← 下次传入的游标
2) 1) "user:1001"
2) "user:1042"
3) "user:1007"

# 继续: cursor=17
SCAN 17 MATCH user:* COUNT 100
→ 1) "0" ← 游标为 0, 遍历结束
2) 1) "user:1099"

KEYS = 一口气翻完整本电话簿 -- 人少无所谓, 百万条目时你得等很久.
SCAN = 每次翻几页, 记下书签位置 -- 下次从书签继续, 随时可停, 不影响别人查阅.

SCAN 注意事项

  1. COUNT 只是建议值, 不保证每次恰好返回这么多
  2. 遍历期间如果有新增/删除 key, 结果可能重复或遗漏(最终一致但非精确快照)
  3. 同类命令还有 HSCAN, SSCAN, ZSCAN, 用于遍历 Hash/Set/ZSet 内部元素

6. 服务信息与基础配置

INFO

INFO [section]

返回服务器的各种信息和统计数据. 常用 section: server / memory / clients / stats / replication / keyspace

INFO memory
→ used_memory_human:1.20M
used_memory_peak_human:2.50M
mem_fragmentation_ratio:1.03

INFO keyspace
→ db0:keys=152,expires=30,avg_ttl=86400000

CONFIG GET / CONFIG SET

CONFIG GET pattern / CONFIG SET parameter value

动态查看和修改运行时配置, 无需重启服务. 修改立即生效但不会持久化到配置文件(需额外执行 CONFIG REWRITE).

CONFIG GET maxmemory
→ 1) "maxmemory"
2) "0" ← 0 表示不限制

CONFIG SET maxmemory 256mb
OK

CONFIG GET save
→ 1) "save"
2) "3600 1 300 100 60 10000" ← RDB 持久化策略
常用配置项 说明 默认值
maxmemory 最大内存限制 0(不限)
maxmemory-policy 内存淘汰策略 noeviction
timeout 空闲连接超时(秒) 0(不断开)
databases 数据库数量 16

快速回顾

场景 命令 要点
连接测试 PING 返回 PONG 即正常
判断 key 存在 EXISTS 返回存在的数量
查看类型 TYPE string/list/set/zset/hash/stream
删除 key DEL / UNLINK UNLINK 异步删除, 大 key 首选
设置过期 EXPIRE / PEXPIRE 秒/毫秒
查剩余时间 TTL / PTTL -1 永久, -2 不存在
模式匹配查找 SCAN 生产环境替代 KEYS
服务状态 INFO 分 section 查看
运行时配置 CONFIG GET/SET 即时生效, 需 REWRITE 持久化

动手练习

  1. 连接验证: 启动一个本地 Redis 实例, 用 redis-cli 连接并执行 PING, 确认连通.
  2. 键操作综合: 创建 3 个 key: user:1(值任意), user:2, cache:token, 然后用 EXISTS 一次性检查三个是否存在; 给 cache:token 设置 60 秒过期并用 TTL 确认; 用 SCAN 配合 MATCH user:* 找出所有 user 前缀的 key.
  3. 信息查看: 用 INFO keyspace 查看当前数据库 key 数量.
  4. 异步删除: 用 UNLINK 删除一个 key, 再用 EXISTS 验证已被删除.
  5. 思考题: 如果一个 Hash 类型的 key 内部有 100 万个 field, 删除它时应该用 DEL 还是 UNLINK? 为什么?