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

基础命令与通用操作

连接 Redis、管理键空间、掌握最核心的通用命令

Redis 学习笔记 · 第 01 篇 · 大纲

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 <db-index>

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

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

实践建议

生产环境中不建议使用多数据库。原因:① 单线程模型下所有 db 共享同一个 CPU,无法隔离负载;② 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 timestampUnix 秒设置绝对过期时间点
PEXPIREAT key ms-timestampUnix 毫秒毫秒精度绝对时间

查询剩余时间

命令返回值
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 采用惰性删除 + 定期删除双重策略:① 访问 key 时检查是否过期(惰性);② 每秒 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 注意事项

COUNT 只是建议值,不保证每次恰好返回这么多;② 遍历期间如果有新增/删除 key,结果可能重复或遗漏(最终一致但非精确快照);③ 同类命令还有 HSCANSSCANZSCAN,用于遍历 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 parameter
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返回存在的数量
查看类型TYPEstring/list/set/zset/hash/stream
删除 keyDEL / UNLINKUNLINK 异步删除,大 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:2cache: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?为什么?