掌握 Redis:核心命令使用教程(详尽版)
引言
Redis (Remote Dictionary Server) 是一个开源的、高性能的、基于内存的键值存储系统。它以其惊人的速度、丰富的数据结构支持以及灵活性,在现代 Web 应用架构中扮演着至关重要的角色。从简单的缓存层到复杂的消息队列、实时排行榜、会话管理,甚至是轻量级的主数据库,Redis 的应用场景极其广泛。
要充分发挥 Redis 的威力,深入理解并熟练运用其核心命令是必不可少的。本教程旨在提供一个全面而详细的指南,涵盖 Redis 最常用的数据类型及其核心操作命令,帮助开发者从入门到精通,真正掌握 Redis 的使用。
一、 准备工作:连接与基础
在开始探索命令之前,你需要确保已经安装了 Redis 服务,并且可以通过客户端进行连接。
- 安装 Redis: 根据你的操作系统(Linux, macOS, Windows via WSL/Docker),可以通过包管理器(apt, yum, brew)或从 Redis 官网下载源码编译安装。
- 启动 Redis 服务: 通常使用
redis-server
命令启动。 - 连接 Redis: 使用 Redis 自带的命令行客户端
redis-cli
。
bash
redis-cli
如果 Redis 服务运行在不同的主机或端口,或者设置了密码,可以使用以下参数:
bash
redis-cli -h <hostname> -p <port> -a <password> - 基本测试: 连接成功后,可以尝试
PING
命令,如果服务器正常,会返回PONG
。
127.0.0.1:6379> PING
PONG
二、 Redis 核心数据类型与命令详解
Redis 之所以强大,很大程度上归功于其支持的多种数据结构。了解每种数据结构的特点和适用场景,并掌握对应的操作命令是关键。
(一) String(字符串)类型
这是 Redis 最基本的数据类型,可以存储任何形式的字符串,包括文本、序列化的 JSON、甚至是二进制数据(最大 512MB)。
- 特点: 简单、高效,支持原子性的计数操作。
-
应用场景: 缓存(页面片段、API 响应)、计数器(网站访问量、点赞数)、分布式锁、存储 Session 信息。
-
核心命令:
SET key value [EX seconds|PX milliseconds] [NX|XX]
- 设置指定
key
的值为value
。 EX seconds
: 设置键的过期时间(秒)。PX milliseconds
: 设置键的过期时间(毫秒)。NX
: 只在键不存在时,才对键进行设置操作。常用于实现分布式锁。XX
: 只在键已经存在时,才对键进行设置操作。
127.0.0.1:6379> SET user:1:name "Alice"
OK
127.0.0.1:6379> SET cache:page:home "<HTML>..." EX 3600
OK
127.0.0.1:6379> SET lock:resource resource_id NX EX 10
OK # 如果锁不存在,设置成功
(nil) # 如果锁已存在,设置失败
- 设置指定
GET key
- 获取指定
key
的值。如果键不存在,返回(nil)
。
127.0.0.1:6379> GET user:1:name
"Alice"
127.0.0.1:6379> GET non_existent_key
(nil)
- 获取指定
SETEX key seconds value
- 原子性地设置
key
的值为value
并指定过期时间(秒)。等价于SET key value EX seconds
。
127.0.0.1:6379> SETEX session:xyz789 1800 "user_id=123&role=admin"
OK
- 原子性地设置
SETNX key value
- 只在
key
不存在时设置key
的值。等价于SET key value NX
。返回1
表示设置成功,0
表示key
已存在,设置失败。
- 只在
MSET key value [key value ...]
- 同时设置一个或多个
key-value
对。这是一个原子性操作。
127.0.0.1:6379> MSET user:1:email "[email protected]" user:2:name "Bob"
OK
- 同时设置一个或多个
MGET key [key ...]
- 获取一个或多个指定
key
的值。返回一个列表,包含对应key
的值,如果某个key
不存在,则对应位置为(nil)
。
127.0.0.1:6379> MGET user:1:name user:2:name user:3:name
1) "Alice"
2) "Bob"
3) (nil)
- 获取一个或多个指定
INCR key
- 将
key
中存储的数字值增一。如果key
不存在,那么key
的值会先被初始化为0
,然后再执行INCR
操作。如果值不是整数类型,会返回错误。这是一个原子操作。
127.0.0.1:6379> SET page_views 100
OK
127.0.0.1:6379> INCR page_views
(integer) 101
127.0.0.1:6379> GET page_views
"101"
127.0.0.1:6379> INCR counter # key 不存在
(integer) 1
- 将
DECR key
- 将
key
中存储的数字值减一。原子操作。规则同INCR
。
127.0.0.1:6379> DECR page_views
(integer) 100
- 将
INCRBY key increment
- 将
key
所存储的值加上指定的增量increment
。原子操作。
127.0.0.1:6379> INCRBY page_views 50
(integer) 150
- 将
DECRBY key decrement
- 将
key
所存储的值减去指定的减量decrement
。原子操作。
127.0.0.1:6379> DECRBY page_views 20
(integer) 130
- 将
APPEND key value
- 如果
key
已经存在并且是一个字符串,APPEND
命令将指定的value
追加到该key
原来值(value)的末尾。如果key
不存在,APPEND
就简单地将给定key
设为value
,就像执行SET key value
一样。返回追加后字符串的总长度。
127.0.0.1:6379> SET mykey "Hello"
OK
127.0.0.1:6379> APPEND mykey " World"
(integer) 11
127.0.0.1:6379> GET mykey
"Hello World"
- 如果
STRLEN key
- 返回
key
所储存的字符串值的长度。
127.0.0.1:6379> STRLEN mykey
(integer) 11
- 返回
(二) List(列表)类型
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。底层实际是双向链表(或在元素较少且长度较小时使用优化的 ziplist),所以在列表两端插入或删除元素非常快(O(1)),即使列表包含数百万个元素。
- 特点: 有序、可重复、两端操作高效。
-
应用场景: 消息队列(利用
LPUSH
+BRPOP
)、任务队列、最新动态(如微博 Timeline)、栈、队列。 -
核心命令:
LPUSH key element [element ...]
- 将一个或多个值
element
插入到列表key
的头部(左侧)。如果key
不存在,会创建一个空列表并执行LPUSH
操作。返回执行LPUSH
命令后,列表的长度。
127.0.0.1:6379> LPUSH tasks "task3" "task2" "task1"
(integer) 3 # 列表现在是 ["task1", "task2", "task3"]
- 将一个或多个值
RPUSH key element [element ...]
- 将一个或多个值
element
插入到列表key
的尾部(右侧)。返回执行RPUSH
命令后,列表的长度。
127.0.0.1:6379> RPUSH tasks "task4" "task5"
(integer) 5 # 列表现在是 ["task1", "task2", "task3", "task4", "task5"]
- 将一个或多个值
LPOP key [count]
- 移除并获取列表
key
的第一个元素(头部)。如果key
不存在或列表为空,返回(nil)
。可选的count
参数(Redis 6.2+)可以一次性弹出多个元素。
“`
127.0.0.1:6379> LPOP tasks
“task1”
列表现在是 [“task2”, “task3”, “task4”, “task5”]
“`
- 移除并获取列表
RPOP key [count]
- 移除并获取列表
key
的最后一个元素(尾部)。规则同LPOP
。
“`
127.0.0.1:6379> RPOP tasks
“task5”
列表现在是 [“task2”, “task3”, “task4”]
“`
- 移除并获取列表
LLEN key
- 返回列表
key
的长度。
127.0.0.1:6379> LLEN tasks
(integer) 3
- 返回列表
LRANGE key start stop
- 返回列表
key
中指定区间内的元素。start
和stop
都是基于 0 的下标。0
表示列表的第一个元素,1
表示第二个,以此类推。也可以使用负数下标,-1
表示列表的最后一个元素,-2
表示倒数第二个,以此类推。LRANGE key 0 -1
可以获取列表中的所有元素。
127.0.0.1:6379> LRANGE tasks 0 -1
1) "task2"
2) "task3"
3) "task4"
127.0.0.1:6379> LRANGE tasks 0 1
1) "task2"
2) "task3"
- 返回列表
LINDEX key index
- 返回列表
key
中,下标为index
的元素。下标规则同LRANGE
。如果index
超出范围,返回(nil)
。
127.0.0.1:6379> LINDEX tasks 1
"task3"
127.0.0.1:6379> LINDEX tasks -1
"task4"
- 返回列表
LINSERT key BEFORE|AFTER pivot element
- 将值
element
插入到列表key
当中,位于值pivot
之前或之后。如果pivot
不存在,不执行任何操作。如果key
不存在,视为一个空列表,不执行操作。
127.0.0.1:6379> LINSERT tasks BEFORE "task3" "task2.5"
(integer) 4 # 列表现在是 ["task2", "task2.5", "task3", "task4"]
- 将值
LTRIM key start stop
- 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。下标规则同
LRANGE
。常用于保持列表只存储最新的 N 个元素。
“`
127.0.0.1:6379> RPUSH logs “log entry 1” “log entry 2” … “log entry 100”
保留最新的 50 条日志
127.0.0.1:6379> LTRIM logs -50 -1
OK
“`- 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。下标规则同
-
BLPOP key [key ...] timeout
- 阻塞式列表弹出原语。它是
LPOP
的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被BLPOP
命令阻塞,直到等待timeout
超时或发现可弹出元素为止。timeout
为 0 表示无限期阻塞。可以同时监听多个key
,按key
出现的顺序检查,返回第一个非空列表的头部元素。常用于实现可靠的消息队列消费者。
“`
消费者进程执行
127.0.0.1:6379> BLPOP new_tasks 0
(此时会阻塞,等待 new_tasks 列表有元素)
另一个客户端(生产者)执行
127.0.0.1:6379> LPUSH new_tasks “urgent job”
(integer) 1消费者进程会立即解除阻塞并返回
1) “new_tasks” # 弹出元素的 key
2) “urgent job” # 弹出的元素
``
BRPOP key [key …] timeout
**
RPOP的阻塞版本,从列表尾部弹出。规则同
BLPOP`。 - 阻塞式列表弹出原语。它是
(三) Set(集合)类型
Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这意味着集合中不能出现重复的数据。Redis 中集合是通过哈希表实现的,所以添加、删除、查找的复杂度都是 O(1)。
- 特点: 无序、唯一、高效的成员检查和集合运算(交集、并集、差集)。
-
应用场景: 标签系统(给用户、文章打标签)、共同好友/关注、抽奖系统(保证唯一性)、IP 地址黑名单/白名单。
-
核心命令:
SADD key member [member ...]
- 将一个或多个
member
元素加入到集合key
当中,已经存在于集合的member
元素将被忽略。返回被成功添加的新成员的数量,不包括被忽略的成员。
127.0.0.1:6379> SADD tags:article:1 "redis" "database" "nosql"
(integer) 3
127.0.0.1:6379> SADD tags:article:1 "redis" "performance"
(integer) 1 # "redis" 已存在,只有 "performance" 被添加
- 将一个或多个
SMEMBERS key
- 返回集合
key
中的所有成员。注意:对于非常大的集合,此命令可能会阻塞服务器,生产环境慎用,考虑SSCAN
。
“`
127.0.0.1:6379> SMEMBERS tags:article:1
1) “nosql”
2) “performance”
3) “redis”
4) “database”
(注意:顺序是不保证的)
“`
- 返回集合
SISMEMBER key member
- 判断
member
元素是否是集合key
的成员。是返回1
,不是或key
不存在返回0
。
127.0.0.1:6379> SISMEMBER tags:article:1 "redis"
(integer) 1
127.0.0.1:6379> SISMEMBER tags:article:1 "java"
(integer) 0
- 判断
SCARD key
- 返回集合
key
的基数(集合中元素的数量)。
127.0.0.1:6379> SCARD tags:article:1
(integer) 4
- 返回集合
SREM key member [member ...]
- 移除集合
key
中的一个或多个member
元素,不存在的member
元素会被忽略。返回被成功移除的元素的数量。
127.0.0.1:6379> SREM tags:article:1 "nosql" "nonexistent"
(integer) 1 # 只有 "nosql" 被移除
- 移除集合
SPOP key [count]
- 随机移除并返回集合
key
中的一个或多个元素。count
参数用于指定移除数量。
127.0.0.1:6379> SPOP tags:article:1
"database" # 随机返回一个成员并移除
127.0.0.1:6379> SPOP tags:article:1 2
1) "redis"
2) "performance" # 随机返回两个成员并移除
- 随机移除并返回集合
SRANDMEMBER key [count]
- 随机返回集合
key
中一个或多个元素,但不移除它们。如果count
是正数,返回的元素不重复;如果count
是负数,可能返回重复的元素。
127.0.0.1:6379> SADD myset a b c d e
(integer) 5
127.0.0.1:6379> SRANDMEMBER myset 2
1) "c"
2) "a" # 随机返回两个,不移除
127.0.0.1:6379> SRANDMEMBER myset -5 # 可能重复
1) "e"
2) "a"
3) "c"
4) "a"
5) "d"
- 随机返回集合
- 集合运算命令:
SUNION key [key ...]
- 返回给定所有集合的并集。
127.0.0.1:6379> SADD groupA "user1" "user2" "user3"
(integer) 3
127.0.0.1:6379> SADD groupB "user2" "user3" "user4"
(integer) 3
127.0.0.1:6379> SUNION groupA groupB
1) "user1"
2) "user2"
3) "user3"
4) "user4"
- 返回给定所有集合的并集。
SINTER key [key ...]
- 返回给定所有集合的交集。
127.0.0.1:6379> SINTER groupA groupB
1) "user2"
2) "user3"
- 返回给定所有集合的交集。
SDIFF key [key ...]
- 返回第一个集合与其他集合的差集(在第一个集合中但不在其他集合中的元素)。
127.0.0.1:6379> SDIFF groupA groupB
1) "user1"
127.0.0.1:6379> SDIFF groupB groupA
1) "user4"
- 返回第一个集合与其他集合的差集(在第一个集合中但不在其他集合中的元素)。
SUNIONSTORE destination key [key ...]
SINTERSTORE destination key [key ...]
SDIFFSTORE destination key [key ...]
- 这些命令与上面的运算命令类似,但它们不是直接返回结果,而是将结果存储在
destination
集合中。如果destination
集合已存在,会被覆盖。
- 这些命令与上面的运算命令类似,但它们不是直接返回结果,而是将结果存储在
(四) Sorted Set(有序集合 / ZSet)类型
Redis 有序集合和集合一样,也是 String 类型元素的集合,且不允许重复的成员。不同的是,每个元素都会关联一个 double 类型的分数(score)。Redis 正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。
- 特点: 有序(根据 score)、唯一成员、高效的按 score 或成员查找、范围查询。
-
应用场景: 排行榜(游戏积分榜、热门商品榜)、带权重的任务队列、范围查找(如查找指定分数区间的用户)。
-
核心命令:
ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
- 将一个或多个
member
元素及其score
值加入到有序集合key
中。如果某个member
已经是有序集的成员,那么更新这个member
的score
值。 NX
: 只添加新成员,不更新已存在的成员。XX
: 只更新已存在的成员,不添加新成员。CH
: 返回本次操作改变的元素数量(新增和更新的)。默认只返回新增数量。INCR
: 当指定此选项时,ZADD
的行为类似ZINCRBY
,对指定member
的score
值进行增加,如果member
不存在则添加。
127.0.0.1:6379> ZADD leaderboard 100 "player1" 95 "player2" 110 "player3"
(integer) 3
127.0.0.1:6379> ZADD leaderboard 105 "player1" # 更新 player1 的分数
(integer) 0 # 默认返回新增数量
127.0.0.1:6379> ZADD leaderboard CH 108 "player1" 80 "player4"
(integer) 2 # CH 返回了更新和新增的总数
- 将一个或多个
ZRANGE key start stop [WITHSCORES]
- 返回有序集合
key
中,指定排名区间内的成员。成员按score
值递增(从小到大)排序。start
和stop
都是基于 0 的下标。WITHSCORES
选项让成员和它的score
值一并返回。
“`
假设 leaderboard 现在是: player2(95), player1(108), player3(110), player4(80) -> 排序后: player4(80), player2(95), player1(108), player3(110)
127.0.0.1:6379> ZRANGE leaderboard 0 -1 # 获取所有成员,按分数升序
1) “player4”
2) “player2”
3) “player1”
4) “player3”
127.0.0.1:6379> ZRANGE leaderboard 0 1 WITHSCORES # 获取排名前2的成员及分数
1) “player4”
2) “80”
3) “player2”
4) “95”
“`- 返回有序集合
ZREVRANGE key start stop [WITHSCORES]
- 返回有序集合
key
中,指定排名区间内的成员。成员按score
值递减(从大到小)排序。
127.0.0.1:6379> ZREVRANGE leaderboard 0 1 WITHSCORES # 获取分数最高的2名
1) "player3"
2) "110"
3) "player1"
4) "108"
- 返回有序集合
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
- 返回有序集合
key
中,所有score
值介于min
和max
之间(包括等于min
或max
)的成员。成员按score
递增排序。 min
和max
可以是-inf
和+inf
。- 可以使用
(
符号表示开区间,如(95
表示大于 95。 LIMIT
用于分页。
127.0.0.1:6379> ZRANGEBYSCORE leaderboard 100 110 WITHSCORES
1) "player1"
2) "108"
3) "player3"
4) "110"
127.0.0.1:6379> ZRANGEBYSCORE leaderboard (95 +inf LIMIT 0 2 WITHSCORES # 分数大于95,取前2个
1) "player1"
2) "108"
3) "player3"
4) "110"
- 返回有序集合
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
- 类似
ZRANGEBYSCORE
,但按score
递减排序。注意max
和min
的位置。
- 类似
ZCARD key
- 返回有序集合
key
的基数(成员数量)。
127.0.0.1:6379> ZCARD leaderboard
(integer) 4
- 返回有序集合
ZSCORE key member
- 返回有序集合
key
中,成员member
的score
值。如果member
不存在,返回(nil)
。
127.0.0.1:6379> ZSCORE leaderboard "player1"
"108"
- 返回有序集合
ZCOUNT key min max
- 返回有序集合
key
中,score
值在min
和max
之间(包括边界)的成员数量。区间表示同ZRANGEBYSCORE
。
127.0.0.1:6379> ZCOUNT leaderboard 100 110
(integer) 2
- 返回有序集合
ZINCRBY key increment member
- 为有序集合
key
的成员member
的score
值加上增量increment
。如果member
不存在,则添加该成员,其初始score
为increment
。返回member
的新score
值。原子操作。
127.0.0.1:6379> ZINCRBY leaderboard 5 "player2" # player2 原来是 95
"100" # 返回新的分数
- 为有序集合
ZREM key member [member ...]
- 移除有序集合
key
中的一个或多个成员,不存在的成员将被忽略。返回被成功移除的成员的数量。
127.0.0.1:6379> ZREM leaderboard "player4" "nonexistent"
(integer) 1
- 移除有序集合
ZRANK key member
- 返回有序集合
key
中成员member
的排名(按score
升序,排名从 0 开始)。
“`
当前升序排名: player2(100), player1(108), player3(110)
127.0.0.1:6379> ZRANK leaderboard “player1”
(integer) 1
“`- 返回有序集合
ZREVRANK key member
- 返回有序集合
key
中成员member
的排名(按score
降序,排名从 0 开始)。
“`
当前降序排名: player3(110), player1(108), player2(100)
127.0.0.1:6379> ZREVRANK leaderboard “player1”
(integer) 1
“`- 返回有序集合
ZREMRANGEBYRANK key start stop
- 移除有序集合
key
中,指定排名区间内的所有成员(按score
升序排名)。
- 移除有序集合
ZREMRANGEBYSCORE key min max
- 移除有序集合
key
中,所有score
值介于min
和max
之间(包括边界)的成员。
- 移除有序集合
(五) Hash(哈希)类型
Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。相对于将对象的每个属性都单独存储为 String 类型,使用 Hash 在内存占用和访问效率上通常更有优势,尤其是在对象属性较多时。
- 特点: 键值对集合,适合存储对象结构。
-
应用场景: 存储用户信息(如
user:id -> {name: "Alice", age: 30, email: "..."}
)、商品信息、配置项。 -
核心命令:
HSET key field value [field value ...]
- 将哈希表
key
中的字段field
的值设为value
。如果key
不存在,一个新的哈希表被创建并进行HSET
操作。如果字段field
已经存在于哈希表中,旧值将被覆盖。在 Redis 4.0.0 之前,HSET
一次只能设置一个字段。之后可以设置多个。返回被成功设置的字段数量(不包括更新的字段)。
127.0.0.1:6379> HSET user:1 name "Alice" age 30 email "[email protected]"
(integer) 3
127.0.0.1:6379> HSET user:1 age 31 city "New York"
(integer) 1 # age 是更新,city 是新增,返回新增数量 1
- 将哈希表
HGET key field
- 获取存储在哈希表
key
中指定字段field
的值。如果key
或field
不存在,返回(nil)
。
127.0.0.1:6379> HGET user:1 name
"Alice"
127.0.0.1:6379> HGET user:1 country
(nil)
- 获取存储在哈希表
HMSET key field value [field value ...]
- (已不推荐,建议使用
HSET
代替) 同时将多个field-value
对设置到哈希表key
中。此命令会覆盖已经存在的字段。
- (已不推荐,建议使用
HMGET key field [field ...]
- 获取哈希表
key
中,一个或多个给定字段的值。返回一个列表,值按请求字段的顺序排列。如果字段不存在,对应位置为(nil)
。
127.0.0.1:6379> HMGET user:1 name age country
1) "Alice"
2) "31"
3) (nil)
- 获取哈希表
HGETALL key
- 返回哈希表
key
中,所有的字段和值。返回的是一个包含字段和值的列表,字段和值交替出现。注意:对于包含大量字段的哈希表,此命令可能会阻塞服务器,生产环境考虑HSCAN
。
127.0.0.1:6379> HGETALL user:1
1) "name"
2) "Alice"
3) "age"
4) "31"
5) "email"
6) "[email protected]"
7) "city"
8) "New York"
- 返回哈希表
HDEL key field [field ...]
- 删除哈希表
key
中的一个或多个指定字段,不存在的字段将被忽略。返回被成功删除的字段的数量。
127.0.0.1:6379> HDEL user:1 email non_existent_field
(integer) 1
- 删除哈希表
HLEN key
- 返回哈希表
key
中字段的数量。
127.0.0.1:6379> HLEN user:1
(integer) 3 # name, age, city
- 返回哈希表
HEXISTS key field
- 查看哈希表
key
中,给定字段field
是否存在。存在返回1
,不存在返回0
。
127.0.0.1:6379> HEXISTS user:1 age
(integer) 1
127.0.0.1:6379> HEXISTS user:1 email
(integer) 0
- 查看哈希表
HKEYS key
- 返回哈希表
key
中的所有字段。
127.0.0.1:6379> HKEYS user:1
1) "name"
2) "age"
3) "city"
- 返回哈希表
HVALS key
- 返回哈希表
key
中的所有值。
127.0.0.1:6379> HVALS user:1
1) "Alice"
2) "31"
3) "New York"
- 返回哈希表
HINCRBY key field increment
- 为哈希表
key
中的字段field
的值加上增量increment
。如果key
不存在,会创建一个新的哈希表。如果field
不存在,会先创建field
并设值为 0。如果field
的值不是整数,会返回错误。原子操作。返回执行命令之后field
的值。
127.0.0.1:6379> HINCRBY user:1 age 1
(integer) 32
127.0.0.1:6379> HINCRBY user:1 login_count 1 # field 不存在
(integer) 1
- 为哈希表
HINCRBYFLOAT key field increment
- 类似
HINCRBY
,但可以处理浮点数增量。
- 类似
三、 通用键(Key)管理命令
这些命令不特定于某种数据类型,而是用于管理 Redis 中的键。
KEYS pattern
- 查找所有符合给定模式
pattern
的key
。*
匹配任意数量字符,?
匹配单个字符,[]
匹配括号内任一字符。 - 警告:
KEYS
命令会遍历所有键,在生产环境中对大量键使用会严重阻塞服务器,应极力避免!请使用SCAN
命令代替。
127.0.0.1:6379> KEYS user:*
1) "user:1"
2) "user:2"
(生产环境禁用!)
- 查找所有符合给定模式
SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
- 基于游标的迭代器,用于增量迭代键空间。它每次调用只返回少量元素,因此可以安全地在生产环境中使用,不会阻塞服务器。
- 需要多次调用,每次使用上次返回的游标作为下次调用的
cursor
参数,直到返回的游标为0
表示迭代完成。 MATCH pattern
: 只返回匹配模式的键。COUNT count
: 每次迭代返回的元素数量的提示(不保证精确)。TYPE type
: (Redis 6.0+) 只返回指定类型的键。
“`
第一次调用
127.0.0.1:6379> SCAN 0 MATCH user:* COUNT 10
1) “17” # 下一次迭代的游标
2) 1) “user:1”
2) “user:2”
… (最多 10 个左右)后续调用
127.0.0.1:6379> SCAN 17 MATCH user:* COUNT 10
1) “0” # 游标为 0,迭代结束
2) 1) “user:100”
…
``
HSCAN
* 类似地,还有用于迭代 Hash 字段的,迭代 Set 成员的
SSCAN,迭代 Zset 成员及分数的
ZSCAN`。EXISTS key [key ...]
- 检查给定的一个或多个
key
是否存在。返回存在的key
的数量。
127.0.0.1:6379> EXISTS user:1 non_existent_key
(integer) 1
- 检查给定的一个或多个
DEL key [key ...]
- 删除给定的一个或多个
key
。不存在的key
会被忽略。返回被成功删除的key
的数量。
127.0.0.1:6379> DEL user:1 tasks
(integer) 2
- 删除给定的一个或多个
TYPE key
- 返回
key
所储存的值的类型。可能是string
,list
,set
,zset
,hash
,stream
或none
(当key
不存在时)。
127.0.0.1:6379> SET my_string "hello"
OK
127.0.0.1:6379> TYPE my_string
string
127.0.0.1:6379> TYPE non_existent_key
none
- 返回
RENAME key newkey
- 将
key
改名为newkey
。如果newkey
已经存在,它将被覆盖。如果key
不存在,则返回错误。这是一个原子操作。
- 将
RENAMENX key newkey
- 当
newkey
不存在时,将key
改名为newkey
。如果newkey
已存在,则操作失败。原子操作。
- 当
EXPIRE key seconds
- 为给定
key
设置生存时间(秒)。当key
过期时,它会被自动删除。返回1
表示成功设置,0
表示key
不存在或设置失败。
127.0.0.1:6379> SET temp_data "important info"
OK
127.0.0.1:6379> EXPIRE temp_data 60 # 60 秒后自动删除
(integer) 1
- 为给定
PEXPIRE key milliseconds
- 类似
EXPIRE
,但单位是毫秒。
- 类似
TTL key
- 以秒为单位,返回给定
key
的剩余生存时间。 - 返回
-1
表示key
存在但没有设置过期时间(永久)。 - 返回
-2
表示key
不存在。
127.0.0.1:6379> TTL temp_data
(integer) 58 # (过了几秒后查询)
- 以秒为单位,返回给定
PTTL key
- 类似
TTL
,但单位是毫秒。
- 类似
PERSIST key
- 移除给定
key
的生存时间,将这个key
从『易失的』(带生存时间key
) 转换为『持久的』(一个不带生存时间、永不过期的key
)。成功返回1
,如果key
不存在或本身就是持久的,返回0
。
127.0.0.1:6379> PERSIST temp_data
(integer) 1
127.0.0.1:6379> TTL temp_data
(integer) -1 # 变为永久
- 移除给定
四、 进阶概念与相关命令(简介)
除了上述核心数据结构和键管理命令,Redis 还有一些重要的机制和相关命令值得了解:
- 事务 (Transactions):
- Redis 事务允许将一组命令打包,然后一次性、按顺序地执行。
- 核心命令:
MULTI
(开启事务),EXEC
(执行事务),DISCARD
(取消事务),WATCH key [key ...]
(乐观锁)。 - Redis 事务不保证原子性(如果事务中的某个命令执行出错,其他命令仍会执行),但能保证隔离性(事务执行期间不会被其他客户端命令打断)。
WATCH
提供了检查与设置(Check-and-Set)的机制,用于处理并发冲突。
- 发布/订阅 (Publish/Subscribe):
- 一种消息通信模式,发送者(publisher)发送消息到频道(channel),订阅者(subscriber)接收它们感兴趣的频道的消息。
- 核心命令:
SUBSCRIBE channel [channel ...]
,UNSUBSCRIBE [channel [channel ...]]
,PUBLISH channel message
,PSUBSCRIBE pattern [pattern ...]
,PUNSUBSCRIBE [pattern [pattern ...]]
。 - Pub/Sub 是“即发即弃”的,不保证消息的持久化。
- 持久化 (Persistence):
- 为了防止服务器宕机导致内存数据丢失,Redis 提供了两种持久化方式:
- RDB (Redis Database Backup): 在指定的时间间隔内生成数据集的时间点快照(snapshot)。适合备份,恢复速度快,但可能丢失最后一次快照后的数据。
- AOF (Append Only File): 记录服务器接收到的所有写操作命令,并在服务器启动时重新执行这些命令来恢复数据。数据安全性更高,但文件可能较大,恢复速度相对较慢。
- 可以通过配置文件 (
redis.conf
) 或CONFIG SET
命令进行设置。相关命令如SAVE
(同步 RDB),BGSAVE
(后台异步 RDB),BGREWRITEAOF
(重写 AOF 文件)。
- 为了防止服务器宕机导致内存数据丢失,Redis 提供了两种持久化方式:
- Lua 脚本 (Lua Scripting):
- 允许用户在 Redis 服务器端执行 Lua 脚本,可以实现复杂的原子操作,减少网络开销。
- 核心命令:
EVAL script numkeys key [key ...] arg [arg ...]
,EVALSHA sha1 numkeys key [key ...] arg [arg ...]
,SCRIPT LOAD script
,SCRIPT EXISTS sha1 [sha1 ...]
,SCRIPT FLUSH
,SCRIPT KILL
。
五、 最佳实践与建议
- Key 命名: 使用有意义且结构化的 Key 名,如
object-type:id:field
(例如user:1001:profile
)。这有助于管理和调试。 - 设置过期时间: 对缓存类数据、Session 等临时数据,务必使用
EXPIRE
或SETEX
设置合理的过期时间,防止内存无限增长。 - 避免使用耗时命令: 在生产环境中,避免使用如
KEYS
,SMEMBERS
,HGETALL
,LRANGE 0 -1
(对超大列表)等可能阻塞服务器的操作。优先使用SCAN
系列命令进行迭代。 - 内存管理: 监控 Redis 内存使用情况 (
INFO memory
)。选择合适的数据结构(例如,用 Hash 存储对象比多个 String 更节省内存)。考虑使用 Redis 的内存淘汰策略(如 LRU, LFU)。 - 安全: 绑定 Redis 到内网 IP (
bind 127.0.0.1
或内网地址),设置强密码 (requirepass
),考虑使用 Redis 6.0+ 的 ACL(访问控制列表)进行更细粒度的权限管理。
结语
Redis 是一个功能强大且灵活的工具。掌握其核心数据结构和命令是有效利用 Redis 的第一步,也是最重要的一步。本教程覆盖了最常用的命令和概念,但这仅仅是冰山一角。随着你对 Redis 的深入使用,还会接触到 Stream 数据类型、地理空间索引、HyperLogLog、Bitmap、Redis Modules 等更多高级特性。
理论学习固然重要,但更关键的是动手实践。尝试在你的项目中使用 Redis 解决实际问题,比如实现缓存、构建排行榜、或者设计一个简单的消息队列。通过不断的实践和探索,你将能够更加深刻地理解 Redis 的精髓,并将其威力发挥到极致。祝你在 Redis 的世界里探索愉快!