跳到主要内容

Redis 速查表:80+ 命令带真实生产坑(字符串、哈希、列表、集合、有序集合、Streams、发布订阅)

Redis 速查表,80+ 命令覆盖字符串/哈希/列表/集合/有序集合/发布订阅/Streams/脚本,带真实例子和坑。

  • 本地处理
  • 分类 开发运维
  • 适合 分享前检查文件类型、大小、元数据和明显不匹配信号。
152
(18)
GET key

取一个 key 上存的字符串值。key 不存在返回 nil。Redis 用得最多的一条,所有缓存读都走这里。

例子
GET user:1001:name
GET session:abc123
GET feature_flag:dark_mode
SET key value [EX seconds] [NX|XX]

把字符串值写到 key 上,可选过期时间。EX 按秒过期,NX 只在不存在时写(原子创建),XX 只在存在时写(原子更新)。

常见坑: 不带 EX 的 SET 会把 key 原本的 TTL 抹掉,新值永不过期。想"刷缓存保留 TTL"用 SET key val KEEPTTL(6.0+)或单独再 EXPIRE。

例子
SET user:1001:name "Alice"
SET lock:order:42 worker-7 EX 30 NX
SET cfg:rate_limit 100 XX
DEL key [key ...]

删一个或多个 key,返回真正被删的数量。同步操作,删一个百万字段的大 hash 会卡住事件循环。

常见坑: 大 key 用 UNLINK 替代,同步从 keyspace 摘掉,内存回收交给后台线程,不卡主线程。

例子
DEL user:1001:cache
DEL k1 k2 k3
UNLINK big_hash  -- 大 key 推荐
EXISTS key [key ...]

判断一个或多个 key 是否存在。传 N 个 key 时返回存在的数量(同一个 key 传两次算两次)。

例子
EXISTS user:1001
EXISTS k1 k2 k3
EXISTS missing  -- 返回 0
EXPIRE key seconds

给 key 设置以秒为单位的 TTL。计时到期后 key 被惰性删除,下次访问时或后台清理任务扫到时才真消失。

常见坑: 给不存在的 key 设 EXPIRE 静默返回 0,不会报错。设锁时务必检查返回值。

例子
EXPIRE session:abc 3600
EXPIRE cache:home_page 60
PEXPIRE k 500  -- 毫秒
TTL key

查 key 离过期还剩多少秒。-2 表示 key 不存在,-1 表示 key 存在但没设过期。

例子
TTL session:abc  -- 比如返回 1800
TTL forever_key  -- 返回 -1
PTTL k  -- 毫秒
PERSIST key

清除 key 的 TTL,让它变成永久。没 TTL 或 key 不存在返回 0,成功返回 1。

例子
PERSIST hot_session
PERSIST upgraded_cache_key
KEYS pattern

用 glob 模式扫整个数据库的 key(如 user:*)。一次性同步遍历整个 keyspace,生产环境绝不能用。

常见坑: 1000 万 key 的库上 KEYS * 能阻塞几秒钟,所有别的客户端全卡死。生产用 SCAN。KEYS 只在本地开发库用。

例子
KEYS user:*  -- 仅限本地
KEYS session:*
KEYS *:tmp
SCAN cursor [MATCH pattern] [COUNT n]

cursor 增量遍历 keyspace,KEYS 的安全替代。每次扫几个 bucket,返回下次用的新 cursor。cursor 回到 0 就扫完了。

常见坑: SCAN 跨轮次可能返回同一个 key 两次,扫描中新增/修改的 key 可能返回也可能不返回。客户端做去重。COUNT 是提示不是限制。

例子
SCAN 0 MATCH user:* COUNT 1000
SCAN 12345 MATCH session:*
while true; do cursor=$(redis-cli SCAN $cursor MATCH 'tmp:*' | head -1); ...; done
TYPE key

返回 key 上值的数据类型:string、list、set、zset、hash、stream,key 不存在返回 none。

例子
TYPE user:1001  -- hash
TYPE leaderboard  -- zset
TYPE missing  -- none
RENAME key newkey

原子重命名一个 key。newkey 已存在会被静默覆盖。要"目标存在就失败"用 RENAMENX。

常见坑: 集群模式下 RENAME 要求两个 key 在同一个 slot,用 {tag} 强制同槽:RENAME {usr}:1001 {usr}:1001:archived。

例子
RENAME old_key new_key
RENAMENX draft:42 published:42
UNLINK key [key ...]

和 DEL 一样删 key,但内存回收交给后台线程,不同步阻塞。任何可能很大的 key 都该用它删。

常见坑: 后台释放只在超过一定体积时才触发,小 key 还是同步释放,所以小 key 上 UNLINK 不比 DEL 快。收益全在大 key 上。

例子
UNLINK big_hash
UNLINK session:* 的批量 -- 配合 SCAN 拿到 key 再 UNLINK
COPY source destination [DB n] [REPLACE]

把 source 的值复制到 destination(6.2+)。REPLACE 覆盖已存在的目标,DB 复制到另一个库。复制会保留源 key 的 TTL。

例子
COPY user:1001 user:1001:backup
COPY cfg cfg:staging DB 1 REPLACE
DUMP key

把 key 的值序列化成 Redis 专用二进制串,RESTORE 能在别处重建。跨实例迁移 key 的工具底层就是这对命令。

常见坑: DUMP 串通常不跨大版本通用,RESTORE 会校验内嵌的版本和 CRC,不匹配就拒绝。在相同版本间迁移,或用支持 RESTORE 的迁移工具。

例子
DUMP user:1001
RESTORE user:1001:copy 0 "$serialized"  -- 0 表示无 TTL
RANDOMKEY

从当前库随机返回一个 key,库为空返回 nil。用于抽样检查 key 形态或估算 TTL 覆盖率。

例子
RANDOMKEY
for i in {1..100}; do redis-cli RANDOMKEY; done | sort | uniq -c  -- 采样看前缀分布
OBJECT ENCODING key

看 Redis 给某个值选的底层编码:listpack、intset、hashtable、skiplist、embstr、int 等。某个 key 比预期吃内存时第一步就查它。

常见坑: 小集合初始是紧凑的 listpack/intset,越过 hash-max-listpack-entries 等阈值后会悄悄切成 hashtable/skiplist。切换不可逆,每元素开销大约翻倍。

例子
OBJECT ENCODING leaderboard  -- listpack 或 skiplist
OBJECT ENCODING counter  -- int
OBJECT IDLETIME key

返回 key 有多少秒没被访问过(仅在 LRU 类 maxmemory-policy 下有意义)。手动清理前找冷 key 很好用。

例子
OBJECT IDLETIME old_cache  -- 比如 86400 表示一天没碰
OBJECT FREQ hot_key  -- LFU 策略下看访问频度
MOVE key db

把 key 从当前库移到同实例的另一个编号库。目标库已有同名 key 时不动(返回 0)。

常见坑: 集群模式没有编号库,MOVE 在集群里直接报错。多库本身也不推荐,隔离用 key 前缀或独立实例更好。

例子
MOVE session:abc 1
SELECT 1  -- 切到 1 号库验证
字符串 (14)
INCR key

把 key 上存的整数原子加 1。key 不存在先按 0 处理。返回新值。计数器和限流的基石。

常见坑: 值不是合法 int64 会报错。"abc" 或超过 int64 上限的字符串 INCR 会失败,计数 key 命名要单独区分开。

例子
INCR page_views:home
INCR rate_limit:ip:1.2.3.4
INCRBY user:42:credits 10
DECR key

把 key 上的整数原子减 1。常用于"固定容量资源池"释放名额。

例子
DECR inventory:sku:42
DECRBY queue_depth 5
APPEND key value

在 key 末尾追加字符串。key 不存在等价于 SET。返回追加后总长度。

例子
APPEND log:2026-05-26 "request_id=42\n"
APPEND buffer:user:1 chunk
GETSET key value

原子地写新值并返回旧值。常用于"重置计数器同时读出旧值",一个 round-trip 搞定。

常见坑: 6.2 起被 SET key value GET 取代,语义一样,选项更统一。两条都还能用。

例子
GETSET page_views:home 0
SET counter 0 GET  -- 推荐写法
STRLEN key

返回 key 上字符串的字节长度。key 不存在返回 0。常用于快速判断缓存是否填好。

例子
STRLEN session:abc  -- 比如返回 312
STRLEN empty_key  -- 0
SETEX key seconds value

一条命令原子写值并设秒级 TTL。等价于 SET key value EX seconds,但少敲两个 token。

例子
SETEX session:abc 3600 user_id=42
SETEX cache:home 60 "<html>..."
SETNX key value

key 不存在才写入。成功返回 1,已存在返回 0。"先到先得"的经典原语。

常见坑: 现代写法推荐 SET key value NX EX ttl,SETNX 没 TTL 选项,单独 EXPIRE 在两条命令间客户端崩了就留下个永不过期的 key。

例子
SETNX lock:order:42 worker-7
SET lock:order:42 worker-7 NX EX 30  -- 推荐
MSET key value [key value ...]

一次原子 round-trip 给多个 key 设多个值。要么全部设上,要么(它不会中途失败)一个都不缺,没有半成品 MSET。

例子
MSET user:1:name Alice user:1:age 30
MSETNX a 1 b 2  -- 全部不存在才设,原子
MGET key [key ...]

一次 round-trip 取多个字符串值,返回与输入对齐的数组。缺失的 key 在对应位置返回 nil。

常见坑: 集群模式下所有 key 必须在同一个 slot,否则 MGET 报 CROSSSLOT。用 {tag} 强制同槽,或客户端按 slot 分发。

例子
MGET user:1:name user:2:name user:3:name
MGET {usr}:1 {usr}:2  -- 集群下用 hash tag 同槽
INCRBYFLOAT key increment

给 key 的值加一个浮点数,以字符串返回新值。不需要单独的浮点类型就能做"金额加减"这类小数运算。

常见坑: 浮点舍入照样存在,0.1 + 0.2 不会精确等于 0.3。算钱请存"分"用 INCRBY,别拿"元"做 INCRBYFLOAT。

例子
INCRBYFLOAT account:42:balance 0.99
INCRBYFLOAT sensor:temp -1.5
SETRANGE key offset value

从指定字节偏移开始覆盖写 key 的字符串,偏移超过当前末尾时用 0 字节补齐。把字符串当成定长字节缓冲来用。

例子
SETRANGE packet:42 4 "PAYLOAD"
SETRANGE greeting 6 "Redis"  -- 改第 6 字节起的内容
GETRANGE key start end

按闭区间字节范围返回 key 字符串的子串,负数从尾算(-1 是最后一字节)。SETRANGE 的读对应命令。

例子
GETRANGE log_line 0 99  -- 前 100 字节
GETRANGE iso_date 0 3  -- 取年份 "2026"
GETDEL key

一步原子读出 key 的值并删除(6.2+)。"一次性 token"的干净原语,读到的同时它就没了。

例子
GETDEL otp:user:42  -- 一次性验证码
GETDEL pending_payload:abc
GETEX key [EX seconds | PERSIST]

读 key 的值并在同一条命令里调整它的 TTL(6.2+):EX 续期,PERSIST 清除过期。"滑动窗口会话"不用第二次 round-trip。

例子
GETEX session:abc EX 1800  -- 读会话并续 30 分钟
GETEX cache:home PERSIST  -- 读并转永久
哈希 (13)
HSET key field value [field value ...]

给 hash 设一个或多个 field。返回新增 field 数量(覆盖不计)。"对象上几个小字段"就用 hash。

常见坑: 4.0 起 HSET 支持多 field 一起写,旧 HMSET 已 deprecated。HMSET 还能跑,但新代码别用。

例子
HSET user:1001 name Alice age 30 email alice@x.io
HSET cart:42 sku:1 2 sku:2 1
HGET key field

取 hash 上某个 field 的值。field 或 key 不存在返回 nil。

例子
HGET user:1001 name  -- "Alice"
HGET cfg dark_mode
HMGET key field [field ...]

一次 round-trip 取 hash 多个 field。返回数组,缺失的位置是 nil,顺序与输入对齐。

例子
HMGET user:1001 name age email
HMGET cfg theme lang tz
HDEL key field [field ...]

删 hash 上一个或多个 field。返回实际删除数。删到最后一个 field,hash 本身也消失。

例子
HDEL user:1001 stale_flag
HDEL cart:42 sku:1 sku:3
HKEYS key

返回 hash 所有 field 名,顺序任意。复杂度 O(N),几十个 field 没事,百万级危险。

例子
HKEYS user:1001
HKEYS cfg
HVALS key

返回 hash 所有 value,顺序任意。复杂度同 HKEYS,大 hash 用 HSCAN。

例子
HVALS cfg
HVALS leaderboard_summary
HGETALL key

把 hash 所有 field 和 value 平铺返回 [f1, v1, f2, v2, ...]。方便,但大 hash 上是定时炸弹。

常见坑: 10 万+ field 的 hash 上 HGETALL 一次能返回几 MB 数据,阻塞事件循环,客户端内存也爆。改用 HSCAN 或把 hash 拆开。

例子
HGETALL user:1001
HSCAN big_hash 0 COUNT 500  -- 安全替代
HINCRBY key field increment

原子地给 hash 上某 field 加整数。field 不存在按 0 自动建。"每用户多维计数"的基石。

例子
HINCRBY user:1001:stats login_count 1
HINCRBY user:1001:stats bytes_uploaded 4096
HINCRBYFLOAT user:1001:wallet usd 0.99
HSETNX key field value

field 不存在才写入。新建返回 1,已存在返回 0。hash 上"按字段先到先得"。

例子
HSETNX user:1001 created_at 1716700000
HSETNX cfg first_seen_version 5
HEXISTS key field

判断 hash 上某个 field 是否存在。O(1)。存在返回 1,field 或整个 hash 不在返回 0。

例子
HEXISTS user:1001 email
HEXISTS cfg dark_mode  -- 0 表示未设置过
HLEN key

返回 hash 的 field 数量。O(1),计数在 hash 头里。key 不存在返回 0。

例子
HLEN user:1001  -- 比如 5 个字段
HLEN cart:42  -- 购物车 SKU 数
HSCAN key cursor [MATCH pattern] [COUNT n] [NOVALUES]

cursor 增量遍历 hash,大 hash 上 HGETALL 的安全替代。NOVALUES(7.4+)只返回 field 名,payload 减半。

常见坑: 和 SCAN 一样,HSCAN 跨轮次可能重复返回同一个 field,COUNT 只是提示。客户端按集合去重处理。

例子
HSCAN big_hash 0 MATCH attr:* COUNT 500
HSCAN user:1001 0 NOVALUES  -- 只要字段名(7.4+)
HRANDFIELD key [count [WITHVALUES]]

从 hash 随机返回字段(6.2+)。正 count 返回不重复字段,负 count 允许重复。WITHVALUES 同时带上值。

例子
HRANDFIELD user:1001  -- 随机一个字段
HRANDFIELD quiz_bank 3 WITHVALUES  -- 随机抽 3 道题
列表 (15)
LPUSH key value [value ...]

把一个或多个值压到 list 头(左侧)。list 不存在自动建。返回新长度。配 RPOP 做 FIFO 队列。

例子
LPUSH queue:jobs job_42
LPUSH queue:jobs job_43 job_44  -- 多值
LPUSH log:errors "$timestamp $msg"
RPUSH key value [value ...]

把值压到 list 尾(右侧)。配 LPOP 是 FIFO,配 RPOP 是 LIFO。亚毫秒级。

例子
RPUSH queue:jobs job_42
RPUSH timeline:1001 "post:42"
LPOP key [count]

从 list 头弹出并返回一个值。带 count(6.2+)可一次弹 N 个。空 list 或缺失返回 nil。

例子
LPOP queue:jobs
LPOP queue:jobs 10  -- 一次取一批
RPOP key [count]

从 list 尾弹出并返回一个值。形参与 LPOP 一致,带 count 一次最多弹 N 个。

例子
RPOP queue:jobs
RPOP queue:jobs 100
LRANGE key start stop

按下标返回 list 切片。两端闭区间,负数从尾开始(-1 是最后一个)。LRANGE k 0 -1 取全表。

常见坑: LRANGE k 0 -1 在百万级 list 上是 O(N),全量传回客户端。务必分页(LRANGE k 0 99,再 100 199,依次)。

例子
LRANGE timeline 0 9  -- 前 10 条
LRANGE timeline -10 -1  -- 最后 10 条
LLEN key

返回 list 长度。O(1),头里有计数。key 不存在返回 0。

例子
LLEN queue:jobs  -- 比如 42
LLEN missing  -- 0
LINDEX key index

取 list 指定下标的元素。负数从尾算。O(N),长 list 别在热路径用。

例子
LINDEX timeline 0  -- 第一条
LINDEX timeline -1  -- 最后一条
LREM key count value

从 list 删除最多 |count| 个值匹配的元素。count > 0 从头开始,< 0 从尾开始,0 删全部。返回实际删除数。

例子
LREM dedupe_queue 1 job_42  -- 从头删第一个
LREM dedupe_queue 0 job_42  -- 全删
BLPOP key [key ...] timeout

阻塞左弹:在给定 list 上最多等 timeout 秒(0 表示永远等),有数据立刻返回 [key, value],超时返回 nil。

常见坑: 集群模式下所有 key 必须落同一个 slot,用 {tag}。每个阻塞客户端占一个连接,1 万 worker 就是 1 万长连接,Redis 端要规划。

例子
BLPOP queue:jobs 5
BLPOP queue:high queue:low 0  -- 优先级队列
LSET key index value

用新值覆盖 list 指定下标的元素。下标越界报错。负数从尾算。

例子
LSET timeline 0 "post:99"  -- 改最新一条
LSET queue -1 "retry:job_42"  -- 改最后一个
LTRIM key start stop

把 list 裁剪到只保留闭区间内的元素,其余全丢弃。维护"最近 N 条"定长 feed 的标准做法。

常见坑: LPUSH 后 LTRIM 是封顶列表的经典写法,但要放进 MULTI 或 Lua,两条命令之间 list 会短暂超出上限,并发读者会看到多出来的条目。

例子
LPUSH feed:1001 "post:99"
LTRIM feed:1001 0 99  -- 只留最新 100 条
LTRIM log 0 -1  -- 不变(保留全部)
LINSERT key BEFORE|AFTER pivot value

在第一个匹配 pivot 的元素前或后插入一个值。返回新长度,找不到 pivot 返回 -1,key 不存在返回 0。

常见坑: LINSERT 从头扫找 pivot,O(N)。长 list 上慢,而且只在第一个匹配处插入,不是所有匹配处。

例子
LINSERT playlist BEFORE "song:5" "song:ad"
LINSERT steps AFTER "build" "test"
RPOPLPUSH source destination

原子地从 source 尾弹出并压到 destination 头,返回被移动的元素。"可靠队列"的经典积木。

常见坑: 6.2 起被 LMOVE 取代,LMOVE 两边都能选方向。模式:RPOPLPUSH queue processing,活干成功后再从 processing 删,崩了能重放。

例子
RPOPLPUSH queue processing
LMOVE queue processing LEFT RIGHT  -- 推荐(6.2+)
BRPOPLPUSH source destination timeout

RPOPLPUSH 的阻塞版:在 source 上最多等 timeout 秒,有元素就原子移到 destination。可靠 worker 队列靠它。

常见坑: 6.2 起 deprecated,用 BLMOVE。可靠队列思路:worker BLMOVE jobs→inflight,处理完从 inflight LREM,再由定时巡检把卡在 inflight 太久的重新入队。

例子
BRPOPLPUSH jobs inflight 5
BLMOVE jobs inflight LEFT RIGHT 5  -- 推荐(6.2+)
BRPOP key [key ...] timeout

阻塞右弹:在给定 list 尾上最多等 timeout 秒(0 永远等)。返回 [key, value],超时返回 nil。

例子
BRPOP queue:jobs 5
BRPOP queue:high queue:low 0  -- 配 RPUSH 做 FIFO 优先级队列
集合 (13)
SADD key member [member ...]

给 set 加一个或多个成员。返回新增数(已存在的静默忽略)。set 提供 O(1) 成员判断。

例子
SADD online_users 1001 1002 1003
SADD tags:post:42 redis tutorial cache
SREM key member [member ...]

从 set 删一个或多个成员。返回实际删除数。删到最后一个成员,set 本身也消失。

例子
SREM online_users 1001
SREM tags:post:42 deprecated
SMEMBERS key

返回 set 全部成员,顺序任意。O(N),"一篇博文的 tag" 几十个没事,几十万的大 set 危险。

常见坑: 大 set 用 SSCAN。100 万成员的 set 上 SMEMBERS 一次返回百万字符串,吃掉客户端内存还卡 Redis。

例子
SMEMBERS tags:post:42
SSCAN big_set 0 COUNT 500  -- 大 set 安全替代
SISMEMBER key member

判断成员是否在 set 中。O(1)。"按用户的 feature flag、在线状态、封禁 IP" 的基石。

例子
SISMEMBER online_users 1001
SISMEMBER banned_ips 1.2.3.4
SMISMEMBER online_users 1001 1002 1003  -- 批量(6.2+)
SUNION key [key ...]

返回多个 set 的并集,任一 set 里出现过的去重成员。常用于"今天或昨天活跃的用户"这类查询。

例子
SUNION active:today active:yesterday
SUNIONSTORE active:48h active:today active:yesterday
SINTER key [key ...]

返回多个 set 的交集,在每个 set 都出现的成员。常用于"同时点了广告 A 和广告 B 的用户"这种人群计算。

常见坑: 复杂度 O(N*M),N 是最小 set 的大小,M 是 set 数量。最小 set 放第一个,Redis 早期 miss 就剪枝。

例子
SINTER ad_A_clickers ad_B_clickers
SINTERSTORE both_clickers ad_A_clickers ad_B_clickers
SDIFF key [key ...]

返回在第一个 set 但不在后续任何 set 的成员。Redis 实现"没看过弹窗的用户"的标准做法。

例子
SDIFF all_users popup_seen
SDIFFSTORE retarget all_users popup_seen unsubscribed
SCARD key

返回 set 的成员数。O(1),基数记在 set 头里。key 不存在返回 0。

例子
SCARD online_users  -- 当前在线数
SCARD tags:post:42
SPOP key [count]

随机移除并返回 set 中的一个或多个成员。和 SRANDMEMBER 不同,SPOP 会改 set。常用于"无放回抽 N 个中奖者"。

例子
SPOP raffle:pool  -- 抽一个并移出
SPOP raffle:pool 3  -- 一次抽 3 个不重复
SRANDMEMBER key [count]

从 set 随机返回成员但不移除。正 count 返回不重复成员,负 count 允许重复、数量可超过 set 大小。

例子
SRANDMEMBER products:featured 4  -- 随机推荐 4 个
SRANDMEMBER dice:faces -10  -- 模拟 10 次有放回掷骰
SMOVE source destination member

原子地把一个成员从一个 set 移到另一个。成功返回 1,成员不在 source 返回 0。一步同时改两个 set。

例子
SMOVE pending approved order:42
SMOVE online away user:1001
SSCAN key cursor [MATCH pattern] [COUNT n]

cursor 增量遍历 set,大 set 上 SMEMBERS 的安全替代。每次扫几个 bucket,cursor 回到 0 就完。

例子
SSCAN ip:banned 0 MATCH "10.*" COUNT 500
SSCAN set:huge 0 COUNT 1000
SINTERCARD numkeys key [key ...] [LIMIT n]

返回多个 set 交集的大小,但不实际构造交集(7.0+)。LIMIT 数到 n 就提前停,"是否至少有 n 个共同成员"比 SINTER 便宜得多。

例子
SINTERCARD 2 ad_A_clickers ad_B_clickers
SINTERCARD 2 followers:1 followers:2 LIMIT 1  -- 只问有无共同关注
有序集合 (13)
ZADD key [NX|XX] [GT|LT] [CH] score member [score member ...]

给 zset 加或更新成员。NX 跳过更新,XX 跳过插入,GT/LT 只在新分数更大/更小时更新。返回新增数(带 CH 时返回变更数)。

例子
ZADD leaderboard 100 alice 95 bob 110 carol
ZADD high_scores GT 200 alice  -- 仅当 200 比当前高才更新
ZADD jobs:scheduled 1716700000 job_42  -- 用时间戳当分数
ZRANGE key start stop [WITHSCORES] [REV] [BYSCORE|BYLEX] [LIMIT offset count]

zset 范围查询。默认按 rank 升序,REV 反序,BYSCORE 改成分数区间,BYLEX 改成字典序区间。6.2+ 的万能瑞士军刀。

例子
ZRANGE leaderboard 0 9 WITHSCORES  -- 前 10
ZRANGE leaderboard 0 9 REV WITHSCORES  -- top 10 倒序
ZRANGE leaderboard 100 200 BYSCORE LIMIT 0 50
ZREVRANGE key start stop [WITHSCORES]

按分数从高到低返回成员。6.2+ 等价于 ZRANGE ... REV。"top N 排行榜"标准写法。

常见坑: 6.2 起 deprecated,新代码用 ZRANGE ... REV。旧命令还能跑,行为完全一致。

例子
ZREVRANGE leaderboard 0 9 WITHSCORES
ZRANGE leaderboard 0 9 REV WITHSCORES  -- 推荐
ZRANGEBYSCORE key min max [LIMIT offset count]

返回分数在 [min, max] 区间的成员。( 表示开区间。"该跑的定时任务"用时间戳当分数就是这条。

例子
ZRANGEBYSCORE jobs:scheduled -inf 1716700000  -- 时间戳之前
ZRANGEBYSCORE leaderboard (100 200  -- (100, 200]
ZRANGEBYSCORE leaderboard 100 +inf LIMIT 0 50
ZINCRBY key increment member

原子地给 zset 成员的分数加 increment。成员不存在按 increment 自动建。

例子
ZINCRBY leaderboard 10 alice
ZINCRBY trending:topics 1 "redis"
ZRANK key member [WITHSCORE]

按分数升序返回成员的 0-based 排名。成员不存在返回 nil。ZREVRANK 是高到低排名。

例子
ZRANK leaderboard alice  -- 比如 5
ZREVRANK leaderboard alice  -- 高到低
ZRANK leaderboard alice WITHSCORE  -- 7.2+
ZSCORE key member

以字符串返回 zset 中某成员的分数,成员不存在返回 nil。O(1)。ZMSCORE(6.2+)一次取多个分数。

例子
ZSCORE leaderboard alice  -- 比如 "110"
ZMSCORE leaderboard alice bob carol  -- 批量(6.2+)
ZCARD key

返回 zset 的成员数。O(1)。key 不存在返回 0。配 ZCOUNT 数某个分数区间内的成员。

例子
ZCARD leaderboard  -- 总参赛人数
ZCOUNT leaderboard 90 100  -- 分数在 [90,100] 的人数
ZREM key member [member ...]

从 zset 删一个或多个成员。返回实际删除数。删到最后一个成员,key 消失。排行榜清退的基础。

例子
ZREM leaderboard cheater_42
ZREM jobs:scheduled job_done_1 job_done_2
ZPOPMIN key [count]

原子移除并返回分数最低的成员(5.0+),每个带上分数。"最小分数优先队列"的天然弹出。

例子
ZPOPMIN jobs:scheduled  -- 取最早该跑的任务
ZPOPMIN delay_queue 10  -- 一次取 10 个
ZPOPMAX key [count]

原子移除并返回分数最高的成员(5.0+),每个带分数。BZPOPMIN / BZPOPMAX 是给队列 worker 用的阻塞版。

例子
ZPOPMAX high_scores  -- 取当前最高分并移出
BZPOPMIN delay_queue 5  -- 阻塞取最小分数(5.0+)
ZREMRANGEBYSCORE key min max

删除所有分数落在 [min, max] 的成员。用时间戳当分数时,这就是滑动窗口集合上"清掉早于某时刻的全部"的一行写法。

例子
ZREMRANGEBYSCORE rate_limit:ip:1.2.3.4 -inf (1716700000  -- 滑窗限流清旧
ZREMRANGEBYRANK leaderboard 0 -101  -- 只留 top 100
ZRANGESTORE dest src min max [BYSCORE|BYLEX] [REV] [LIMIT off count]

执行一次 ZRANGE 查询,把结果成员(带分数)存进目标 zset(6.2+)。在服务端固化一份"top N"快照,不用把数据传回客户端。

例子
ZRANGESTORE top10 leaderboard 0 9 REV  -- 固化前 10 名
ZUNIONSTORE combined 2 lb:eu lb:us  -- 合并两个榜
位图 (6)
SETBIT key offset value

在 string 上指定偏移设置一个 bit(0 或 1)。偏移超过当前长度时自动用 0 字节补齐。"日活用户位图"的基础。

常见坑: SETBIT k 100000000 1 瞬间分配 12.5 MB。注意偏移,user_id*8 和 user_id 写错能炸内存。

例子
SETBIT dau:2026-05-26 1001 1
SETBIT feature:beta 42 1
GETBIT key offset

读 string 指定偏移上的 bit(0 或 1)。偏移超过 string 长度返回 0。

例子
GETBIT dau:2026-05-26 1001  -- 1 表示活跃
GETBIT feature:beta 42
BITCOUNT key [start end [BYTE|BIT]]

统计 string 中为 1 的 bit 数,可选范围(按字节或按位)。"今天有多少用户活跃"最快的写法。

例子
BITCOUNT dau:2026-05-26  -- 当日总活跃数
BITCOUNT dau:2026-05-26 0 999 BYTE
BITOP AND|OR|XOR|NOT destkey key [key ...]

对一个或多个 string 做按位运算,结果写入 destkey。配合每日 DAU 位图可算周留存、流失、N 日活跃人群。

常见坑: BITOP 是 O(N),按最长 source 算。1000 万用户的日 DAU 位图是 1.25 MB,OK,但跨一年 OR 一次写入 destkey 超过 450 MB。

例子
BITOP AND retention:7d dau:2026-05-20 dau:2026-05-26
BITOP OR active:week dau:2026-05-20 dau:2026-05-21 ... dau:2026-05-26
BITPOS key bit [start [end [BYTE|BIT]]]

找出 string 中第一个为 0 或 1 的 bit 的位置,可选范围。用位图做"找第一个空槽位"分配器时很顺手。

例子
BITPOS slots 0  -- 第一个空闲槽
BITPOS dau:2026-05-26 1  -- 第一个活跃用户的位
BITFIELD key [GET|SET|INCRBY type offset value] [OVERFLOW WRAP|SAT|FAIL]

把一个 string 当成任意位宽的有/无符号整数数组,一条原子命令里读写多个字段。OVERFLOW 控制溢出时回绕 / 饱和 / 失败。

常见坑: 偏移以类型为单位,除非加 # 前缀。BITFIELD k SET u8 #0 和 BITFIELD k SET u8 0 含义不同,# 会乘上类型位宽。两种混用会写乱布局。

例子
BITFIELD stats INCRBY u8 #0 1 GET u8 #0  -- 第 0 个 u8 加 1 并读回
BITFIELD counter OVERFLOW SAT INCRBY u8 #0 200  -- 饱和到 255 不回绕
HyperLogLog (4)
PFADD key element [element ...]

把一个或多个元素加入 HyperLogLog。估算基数变了返回 1,否则 0。无论加多少元素,固定占 12 KB。

常见坑: HyperLogLog 是估算,标准误差约 0.81%。需要精确计数的场景(计费、审计)绝不能用。十亿级 UV / 去重用它正合适。

例子
PFADD uv:2026-05-26 user_1001 user_1002
PFADD uniq_search_terms "redis cheat"
PFCOUNT key [key ...]

返回一个 HyperLogLog 的近似基数,多 key 则返回合并后的基数。单 key O(1),合并 O(N)。

例子
PFCOUNT uv:2026-05-26
PFCOUNT uv:2026-05-20 uv:2026-05-21 uv:2026-05-26  -- 多日合并
PFMERGE destkey sourcekey [sourcekey ...]

把多个 HyperLogLog 合并到 destkey。幂等,同样的 source 重复合并结果一样。"日 UV 合算月 UV"常用。

例子
PFMERGE uv:2026-05 uv:2026-05-01 uv:2026-05-02 ... uv:2026-05-31
PFADD vs Set memory

HyperLogLog 数唯一元素,无论加多少都固定约 12 KB,而存同样成员的 Set 会线性增长。用精确性换恒定内存。

常见坑: 如果你将来要拿到真实成员(不只是数量),就不能用 HLL,它是单向的。需要枚举才留真 Set,只算基数就用 HLL。

例子
PFADD uv:2026-05-26 u1 u2 u3
MEMORY USAGE uv:2026-05-26  -- 约 12KB 上限
发布订阅 (5)
PUBLISH channel message

向 channel 上每个 SUBSCRIBE 的客户端广播消息。返回接收的订阅者数。Fire-and-forget,不持久化,不可重放。

常见坑: PUBLISH 时不在线的订阅者永远收不到,不缓冲。要至少一次送达用 Streams(XADD + XREADGROUP)。

例子
PUBLISH events:user_signup user_1001
PUBLISH chat:room:42 "hello"
SUBSCRIBE channel [channel ...]

订阅一个或多个 channel。连接进入订阅模式,UNSUBSCRIBE 前大多数普通命令禁用。

例子
SUBSCRIBE events:user_signup
SUBSCRIBE chat:room:42 chat:room:43
PSUBSCRIBE pattern [pattern ...]

按 glob 模式订阅所有匹配的 channel。每条消息会带上实际命中的 channel 名和命中的 pattern。

常见坑: PSUBSCRIBE chat:* 命中所有 chat:N,10 个房间 OK,1000 万个会卡。每次 PUBLISH 都过 pattern,复杂度 O(patterns * subscribers)。

例子
PSUBSCRIBE chat:*
PSUBSCRIBE events:*
PUBSUB CHANNELS [pattern]

列出当前至少有一个订阅者的活跃 channel,可按 glob 过滤。"现在谁在听哪个频道"的自省命令。

例子
PUBSUB CHANNELS
PUBSUB CHANNELS chat:*
PUBSUB NUMSUB chat:42  -- 某频道订阅者数
SPUBLISH shardchannel message

在 Redis 集群里向分片 channel 发布(7.0+)。和普通 PUBLISH 不同,分片 pub/sub 按 slot 路由,不向每个节点广播,因此能随集群扩展。

常见坑: 集群里普通 PUBLISH 会把消息扇出到每个节点,不可扩展。集群高吞吐 pub/sub 用 SPUBLISH + SSUBSCRIBE,流量留在归属分片上。

例子
SPUBLISH orders:shard "new_order"
SSUBSCRIBE orders:shard  -- 分片订阅(7.0+)
Streams (10)
XADD key [MAXLEN [~|=] N] * field value [field value ...]

向 stream 追加新条目。* 表示由 Redis 分配 ID(毫秒时间戳 + 序号)。MAXLEN 配 ~ 是近似截断,配 = 是精确截断。Streams 是 Pub/Sub 的持久可重放替代品。

常见坑: 不带 MAXLEN 的 stream 会无限增长吃光内存。生产 stream 一定要封顶(MAXLEN ~ 1000000)或定期 XTRIM。~ 比 = 便宜得多。

例子
XADD events:orders * user 1001 sku 42 qty 2
XADD events:orders MAXLEN ~ 100000 * user 1001 sku 42
XREAD [COUNT n] [BLOCK ms] STREAMS key [key ...] id [id ...]

读多个 stream 中给定 ID 之后的新条目。$ 表示"仅我开始等之后新加的"。BLOCK 0 永远等。

例子
XREAD COUNT 100 STREAMS events:orders 0
XREAD BLOCK 5000 STREAMS events:orders $
XREADGROUP GROUP grp consumer [COUNT n] [BLOCK ms] STREAMS key id

消费者组读,Redis 按 consumer 跟踪投递,至少一次语义。ID = > 表示"该 consumer 还没看过的新消息"。处理完配 XACK。

常见坑: 先用 XGROUP CREATE 建组,组不存在时 XREADGROUP 报错。consumer 崩了用 XPENDING + XCLAIM 把它待处理的消息转给别人。

例子
XGROUP CREATE events:orders processors $ MKSTREAM
XREADGROUP GROUP processors worker-1 COUNT 100 BLOCK 5000 STREAMS events:orders >
XACK key group id [id ...]

告诉消费者组某些条目已处理。不 XACK 的条目留在 pending list 里,崩溃后可以被重新分派。

例子
XACK events:orders processors 1716700000-0
XLEN key

返回 stream 当前条目数。O(1)。配 XINFO STREAM key 看完整元数据(首尾条目、消费组、长度)。

例子
XLEN events:orders
XINFO STREAM events:orders
XRANGE key start end [COUNT n]

返回 ID 落在闭区间 [start, end] 的 stream 条目。- 和 + 表示最小和最大可能 ID,所以 XRANGE k - + COUNT 10 读最旧的 10 条。

例子
XRANGE events:orders - + COUNT 10  -- 最旧 10 条
XREVRANGE events:orders + - COUNT 10  -- 最新 10 条
XPENDING key group [IDLE ms] [start end count [consumer]]

查看投递给消费组但还没 XACK 的条目。简要形式给出待处理总数和各 consumer 的计数,扩展形式列出具体卡住的条目。

常见坑: XPENDING 数持续增长说明 consumer 在崩或太慢,条目会一直堆到被认领为止。配一个巡检进程,XCLAIM 空闲超阈值的条目,把毒消息转到死信 stream。

例子
XPENDING events:orders processors  -- 概览
XPENDING events:orders processors IDLE 60000 - + 100  -- 卡超过 60s 的
XCLAIM key group consumer min-idle-time id [id ...]

把待处理且空闲至少 min-idle-time 的条目转给另一个 consumer。worker 处理到一半挂掉时的恢复原语。

常见坑: XAUTOCLAIM(6.2+)通常更省事:一次调用扫描、认领并返回 cursor,不用先 XPENDING。务必给重试次数封顶,反复失败的条目应转入死信 stream。

例子
XCLAIM events:orders processors worker-2 60000 1716700000-0
XAUTOCLAIM events:orders processors worker-2 60000 0  -- 推荐(6.2+)
XGROUP CREATE key group id [MKSTREAM]

在 stream 上建消费组,从给定 ID 开始($ 仅新条目,0 从头)。MKSTREAM 在 stream 还不存在时自动创建。

常见坑: 不带 MKSTREAM 时,对不存在的 stream 建组会报错。从 $ 开始意味着组会忽略所有已有条目,要处理积压就从 0 开始。

例子
XGROUP CREATE events:orders processors $ MKSTREAM
XGROUP CREATECONSUMER events:orders processors worker-3  -- 显式建消费者
XTRIM key MAXLEN|MINID [~|=] threshold

按长度(MAXLEN)或最小 ID(MINID,6.2+)裁剪 stream。~ 是近似裁剪,便宜得多,因为只整块丢弃宏节点。

例子
XTRIM events:orders MAXLEN ~ 1000000
XTRIM events:orders MINID 1716700000000  -- 丢弃此时间戳前的(6.2+)
脚本 Lua (5)
EVAL script numkeys key [key ...] arg [arg ...]

原子执行一段 Lua 脚本。所有 key 必须通过 numkeys + KEYS[] 声明。脚本沙箱里运行,单线程,每一行都会阻塞服务器。

常见坑: 长脚本阻塞所有别的客户端。硬上限是 lua-time-limit(默认 5 秒),超时只能 SCRIPT KILL 或 SHUTDOWN NOSAVE 恢复。脚本控制在几条命令以内。

例子
EVAL "return redis.call('GET', KEYS[1])" 1 mykey
EVAL "local v = redis.call('INCR', KEYS[1]); if v > tonumber(ARGV[1]) then redis.call('DEL', KEYS[1]); return 0 end; return v" 1 rate_limit 100
EVALSHA sha1 numkeys key [key ...] arg [arg ...]

按 SHA-1 摘要执行已缓存的脚本。每次调用从整段脚本压缩到 40 个十六进制字符。遇 NOSCRIPT 错误回退到 EVAL。

例子
EVALSHA a9d8b1c... 1 rate_limit 100
-- 通常配合 SCRIPT LOAD: SHA=$(redis-cli SCRIPT LOAD "$src"); redis-cli EVALSHA $SHA ...
SCRIPT LOAD script

把脚本缓存到服务器并返回 SHA-1。不会执行。常用于启动时预热,之后一直用 EVALSHA。

常见坑: FLUSHALL 或重启会清掉脚本缓存,每个客户端要能在 NOSCRIPT 时重新 LOAD。集群模式下要在每个分片单独 LOAD。

例子
SCRIPT LOAD "return 1"  -- 返回 e0e1f9fabfc9d4800c877a703b823ac0578ff831
FCALL function numkeys key [key ...] arg [arg ...]

调用已加载 Redis Functions 库里的具名函数(7.0+)。Functions 是 EVAL 脚本的持久化继任者,按名注册,随 RDB/AOF 持久化并复制。

常见坑: 和 EVAL 脚本不同(FLUSHALL/重启就没),FUNCTION LOAD 的库会在重启后保留并自动复制到副本。把高频 EVALSHA 路径迁到 FUNCTION,运维省心。

例子
FUNCTION LOAD "#!lua name=mylib\nredis.register_function('myfunc', function(keys, args) return redis.call('GET', keys[1]) end)"
FCALL myfunc 1 mykey
SCRIPT EXISTS sha1 [sha1 ...]

按 SHA-1 检查一个或多个脚本是否已缓存在服务器上,返回 1/0 数组。客户端据此决定走 EVALSHA 还是重新 LOAD。

例子
SCRIPT EXISTS a9d8b1c...  -- [1] 已缓存
SCRIPT FLUSH  -- 清空整个脚本缓存
事务 (5)
MULTI

开启事务块。之后的命令进队列(返回 QUEUED)而非立即执行,直到 EXEC 或 DISCARD。MULTI/EXEC 块原子执行。

例子
MULTI
INCR a
INCR b
EXEC
EXEC

原子执行 MULTI 后入队的所有命令,返回回复数组。被 WATCH 的 key 期间被改了,返回 nil 整个事务取消。

常见坑: Redis 事务不是 SQL 那种"错了回滚"。块里某条命令出错(比如类型不对),其它命令照样执行。EXEC 只是把每条结果返回。

例子
MULTI
SET a 1
SET b 2
EXEC  -- 返回 ["OK", "OK"]
DISCARD

丢弃排队的命令并退出 MULTI 模式,不执行。连接回到普通命令模式。

例子
MULTI
SET a 1
DISCARD  -- a 不变
WATCH key [key ...]

乐观锁原语。先 WATCH 几个 key,再 MULTI/EXEC,WATCH 到 EXEC 之间任何 WATCH 的 key 被改,事务取消。Redis 的 CAS 模式。

例子
WATCH balance
val = GET balance
if val >= 100:
  MULTI
  DECRBY balance 100
  EXEC
UNWATCH

清掉当前连接上 WATCH 的所有 key,但不执行事务。EXEC 和 DISCARD 本身会隐式 UNWATCH,只有放弃一次 CAS 尝试时才显式调它。

常见坑: 常见 CAS 泄漏:WATCH 了 key,读完决定不写,却忘了 UNWATCH,该连接下一次 MULTI/EXEC 就被这个过时的 watch 无谓地卡住。提前返回的分支务必 UNWATCH。

例子
WATCH balance
-- 读后决定不改
UNWATCH
WATCH a b c  -- 多 key 乐观锁
持久化与复制 (8)
SAVE

同步把数据集落盘为 RDB。阻塞服务器全程,10 GB 数据要几分钟。生产环境几乎从不该用。

常见坑: 非阻塞 RDB 用 BGSAVE。SAVE 只为灾难恢复脚本那种"明确需要服务器停顿一致点"的场景而存在。

例子
SAVE  -- 一般别用
BGSAVE  -- 推荐
BGSAVE

fork 出后台进程写 RDB 快照,不阻塞主线程。但 fork 本身在大实例上因 copy-on-write 页表成本可能也慢。

常见坑: 64 GB 实例 + 高写入下,fork 可能要几秒,子进程跑的时候常驻内存会翻倍。BGSAVE 放低峰期。

例子
BGSAVE
BGSAVE SCHEDULE  -- 7.0+ 排队避免冲突
LASTSAVE

返回最近一次 RDB 成功保存的 UNIX 时间戳。健康检查会拿它和 now() 比,发现后台保存卡住。

例子
LASTSAVE  -- 比如返回 1716700000
SLAVEOF host port

把当前实例配为指定 master 的副本,同步数据集并跟随主的复制流。已 deprecated,用 REPLICAOF。

常见坑: 5.0 起改名 REPLICAOF。两条都还能跑,新代码、新配置用 REPLICAOF。

例子
SLAVEOF master.internal 6379
SLAVEOF NO ONE  -- 解除从属变独立实例
REPLICAOF host port

SLAVEOF 的现代别名(5.0+)。REPLICAOF NO ONE 切断主从关系,提升为独立主。

例子
REPLICAOF master.internal 6379
REPLICAOF NO ONE  -- 提升为主
BGREWRITEAOF

在后台重写 AOF,压缩成能复现当前数据集的最小命令集。让 AOF 回放保持快、文件不至于无限膨胀。

常见坑: Redis 会按 auto-aof-rewrite-percentage 自动重写,但写入高峰可能跑赢它。盯 INFO persistence 里的 aof_pending_rewrite 和 aof_current_size,文件膨胀前手动触发。

例子
BGREWRITEAOF
INFO persistence  -- 看 aof_current_size / aof_base_size
WAIT numreplicas timeout

阻塞直到本连接发出的写被至少 numreplicas 个副本确认,或到 timeout 毫秒为止。在异步复制之上换取更强的持久性。

常见坑: WAIT 不是事务,副本没达标也不回滚,它只告诉你有多少个确认了。Redis 默认异步复制,WAIT 缩小丢数据窗口但消不掉它。

例子
WAIT 1 100  -- 至少 1 个副本确认,最多等 100ms
WAIT 2 1000  -- 多数派确认
FAILOVER [TO host port] [ABORT] [TIMEOUT ms]

从主到它某个副本触发协调式、低数据丢失的故障切换(6.2+)。和 Sentinel 驱动的切换不同,主会暂停写入并干净地交接。

例子
FAILOVER  -- 自动选副本
FAILOVER TO replica.internal 6379
FAILOVER ABORT  -- 中止进行中的切换
服务器与客户端 (11)
CLIENT LIST

列出所有已连接客户端的地址、连接时长、空闲时间、最近一条命令、标志。排查连接泄漏和"谁在打爆我们"必备。

例子
CLIENT LIST
CLIENT LIST TYPE pubsub  -- 仅 pub/sub 客户端
CLIENT KILL ADDR 1.2.3.4:5678  -- 踢掉某客户端
INFO [section]

以纯文本返回服务器统计:内存、复制、客户端、持久化、CPU、keyspace、命令统计。最有用的诊断命令。

例子
INFO  -- 全量
INFO memory
INFO replication
INFO commandstats  -- 各命令调用次数和耗时
CONFIG GET parameter

读一个或多个服务器配置项。支持 glob(CONFIG GET maxmemory*)。托管 Redis(如 ElastiCache)上只读。

例子
CONFIG GET maxmemory
CONFIG GET maxmemory-policy
CONFIG GET save
CONFIG SET parameter value

运行时改一个配置项,不重启。改动只在内存,配 CONFIG REWRITE 才会写回 redis.conf。

常见坑: 内存已满的实例上 CONFIG SET maxmemory-policy noeviction 会立刻开始拒绝写入。生产环境改之前确认新策略是你想要的。

例子
CONFIG SET maxmemory 4gb
CONFIG SET maxmemory-policy allkeys-lru
CONFIG REWRITE  -- 落盘
FLUSHALL [ASYNC|SYNC]

删除所有 database 里的所有 key。ASYNC(4.0+)后台回收内存。"最快毁掉一个生产周末"的命令。

常见坑: 生产环境在 redis.conf 里改名或禁掉:rename-command FLUSHALL ""。只清当前库用 FLUSHDB。没近期的 RDB/AOF 两条都不可逆。

例子
FLUSHALL ASYNC  -- 生产用 ASYNC
FLUSHDB  -- 仅当前库
DBSIZE

返回当前选中库的 key 数量。O(1),Redis 维护着这个计数,不像 KEYS 要遍历。"这个库多大"的安全问法。

例子
DBSIZE  -- 比如 1240392
SELECT 1
DBSIZE  -- 看 1 号库
MEMORY USAGE key [SAMPLES n]

估算一个 key 连同它的值占用的总字节,包含内部开销。揪出"吃掉大部分内存的少数几个 key"的正确工具。

常见坑: 对聚合类型它是抽样嵌套元素而非全量测量,分布不均的集合上调大 SAMPLES(或用 0 求精确)。配 MEMORY DOCTOR 看一句话健康摘要。

例子
MEMORY USAGE user:1001  -- 字节数
MEMORY USAGE big_zset SAMPLES 0  -- 精确测量
MEMORY DOCTOR
SLOWLOG GET [count]

返回最近执行耗时超过 slowlog-log-slower-than 微秒的命令。延迟突刺时第一个看的地方,它点出具体哪条慢命令和它的参数。

常见坑: Slowlog 只测命令本身的执行时间,不含请求在队列里排在慢命令后面的等待。一条快命令被记成"慢",通常是被前面的 KEYS 或大 Lua 脚本堵住了。

例子
SLOWLOG GET 10  -- 最近 10 条慢命令
SLOWLOG RESET  -- 清空
CONFIG SET slowlog-log-slower-than 10000  -- 阈值 10ms
CLIENT NO-EVICT on|off

让当前连接免于客户端输出缓冲驱逐(7.0+),这样关键的运维或监控客户端不会在内存压力下被踢。少用。

例子
CLIENT NO-EVICT on
CLIENT NO-TOUCH on  -- 读不更新 LRU/LFU(7.2+)
CLIENT SETNAME monitor-1
COMMAND DOCS [command ...]

返回命令的结构化文档:摘要、参数、复杂度、标志。COMMAND COUNT 给总数,COMMAND INFO 返回参数个数和 key 位置元数据,客户端用它做路由。

例子
COMMAND COUNT  -- 服务器支持的命令总数
COMMAND INFO get set
COMMAND DOCS hset
CLUSTER INFO

报告 Redis 集群健康:状态(ok / fail)、16384 个 hash slot 分配了多少、已知和可达节点数。集群异常时第一个看。

常见坑: cluster_state:fail 表示有 slot 没分配,集群拒绝触及这些 slot 的查询。CLUSTER SLOTS / CLUSTER SHARDS 给出 slot 到节点的映射,用来定位缺口。

例子
CLUSTER INFO
CLUSTER SLOTS
CLUSTER KEYSLOT user:1001  -- 这个 key 落哪个槽
常见坑 (12)
KEYS in production

生产环境 KEYS *(或任何 pattern)会同步遍历整个 keyspace,把 Redis 卡几秒。一律用 SCAN。

常见坑: 即使带 pattern 的 KEYS user:* 也会遍历所有 key 逐个匹配。成本和总 keyspace 成正比,不是和命中数。SCAN 增量执行,bucket 间会让出。

例子
KEYS *  -- 不要这样
SCAN 0 MATCH user:* COUNT 500  -- 正确做法
SCAN may miss or duplicate

SCAN 保证整轮遍历里"从头到尾都存在"的 key 至少返回一次,但扫描中新增/删除的 key 可能漏报或重复返回。客户端做去重。

例子
# 用 Set 在客户端去重
seen = set()
cursor = 0
while True:
  cursor, batch = r.scan(cursor)
  for k in batch: seen.add(k)
  if cursor == 0: break
HGETALL on big hash

10 万+ field 的 hash 上 HGETALL 一次返回几 MB,阻塞 Redis 事件循环和客户端。改 HSCAN,或把 hash 拆成 N 个小 hash。

例子
HSCAN big_hash 0 COUNT 500
-- 按 hash_tag 拆分: user:1001:profile, user:1001:prefs, user:1001:cache
Expired keys not freed immediately

TTL 到期 key 不是立刻释放,Redis 用惰性过期(下次访问时删)加概率性后台清理。内存中可能包含"已过期但还没释放"的 key。

常见坑: INFO memory used_memory 比所有 key 体积之和大是正常的。差距太大就调高 hz(CONFIG SET hz 100)让后台清理更激进,或接受一点延迟。

例子
DEBUG SLEEP 0  -- 触发一次访问帮过期
CONFIG SET hz 100  -- 默认 10,调到 100 更激进
Memory fragmentation

长跑的 Redis 实例 jemalloc 碎片会累积,used_memory_rss 能到 used_memory 的 1.5-2 倍。看 INFO memory 里的 mem_fragmentation_ratio,> 1.5 就该处理。

常见坑: 运行时打开主动碎片整理:CONFIG SET activedefrag yes,在不停服情况下处理。老办法,带持久化重启,也行,但会有一个 failover 窗口。

例子
INFO memory  -- 看 mem_fragmentation_ratio
CONFIG SET activedefrag yes
AOF vs RDB trade-offs

RDB 是某时刻快照,文件小、加载快,崩溃可能丢几分钟。AOF 记录每个写,文件大、回放慢,持久度可调(每写/每秒/OS 决定)。

常见坑: 生产默认:两个都开。RDB 用于快速恢复和异地备份,AOF(appendfsync everysec)保证崩溃最多丢 1 秒。AOF 要定期 BGREWRITEAOF 压缩。

例子
CONFIG SET appendonly yes
CONFIG SET appendfsync everysec
BGREWRITEAOF  -- 压缩 AOF
Cache stampede on hot key

一个热门缓存 key 过期的瞬间,所有并发请求同时 miss,一起冲击数据库重算同一个值,形成惊群。一次慢的后端查询变成成千上万次。

常见坑: 缓解:用短时的按 key 锁(SET lock NX EX),只让一个请求重算,其余读旧值或等待;或在过期前一点提前刷新(概率性提前过期)。给 TTL 加抖动,别让 key 集体同时过期。

例子
SET lock:recompute:home worker-7 NX EX 5  -- 只放一个进来重算
EXPIRE cache:home 60  -- 加随机 +rand(0,10) 防同时过期
Hot key / single slot bottleneck

在集群里,对某个超热 key 的每次操作都落到同一个分片,导致那个节点打满、其余空闲。全局计数器或明星用户就是典型热 key。

常见坑: 把热 key 拆成 N 个带后缀的子 key(counter:0..counter:9),读时求和;或在客户端本地加一层短 TTL 缓存。hash tag 决定同槽,别不小心把所有东西 tag 进同一个 slot。

例子
INCR counter:{shard:$((RANDOM%10))}  -- 写打散到 10 个子 key
CLUSTER KEYSLOT "{user}:1001"  -- 确认 hash tag 落槽
Big keys block the event loop

Redis 命令执行是单线程的,所以一个对巨型 key 的 O(N) 操作(百万字段 hash 上 HGETALL、大 set 上 DEL)会在整个过程中卡住所有别的客户端。

常见坑: 离线用 redis-cli --bigkeys 或 --memkeys 找大 key(它们是抽样,不阻塞)。用 UNLINK 删、用 *SCAN 系列读,设计 schema 时别让单个 key 无限增长。

例子
redis-cli --bigkeys  -- 扫描找大 key
redis-cli --memkeys  -- 按内存找
UNLINK the_big_key
maxmemory-policy eviction surprises

内存触到 maxmemory 时的行为完全取决于 maxmemory-policy。noeviction 用 OOM 错误拒绝写入;allkeys-lru 驱逐任意 key;volatile-lru 只驱逐设了 TTL 的 key。

常见坑: volatile-* 策略下若没有 key 带 TTL,行为等同 noeviction,写入开始失败却没 key 被驱逐。要靠 LRU 驱逐,要么给缓存 key 设 TTL,要么用 allkeys-* 策略。

例子
CONFIG GET maxmemory-policy
CONFIG SET maxmemory-policy allkeys-lru  -- 纯缓存场景
INFO stats  -- 看 evicted_keys 是否在涨
EXPIRE on replica does not delete

副本不会独立过期 key,它们等主在 key 过期时发来显式 DEL。在副本上读,可能短暂读到一个逻辑上已过期的 key。

常见坑: 从 Redis 3.2 起,副本读到逻辑已过期的 key 会返回 nil(即便 DEL 还没到),正确性没问题,但在主传来删除前,该 key 仍占副本内存。别假设副本内存和主完全一致。

例子
TTL session:abc  -- 主与副本上结果可能短暂不同
INFO keyspace  -- 对比主从 expires 计数
Numeric strings and float precision

Redis 把数字按字符串存,每条命令各自解析。计数器超过 2^63-1 会让 INCR 溢出;一连串 INCRBYFLOAT 会像任何浮点运算一样累积 IEEE-754 舍入误差。

常见坑: 算钱别对"元"用 INCRBYFLOAT,存"分"用 INCRBY。超大计数器要盯 int64 上限,或把计数器分片让单个 key 不溢出。

例子
INCRBY wallet:42:cents 99  -- 存分,整数
INCR big_counter  -- 接近 9.22e18 时会溢出报错

这个工具能做什么

可搜索的 Redis 速查表,覆盖后端、SRE、值班同学日常真在 redis-cli 里敲的 80+ 条命令,不是凑数的 "SET foo bar" 入门篇。十五大分类:键(GET / SET / DEL / EXISTS / EXPIRE / TTL / PERSIST / KEYS 与 SCAN / TYPE / RENAME), 字符串(INCR / DECR / APPEND / GETSET 和 SET ... GET / STRLEN / SETEX / SETNX 与 SET NX EX 对比),哈希 (HSET 多字段、HGET、HMGET、HDEL、HKEYS、HVALS、HGETALL 的危险、HINCRBY / HINCRBYFLOAT),列表当队列(LPUSH / RPUSH / LPOP / RPOP / LRANGE / LLEN / LINDEX / LREM / BLPOP 做阻塞消费),集合(SADD / SREM / SMEMBERS / SISMEMBER / SUNION / SINTER / SDIFF,附 SINTER 交集顺序 的小技巧),有序集合(ZADD 带 NX/XX/GT/LT,6.2+ 的 ZRANGE 万能瑞士军刀,ZRANGEBYSCORE 配时间戳实现定时任 务,ZINCRBY,ZRANK 带 WITHSCORE),位图做紧凑日活标记 (SETBIT / GETBIT / BITCOUNT / BITOP AND/OR/XOR/NOT), HyperLogLog 概率基数(PFADD / PFCOUNT / PFMERGE),发布 订阅 fire-and-forget(PUBLISH / SUBSCRIBE / PSUBSCRIBE) 以及什么时候该改用 Streams,Streams 5.0+ 持久可重放日志 (XADD 带 MAXLEN,XREAD 配 BLOCK $,XREADGROUP 实现至少 一次消费组,XACK,XLEN),Lua 脚本(EVAL、EVALSHA、 SCRIPT LOAD 配 NOSCRIPT 回退),事务(MULTI、EXEC、 DISCARD、WATCH 乐观锁,以及 Redis 事务不会回滚出错命 令的事实),持久化与复制(SAVE 与 BGSAVE、LASTSAVE 做健 康检查、SLAVEOF 已 deprecated 用 REPLICAOF、AOF 与 RDB 的取舍),服务器与客户端运维(CLIENT LIST 排查"谁在打爆 我们"、INFO 各 section、CONFIG GET/SET 运行时调参、 FLUSHALL ASYNC),以及真烧钱的坑(生产环境 KEYS、SCAN 的重复返回语义、大 hash 上 HGETALL、过期键不实时释放、 内存碎片与主动整理、AOF 与 RDB 取舍)。每条都附中英说 明、1-3 条可直接粘到 redis-cli 跑的真实例子、一行"常见 坑"。搜索框跨命令 / 说明 / 例子 / 坑四个字段一起搜,分 类胶囊缩范围。完全在浏览器里跑,不连任何 Redis,不上传, 不发任何网络请求。配合 PostgreSQL 速查表、SQL 速查搭配 Docker / kubectl / nginx 速查覆盖整条技术栈。

工具细节

输入
文本
页面会根据工具类型展示文本框、数值控件、文件选择或结构化输入。
输出
即时结果 + 复制
结果区优先给出可操作结果,支持项会显示复制、下载或可视化预览。
隐私
浏览器本地处理
主工具逻辑未发现外部 API 调用,输入通常留在当前标签页内处理。
保存 / 分享
免账号使用
打开页面即可使用;刷新后是否保留结果取决于具体工具。
性能预算
首屏 JS ≤ 28 KB
没有声明 WASM 依赖,适合快速打开和移动端使用。
适用场景
开发运维 · 程序员
分类和职业标签用于推荐相关工具、组织内链,并帮助用户快速判断是否适合当前任务。

怎么用

  1. 1. 输入

    把内容粘贴或拖入工具面板。

  2. 2. 处理

    点击按钮,在浏览器内本地处理,文件不上传。

  3. 3. 复制 / 下载

    一键复制结果或下载到本地。

Redis 速查表 适合怎么用

适合在上传、交付、归档、客服排查前使用,也适合任何文件离开本机前的本地复核。

适合文件任务

  • 分享前检查文件类型、大小、元数据和明显不匹配信号。
  • 上传、归档、接收或审核前整理混合文件夹。
  • 敏感文件先留在浏览器里处理,不用交给账号型服务。

文件检查项

  • 不要只凭扩展名判断真实文件类型。
  • 文件发给客户、供应商或公开页面前,先看元数据。
  • 复制、转换或导出结果确认前,保留原文件。

下一步可以接着做

这些入口会把当前任务接到更完整的工具链里。

  1. 1 Nginx 速查表 Nginx 速查表,常见配置、location/server 块、SSL、反代、gzip,真实例子和常见坑。 打开
  2. 2 PostgreSQL 速查表 PostgreSQL 速查表,80+ 命令和函数,psql、JSONB、CTE、窗口函数、索引、分区、高级扩展。 打开
  3. 3 SQL 速查表 SQL 速查表,100+ 条覆盖 SELECT、JOIN、窗口函数、索引,含 MySQL/PostgreSQL/SQLite 方言差异。 打开

真实使用场景

  • 写一把 SET NX EX 分布式锁并把释放写对

    你想加个 cron 守卫,让两台应用机不会把同一个夜间账单任 务跑两遍。搜「NX」和「EVAL」,复制 SET billing_lock $token NX EX 300,再抓那段先比对 token 再 DEL 的 Lua 释 放脚本。那行坑提醒你:裸 DEL 会在 300 秒 TTL 过期后误删 另一台机刚拿到的锁。

  • 截断悄悄涨到 8GB 的 Stream

    值班告警说某个 Redis 实例到了 90% maxmemory。你搜 「Streams」和「MAXLEN」,找到 XADD stream MAXLEN ~ 1000000 和 XTRIM stream MAXLEN ~ 1000000,明白近似(~) 写法比精确截断便宜得多。那行坑说清楚:不封顶的 Stream 会无限增长,刚好就是吃掉 8GB 的元凶。

  • 替掉那条卡了生产 4 秒的 KEYS 扫描

    同事在请求处理里写了 KEYS user:*,1000 万 key 的实例把所 有连接的客户端都卡住了。你筛「键」,读懂 KEYS 是 O(N) 且 阻塞单线程,复制 SCAN 0 MATCH user:* COUNT 1000 的游标循 环,外加那句提醒:SCAN 跨轮次可能返回同一个 key 两次,要 在客户端去重。

  • 选 volatile-lru 让锁键不被淘汰

    你的缓存实例同时放着 session 和锁键,凌晨 3 点 allkeys-lru 把一个在途任务的锁淘汰掉了。你搜「淘汰」,只给缓存键设 TTL,切到 maxmemory-policy volatile-lru,再用 CONFIG GET maxmemory-policy 确认。那个坑胶囊把你踩的 allkeys-lru 雷点 写得明明白白。

常见踩坑

  • 用裸 SET key value 刷新值却把 TTL 抹掉,改用 SET key value KEEPTTL 或重新写上 EX,过期才不会丢。

  • 给锁用 SETNX 加单独 EXPIRE,两条命令间客户端崩了锁就永不过期,改用原子的 SET key token NX EX ttl。

  • 在涨到百万 field 的 hash 上调 HGETALL,一次返回几 MB 还阻塞,改用带 COUNT 的 HSCAN 或只 HMGET 你要的字段。

隐私说明

这份速查就是一个静态页。你输入的搜索词只在浏览器里跟内存中的 命令数组做匹配,不连任何 Redis 服务器,不进 URL,也不上传。 边输入边看 DevTools 的 Network 面板,零请求。堡垒机后面和气隙 网络里都能放心用。

常见问题

类似工具组合

做你这行的人, 还会一起用这些。

Made by Toolora · 100% client-side · Updated 2026-06-13