16人参与 • 2026-01-26 • Redis
这类命令不针对特定数据类型,适用于所有场景,主要用于管理键、查看状态等。
| 命令 | 作用 | 示例 |
|---|---|---|
keys pattern | 查找符合匹配模式的所有键(生产环境慎用,会阻塞 redis) | keys user* → 查找所有以user开头的键 |
exists key | 判断键是否存在,返回 1(存在)/0(不存在) | exists user:100 → 检查键user:100是否存在 |
del key [key ...] | 删除指定键(可批量),返回删除成功的键数量 | del user:100 cart:100 → 删除user:100和cart:100 |
expire key seconds | 为键设置过期时间(单位:秒) | expire code:1234 60 → 键code:123460 秒后过期 |
ttl key | 查看键的剩余过期时间(-1 = 永不过期,-2 = 已过期 / 不存在) | ttl code:1234 → 返回剩余秒数 |
persist key | 移除键的过期时间,使其永久有效 | persist code:1234 → 取消code:1234的过期时间 |
type key | 查看键对应值的数据类型 | type user:100 → 返回hash/string/list等 |
flushdb | 清空当前数据库的所有键(慎用) | flushdb → 清空当前库 |
flushall | 清空所有数据库的所有键(生产环境严禁使用) | flushall → 清空全部库 |
redis 支持多种数据类型,下面是字符串(string)、哈希(hash)、列表(list)、集合(set)、有序集合(zset)这 5 种核心类型的常用命令。
适用于存储简单值(如数字、文本),是 redis 最常用的类型。
# 设置键值(覆盖原有值) set name "张三" # 设置键值并指定过期时间(30秒) setex code 30 "8866" # 获取值 get name # 数值自增(+1,仅适用于数字值) incr num # 数值自增指定步长(+5) incrby num 5 # 数值自减(-1) decr num # 追加字符串到原有值末尾 append name " - 程序员"
一个 hash 键可以存储多个字段(field)和值(value),类似 java 的 map。
# 设置hash的单个字段 hset user:100 name "李四" age 25 # 设置hash的多个字段 hmset user:100 name "李四" age 25 gender "男" # 获取hash的单个字段值 hget user:100 name # 获取hash的多个字段值 hmget user:100 name age # 获取hash的所有字段和值 hgetall user:100 # 获取hash的所有字段名 hkeys user:100 # 获取hash的所有值 hvals user:100 # 判断hash的字段是否存在 hexists user:100 age # 删除hash的指定字段 hdel user:100 gender # 获取hash的字段数量 hlen user:100
底层是双向链表,支持从头部 / 尾部操作元素。
# 从列表尾部添加元素 rpush list:msg "消息1" "消息2" # 从列表头部添加元素 lpush list:msg "消息0" # 从列表尾部移除并返回元素 rpop list:msg # 从列表头部移除并返回元素 lpop list:msg # 获取列表指定范围的元素(0=-1表示所有) lrange list:msg 0 -1 # 获取列表长度 llen list:msg # 根据索引获取元素 lindex list:msg 1 # 根据索引修改元素 lset list:msg 1 "修改后的消息2"
支持集合间的交、并、差运算。
# 向集合添加元素 sadd set:tags "java" "redis" "mysql" # 获取集合所有元素 smembers set:tags # 判断元素是否在集合中 sismember set:tags "redis" # 删除集合指定元素 srem set:tags "mysql" # 获取集合元素数量 scard set:tags # 求两个集合的交集(共同元素) sinter set:tags1 set:tags2 # 求两个集合的并集(所有元素,去重) sunion set:tags1 set:tags2 # 求两个集合的差集(在set1中但不在set2中的元素) sdiff set:tags1 set:tags2
每个元素关联一个分数(score),redis 根据分数排序。
# 向有序集合添加元素(score为分数) zadd zset:rank 95 "张三" 90 "李四" 98 "王五" # 获取有序集合所有元素(带分数,默认升序) zrange zset:rank 0 -1 withscores # 获取有序集合所有元素(降序) zrevrange zset:rank 0 -1 withscores # 获取指定元素的分数 zscore zset:rank "张三" # 增加指定元素的分数(+3) zincrby zset:rank 3 "张三" # 获取元素的排名(升序,从0开始) zrank zset:rank "李四" # 获取元素的排名(降序) zrevrank zset:rank "李四" # 删除指定元素 zrem zset:rank "李四" # 获取集合元素数量 zcard zset:rank
这类命令补充了基础通用命令的不足,尤其适合生产环境的键遍历、性能监控、连接管理。
| 命令 | 作用 | 示例 / 说明 |
|---|---|---|
scan cursor [match pattern] [count count] | 非阻塞式遍历键(替代keys,生产环境首选),分批返回键,避免阻塞 redis | scan 0 match user:* count 100 → 从游标 0 开始,匹配user:*,每次返回 100 个键 |
info [section] | 查看 redis 运行状态信息(如内存、连接、持久化),排查性能问题 | info memory → 查看内存使用;info stats → 查看统计指标 |
client list | 列出所有连接到 redis 的客户端信息(ip、状态、耗时) | 排查长连接 / 慢连接问题,定位异常客户端 |
client kill ip:port | 关闭指定 ip + 端口的客户端连接 | client kill 192.168.1.100:54321 → 断开该客户端连接 |
dbsize | 统计当前数据库的键总数 | 快速了解当前库数据量,比keys *高效 |
renamenx oldkey newkey | 重命名键(仅当 newkey 不存在时才成功,避免覆盖) | renamenx user:old user:new → 安全重命名 |
move key db | 将键移动到指定数据库(redis 默认 16 个库,编号 0-15) | move user:100 1 → 把user:100移到 1 号库 |
redis 事务保证命令的原子性执行,而setnx/getset/redlock是实现分布式锁的核心命令。
(1) 事务命令
redis 事务通过multi(开启)、exec(执行)、discard(取消)实现,命令入队后批量执行:
# 开启事务 multi # 入队命令(此时不执行,仅记录) set order:100 status "paid" hset user:100 order_count 1 # 执行事务(所有入队命令原子执行) exec # 取消事务(放弃所有入队命令) multi set a 1 discard # 事务取消,set a 1不会执行
(2) 分布式锁核心命令(解决多服务并发竞争)
# 1. setnx:设置键(仅当键不存在时成功,返回1=加锁成功,0=已被占用) # 缺点:若加锁客户端宕机,锁无法释放,需配合过期时间 setnx lock:order 1 expire lock:order 30 # 给锁设置30秒过期,避免死锁 # 2. set(推荐):原子性设置值+过期时间(解决setnx+expire非原子问题) set lock:order 1 nx ex 30 # nx=仅当键不存在时设置;ex=过期时间(秒);px=过期时间(毫秒) # 3. getset:获取旧值并设置新值(解锁/锁续期用) # 解锁逻辑示例:先判断值是否是自己的锁,再删除(伪代码) if get lock:order == "my_lock_value" del lock:order # 4. del:释放锁(需配合业务逻辑,避免误删其他客户端的锁) del lock:order
适用于实时通知(如订单状态变更、消息推送),redis 作为轻量级消息中间件使用。
# 订阅频道(客户端1) subscribe channel:order_notify # 订阅order_notify频道 psubscribe channel:* # 订阅所有以channel:开头的频道(通配符) # 发布消息(客户端2) publish channel:order_notify "订单100已支付" # 向频道发布消息,订阅端实时接收 # 取消订阅 unsubscribe channel:order_notify # 取消指定频道订阅 punsubscribe channel:* # 取消通配符订阅
redis 持久化分 rdb(快照)和 aof(日志),以下命令用于手动触发持久化、查看配置:
# 手动触发rdb快照(阻塞redis,生产环境建议低峰期执行) bgsave # 后台异步保存(推荐);save # 同步保存(阻塞,慎用) # 查看持久化配置 config get save # 查看rdb自动保存触发条件(如"900 1"=900秒内至少1个键修改则保存) config get appendonly # 查看aof是否开启(yes/no) # 手动触发aof重写(压缩aof日志,减少文件体积) bgrewriteaof # 后台异步重写(推荐)
补充基础过期命令的细节,适配不同时间精度需求:
# pexpire:设置过期时间(单位:毫秒,适配高精度场景) pexpire code:1234 60000 # 60秒(60000毫秒)后过期 # expireat:指定过期时间戳(秒) expireat user:100 1735689600 # 键在2025-01-01 00:00:00过期 # pexpireat:指定过期时间戳(毫秒) pexpireat user:100 1735689600000 # ttl/pttl:查看剩余过期时间(pttl返回毫秒) pttl code:1234 # 返回剩余毫秒数
批量操作能减少网络 io 次数(redis 是单线程,网络往返是性能瓶颈),大幅提升效率,是高并发场景的必备命令。
(1) string 类型批量操作
# 批量设置多个键值对(原子操作) mset name "张三" age 25 email "zhangsan@test.com" # 批量获取多个键的值(返回顺序与参数一致) mget name age email # 返回 ["张三", "25", "zhangsan@test.com"] # 批量设置键值+过期时间(redis 7.0+支持,替代setex批量场景) msetex key1 60 "val1" key2 120 "val2"
(2) hash 类型批量操作(补充)
# 批量设置hash字段(已提过,补充批量获取优化) hmset user:101 name "王五" phone "13800138000" address "北京" # 批量获取hash字段(指定多个field,减少网络请求) hmget user:101 name phone # 返回 ["王五", "13800138000"]
(3) 通用批量删除(补充)
# 结合scan+del实现批量删除(生产环境替代keys+del)
# 示例:删除所有以temp:开头的键(伪代码)
cursor=0
while true; do
# 分批获取键
result=$(redis-cli scan $cursor match temp:* count 100)
# 解析游标和键列表
cursor=$(echo $result | awk 'nr==1{print $1}')
keys=$(echo $result | awk 'nr==2{print $0}')
# 批量删除
if [ -n "$keys" ]; then
redis-cli del $keys
fi
# 游标为0时结束
if [ $cursor -eq 0 ]; then
break
fi
done适用于需要 “原子性批量执行多个命令” 的场景,比普通批量命令更灵活。
(1) 管道(pipeline)命令
管道允许客户端一次性发送多个命令,redis 批量执行后返回结果,减少网络往返次数:
# 终端执行管道命令示例(echo + redis-cli --pipe) echo -e "set a 1\nincr a\nget a" | redis-cli --pipe # 输出:所有命令执行结果,最终get a返回2
(2) lua 脚本命令(原子性执行复杂逻辑)
lua 脚本在 redis 中原子执行,避免多命令竞态问题(如分布式锁续期、库存扣减):
# eval:执行lua脚本(核心命令)
# 格式:eval 脚本 键参数个数 键1 键2 ... 参数1 参数2 ...
# 示例:原子性实现“先判断值再修改”(库存扣减,库存>=1才扣减)
eval "local stock = tonumber(redis.call('get', keys[1]))
if stock and stock >= 1 then
redis.call('decr', keys[1])
return 1 # 扣减成功
else
return 0 # 库存不足
end" 1 stock:1001
# script load:预加载lua脚本(避免重复传输脚本内容)
script load "return redis.call('get', keys[1])" # 返回脚本sha1值
# evalsha:执行预加载的脚本(更高效)
evalsha 5332031c6b470dc5a0dd9b4bf2030dea6d65de91 1 stock:1001
# script exists:检查脚本是否已加载
script exists 5332031c6b470dc5a0dd9b4bf2030dea6d65de91
# script flush:清空所有预加载的lua脚本
script flush适用于地图相关业务(如附近的人、门店、外卖配送),redis 支持经纬度存储和距离计算:
# geoadd:添加地理位置(经度,纬度,位置名称) geoadd shop:nearby 116.403874 39.914885 "门店a" 116.410049 39.914575 "门店b" # geopos:获取指定位置的经纬度 geopos shop:nearby "门店a" # 返回 [116.403874, 39.914885] # geodist:计算两个位置的距离(单位:m/km/mi/ft) geodist shop:nearby "门店a" "门店b" km # 返回距离(如0.58km) # georadius:根据经纬度范围查找位置(附近的门店) # 示例:查找经度116.405、纬度39.915,半径1km内的所有门店 georadius shop:nearby 116.405 39.915 1 km withdist withcoord # georadiusbymember:根据已有位置查找附近位置 # 示例:查找门店a周围1km内的所有门店 georadiusbymember shop:nearby "门店a" 1 km withdist
适用于海量布尔值场景(如用户签到、是否在线、权限开关),1 个键可存储 2^32 个布尔值,内存占用极低:
# setbit:设置指定偏移量的位值(0/1) # 示例:用户1001在第5天签到(偏移量5,值1) setbit sign:1001 5 1 # getbit:获取指定偏移量的位值 getbit sign:1001 5 # 返回1(已签到),0(未签到) # bitcount:统计指定范围内值为1的位数量 # 示例:统计用户1001当月(30天)的签到次数 bitcount sign:1001 0 29 # 返回签到天数 # bitop:位图运算(and/or/xor/not) # 示例:统计同时签到的用户(用户1001和1002的签到交集) bitop and sign:common sign:1001 sign:1002 bitcount sign:common # 返回共同签到天数
适用于 “统计不重复元素个数” 场景(如 uv 统计、独立访客数),占用内存固定(约 12kb),支持海量数据:
# pfadd:添加元素到hyperloglog集合 pfadd uv:20260121 "user1001" "user1002" "user1003" # pfcount:统计集合的基数(不重复元素个数) pfcount uv:20260121 # 返回3 # pfmerge:合并多个hyperloglog集合 # 示例:合并1月21日和1月22日的uv数据 pfmerge uv:202601 uv:20260121 uv:20260122 pfcount uv:202601 # 返回两天的总独立访客数
# auth:认证密码(redis设置密码后,连接时需认证) auth yourpassword # 认证成功返回ok,失败返回错误 # select:切换数据库(redis默认16个库,0-15) select 1 # 切换到1号库 # ping:测试redis连接是否正常 ping # 返回pong表示连接正常 # quit:关闭客户端连接 quit # config set/get:动态修改/查看配置(无需重启redis) # 示例:修改最大内存为10gb config set maxmemory 10gb # 示例:查看aof开关状态 config get appendonly
1.通用命令:重点掌握exists(判断键存在)、del(删除键)、expire(设置过期)、type(查看类型),是所有操作的基础。
2.核心类型命令:
set/get(基础读写)、incr/incrby(数值自增);hset/hget/hgetall(对象读写);lpush/rpush/lpop/rpop(队列操作);sadd/smembers/sinter(去重 / 集合运算);zadd/zrange/zrevrange(排名场景)。3.生产环境中避免使用keys命令(会阻塞 redis),如需遍历键,优先使用scan命令(分批遍历,非阻塞)。
4.进阶通用命令:优先用scan替代keys,info排查性能问题,client list定位连接异常;
5.分布式锁:核心用set key value nx ex seconds(原子加锁 + 过期),避免setnx+expire非原子问题;
6.业务场景命令:发布订阅(publish/subscribe)适用于异步通知,事务(multi/exec)保证命令原子执行,bgsave/bgrewriteaof用于持久化备份;
7.过期时间:毫秒级需求用pexpire/pexpireat,时间戳过期用expireat,精准控制键的有效期。
8.批量 / 高性能命令:mset/mget(批量读写)、pipeline(减少网络 io)、lua 脚本(原子执行复杂逻辑)是提升 redis 性能的核心,高并发场景必用;
9.场景化命令:
10.运维调试命令:auth/select/ping(连接认证)、config set/get(动态配置)、scan+del(安全批量删除)是开发 / 运维排查问题的常用命令;
11.选择原则:根据业务场景匹配命令 —— 性能优先选批量 / 管道,地理场景选 geo,布尔统计选 bitmaps,去重统计选 hyperloglog。
到此这篇关于redis 常用命令之基础、进阶与场景化实战案例的文章就介绍到这了,更多相关redis 常用命令内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论