Redis 基础:通用命令、常用数据结构与单线程模型
redis系列
文章目录
前言
从本篇文章开始,我们正式进入redis部分的学习,本系列是用来记录博主自己学习redis的收获
一、redis的通用指令
1.1、set、get命令
这个命令主要是操作
string类型,我们先来提前认识它
向redis服务器中存储键值对数据:
set key value [value]

通过key获取redis中的value数据:
get key

key再redis中是唯一的,如果多次使用同一个key多次存入,value会被修改
1.2、keys命令
返回所所以满足样式的value值:
keys pattern
支持格式:
- ?:表示匹配任意一个字符
- * :表示匹配任意多个字符
- [aecd…] 表示匹配 [ ] 中的任意一个字符
- [^e]:表示不匹配 [ ] 中的字符
- [a-b]:表示不匹配以
a为开始b为结尾的字符
这里需注意keys 命令的时间复杂度是 O(N),而 Redis 是单线程模型。执行 keys * 会遍历 Redis 中所有 key,在生产环境 key 数量巨大时,会占用大量时间,导致 Redis 主线程被完全阻塞,无法处理其他任何客户端请求。
这和正则表达式比较类似,大家可以自己尝试
1.3、scan命令
SCAN(Redis核心游标迭代命令)增量迭代数据库所有key,替代KEYS *(避免阻塞),支持模糊匹配、分批返回。
cursor:游标(不同于下标),初始必须传0,每次返回新游标,直到返回0表示结束MATCH pattern:模糊匹配key(如user:*)COUNT count:期望每次返回数量(默认10,只是建议,Redis不一定严格遵守)
SCAN cursor [MATCH pattern] [COUNT count]
## 1.4、exists命令
判断某个 key 是否存在,返回存在的个数:
```powershell
exists key [key]

1.5、del
删除指定的 key,返回删除的个数:
del key [key]

MySQL的删除操作(如
drop database、drop table、delete from)风险极高,误删数据后难以恢复;而Redis的删除操作风险需结合其应用场景判断:作为缓存时,少量key删除影响有限,但大量数据被清空会引发缓存雪崩,直接压垮后端MySQL(大量请求数据在redis中找不到,就会去MySQL中查找);若Redis作为数据库,误删数据的影响则与MySQL一样严重;而当Redis用作消息队列时,误删数据的影响则需根据业务场景具体分析。
1.6、expire命令
为指定的 key 添加秒级的过期时间,过期后删除对应的key-value数据:
expire key seconds

可以使用
pexpire设置毫秒级的过期时间
1.7、ttl命令
获取指定 key 的过期时间,秒级:
ttl key

Redis 采用 「定期删除 + 惰性删除」 组合策略,来处理过期的 key:
-
定期删除(抽样式清理)
- Redis 会每隔一段时间,随机抽取一部分设置了过期时间的 key 来检查。
- 对其中已经过期的 key 进行删除,以此避免遍历所有 key 带来的性能灾难。
- 为什么要“抽样”?因为 Redis 是单线程的,如果一次性扫描大量 key,会阻塞主线程,导致正常请求无法处理(和执行
keys *的危害一样)。
-
惰性删除(访问时检查)
- 即使 key 已经过期,但它不会立刻被删除,而是继续存在。
- 当客户端访问这个 key 时,Redis 才会检查它是否过期:
- 若已过期:直接删除 key,并返回 nil。
- 若未过期:正常返回 value。
- 缺点:如果一个过期 key 一直不被访问,就会一直留在内存里,变成“脏数据”。
1.8、type
返回 key 对应的value的数据类型:
type key

``
二、数据库相关命令
Redis 默认提供16个逻辑数据库(编号0-15),这些数据库共享同一套服务资源,属于逻辑隔离而非物理隔离。与MySQL不同,Redis不支持手动创建或删除数据库。客户端默认连接0号数据库,可通过SELECT命令切换至指定编号的数据库。
2.1、SELECT命令
select dbIndex


❗Redis 虽然支持多数据库功能,但随着版本迭代,已不再推荐使用该特性。若确实需要完全隔离的键值存储环境,建议通过部署多个 Redis 实例来实现,而非在单个实例中使用多数据库功能。原因在于:
- Redis 对多数据库的支持较为有限,缺乏关键特性
- 无论配置多少数据库,Redis 始终采用单线程模型,所有操作仍需排队执行
- 多数据库会增加开发调试和运维的复杂度
因此在实际应用中,坚持使用默认的数据库 0 是最佳实践。。
2.2、flushdb / flushall
flushdb 和 flushall 命令用于清空 Redis 数据库,其中 flushdb 仅清空当前选中的数据库,而 flushall 则会清空所有数据库。
三、redis中的常用数据结构

Redis 对外提供了 5 种常用数据结构,但每种数据结构在底层都有多种内部编码实现,对外承诺的是标准数据结构(如哈希表保证 O (1)),但底层会根据数据实际情况,用更合适的内部编码实现,在用户无感知的前提下,做到 “省时间 + 省空间” 的双重优化。
设计好处:
- 兼容升级:可以优化内部编码,无需修改外部命令。例如 Redis 3.2 引入
quicklist替代ziplist+linkedlist,用户无感知。 - 场景适配:不同编码各有优势,Redis 会根据数据大小、类型自动切换,平衡性能与内存。
我们可通过
object encoding命令查询键的底层编码
3.1、String(字符串)
-
对外用途:存储字符串、数字、二进制数据,Redis 所有键(key)均为字符串,是其他数据结构的基石。
-
底层内部编码:
int:当 value 是整数时,直接用整数存储,节省内存,还支持incr/decr原子操作。embstr:短字符串优化(≤39字节),将 RedisObject 和字符串数据放在一块连续内存,减少内存碎片,提高缓存效率。raw:长字符串(>39字节),单独分配内存存储字符串数据。
-
核心特性:不处理字符集编码,按客户端传入格式原样存储。
3.1.1、常用命令
SET
SET key value [EX/PX 时间] [NX/XX]
设置键值,支持过期时间与存在性判断,ex(设置秒级过期时间)、px(设置毫秒级过期时间)、NX(仅不存在时设置)、XX(仅存在时设置)

可以看到当键值对数据已经存在了,NX无法生效,当键值对数据不存在时XX无法生效。
GET
GET key
获取key对应的值,不存在返回 nil,非字符串类型会报错:
MGET
MGET key [key ...]
⼀次性获取多个 key 的值。如果对应的 key 不存在或者对应的数据类型不是 string,返回 nil,这个命令可以减少网络io

MSET
MSET key value [key value ...]
⼀次性设置多个 key 的值
SETNX
SETNX key value
在 key 不存在的情况下设置 key-value
SETEX
SETEX key seconds value

PSETEX
PSETEX key seconds value
设置key的过期时间(毫秒级)
INCR
INCR key
对指定 key 的字符串数值执行加一操作。若 key 不存在,则默认其值为 0。当 key 对应的字符串不符合整型格式或超出 64 位有符号整型范围时,将抛出错误。
INCRBY
INCRBY key N(可以为负数)
将指定键(key)对应的字符串数值增加相应值。若键不存在,则默认其值为 0 进行运算。若该键对应的值不是有效整数或超出 64 位有符号整数范围,将返回错误。
DECR
DECR key
将 key 对应的字符串数字值减一。若 key 不存在,默认其值为 0。若 key 对应的字符串不是整数或超出 64 位有符号整型范围,则返回错误。
DECRBY
DECRBY key N
对指定 key 的字符串数值执行减法操作。若 key 不存在,默认其值为 0 进行处理。当 key 对应的值不是有效整数或超出 64 位有符号整数范围时,将返回错误提示。

INCRBYFLOAT
INCRBYFLOAT key N
对指定键(key)对应的字符串值进行浮点数加法操作。若该值为负数,则执行减法运算。若键不存在,默认其值为0。若键对应的值非字符串或无法解析为浮点数(包括科学计数法),则抛出错误。
APPEND
APPEND KEY VALUE
如果 key 已存在且存储的是字符串类型,该命令会将 value 追加到原字符串末尾;若 key 不存在,其效果与 SET 命令完全相同。
查询结果中显示的是中文对应的16进制编码,如果想要显示中文,可以在启动redis客户端的时候添加–raw选项
GETRANGE
GETRANGE key start end
获取 key 对应字符串的子串,由 start 和 end 指定区间(包含两端)。支持负数索引:-1 表示最后一个字符,-2 表示倒数第二个字符,以此类推。若索引超出范围,系统会自动根据字符串长度进行修正。

在操作中文字符串是,中文会被强制切割,可能出现乱码问题
SETRANGE
SETRANGE key offset value
从指定偏移位置开始,用value替换字符串的一部分,并返回修改后的字符串长度
STRLEN
STRLEN key
获取指定 key 对应的字符串长度。若 key 不存在则返回 0(单位:字节);若 key 存储的不是字符串类型,则抛出错误。

3.2、 Hash(哈希)
主流编程语言基本都支持哈希结构,只是名称各异,可能叫哈希、字典、关联数组或映射。Redis中的哈希类型特指值本身也是一个键值对集合,格式为key=“key”,value={{field1,value1},…,{fieldN,valueN}}。
在哈希类型中,字段与值的对应关系通常称为 field-value,用于区分 Redis 整体的键值对(key-value)。需要注意的是,这里的 value 特指字段(field)对应的值,而非键(key)对应的值。
- 底层内部编码:
ziplist:压缩列表,当元素数量少、字段值短的时候使用,内存紧凑,节省空间。hashtable:标准哈希表,当元素数量超过阈值时自动切换,提供 O(1) 的读写性能。
3.2.1、常用命令
HSET
设置指定字段(field)对应的值(value),并返回成功添加的字段数量。
HSET key field value [field value ...]

HGET
获取哈希中指定字段的值,若字段不存在则返回 nil。
HGET key field

HEXISTS
检查哈希表中是否存在指定字段:
- 1 - 表示字段存在
- 0 - 表示字段不存在
HEXISTS key field

HDEL
删除哈希表中指定字段的时间复杂度:
- 删除单个元素:O(1)
- 删除N个元素:O(N)
HDEL key field [field ...]

HKEYS
获取哈希中的所有字段并返回字段列表
HKEYS key

HVALS
获取哈希表中所有的值并返回
HVALS key

HGETALL
获取哈希中的所有字段及其对应值,并返回这些键值对。
HGETALL key

HMGET
获取哈希中多个字段的值,返回对应字段的值或 nil。
HMGET key field [field ...]

HLEN
获取哈希表中所有字段的数量并返回该数值
HLEN key

HSETNX
当字段不存在时,设置哈希中的字段和值:返回1表示成功,0表示失败
HSETNX key field value

HINCRBY
更新哈希表中指定字段的数值,增加指定增量,并返回更新后的字段值。
HINCRBY key field increment

HINCRBYFLOAT
支持浮点数的 HINCRBY 实现,返回字段更新后的数值。
HINCRBYFLOAT key field increment

3.3 List(列表)
Redis 列表(List)是 Redis 中存储多个有序字符串的数据结构,具备以下核心特点与功能:

- 有序可重复:列表中的元素按插入顺序排列,支持通过正/负索引(如
0或-1)访问,且允许存在重复元素。 - 高效两端操作:支持在列表头部/尾部快速插入(
LPUSH/RPUSH)、弹出(LPOP/RPOP)元素,时间复杂度为 O(1),可灵活充当栈(后进先出)或队列(先进先出)使用。 - 丰富操作支持:除基础读写外,还支持获取指定范围元素、删除特定元素、截取列表等操作;获取元素不会改变列表长度,删除操作则会缩短列表。
- 存储上限:单个列表最多可存储
2^32-1个元素,能满足多数业务场景的批量数据存储需求。 - 底层内部编码:
quicklist(Redis 3.2+):默认实现,结合了ziplist和linkedlist的优势,是分段的压缩列表,兼顾内存和性能。ziplist:早期版本的实现,元素少时使用,内存紧凑。linkedlist:双向链表,元素多时使用,随机访问性能差,但两端操作快。
3.3.1、常用命令
LPUSH
将⼀个或多个元素从头部插入到列表中,并返回操作后的列表长度
LPUSH key element [element ...]

LPUSHX
若 key 存在,则从列表左侧插入一个或多个元素;若不存在,则直接返回当前列表长度。最终返回操作后的列表长度。
LPUSHX key element [element ...]

RPUSH
将元素从右侧插入(尾插)到列表中,返回插入后列表的长度
RPUSH key element [element ...]

RPUSHX
当 key 存在时,将一个或多个元素从右侧插入(尾插)到列表中,并返回插入后的列表长度。
RPUSHX key element [element ...]

LRANGE
获取区间 [start, end] 内的所有元素(包含边界值,支持负数索引)
LRANGE key start stop

LPOP
从列表头部移除元素并返回该元素,若列表为空则返回 nil。
LPOP key

RPOP
从列表尾部移除元素并返回该元素,若列表为空则返回 nil
RPOP key

LINDEX
返回指定索引位置的元素,若超出范围则返回 nil。
LINDEX key index

LINSERT
在基准值位置插入元素,并返回插入后的列表长度(基准值按从左到右的顺序查找)。
LINSERT key <BEFORE | AFTER> pivot element

LLEN
获取列表长度,返回列表的长度
LLEN key

LREM
lrem key count value
- key:列表的键名
- count:删除数量与方向
count > 0:从列表左边开始,删除前 count 个等于 value 的元素count < 0:从列表右边开始,删除前 |count| 个等于 value 的元素count = 0:删除列表中所有等于 value 的元素
- value:要删除的元素值
返回实际删除的元素个数。
LTRIM
对列表进行截取,只保留指定索引(支持负数索引)范围内的元素,删除其余元素
start:起始索引(从左 0 开始)end:结束索引
LTRIM key start end

LSET
修改列表指定索引位置的元素值。
index:要修改的元素索引value:新值- 索引超出范围会报错
LSET key index value

BLPOP / BRPOP
当列表为空时,客户端会进入阻塞等待状态(此时仍可执行其他Redis命令),直到有新元素加入或超时。这是实现消息队列的核心机制。在阻塞期间不会占用CPU资源。执行结果返回[键名, 元素值]格式的数据,若超时则返回nil。
timeout:阻塞超时时间(秒),0表示一直阻塞- 简单消息队列
- 任务队列
- 异步解耦
BLPOP key [key ...] timeout
BRPOP key [key ...] timeout

如果列表中元数据,功能和lpop一样,当 BLPOP/BRPOP 传入多个 Key 时,会按传入顺序检查列表,优先从第一个非空列表中弹出元素,任何一个非空都会返回停止阻塞

3.4 Set(集合)
Redis 集合(Set)存储多个字符串元素,与列表不同,集合的元素无序且不允许重复,单个集合最多可存储 2^32-1 个元素。除了支持集合内的增删查改,还支持多个集合间的交集、并集、差集运算。
- 底层内部编码:
intset:当元素都是整数且数量少时使用,有序数组存储,节省内存,查询快。hashtable:标准哈希表,当元素包含非整数或数量超过阈值时切换,保证 O(1) 操作性能。
3.4.1 常用命令
SADD
向集合中添加一个或多个元素时,若元素已存在则不会被重复添加。该方法会返回本次成功添加的新元素数量。
SADD key member [member ...]

SMEMBERS
获取集合中的所有元素,返回一个无序的列表
SMEMBERS key

SISMEMBER
检查元素是否存在于集合中时:
- 返回 1 表示元素存在
- 返回 0 表示元素不存在或键不存在
SISMEMBER key member

SPOP
从集合中移除并返回一个或多个元素。需要注意的是,由于集合中的元素是无序的,因此被移除的元素实际上是随机选择的。
SPOP key [count]

SMOVE
将一个元素从源集合移至目标集合,成功返回1,失败返回0
SMOVE source destination member

SREM
从集合中移除指定元素,返回实际被移除的元素数量。
SREM key member [member ...]

SCARD
获取集合(set)的元素基数(cardinality),即集合中元素的数量。
SCARD key

SRANDMEMBER
随机获取指定key的count个元素,返回获取到的元素
SRANDMEMBER key count

SINTER
获取指定集合的交集元素并返回。
SINTER key [key ...]

SINTERSTORE
将给定集合的交集元素存入目标集合并返回交集元素数量。
SINTERSTORE destination key [key ...]

SUNION
返回给定集合的并集元素
SUNION key [key ...]

SUNIONSTORE
将给定集合中的元素合并到目标集合中,并返回合并后的元素总数。
SUNIONSTORE destination key [key ...]

SDIFF
计算给定集合的差集元素,时间复杂度为 O(N),其中 N 是所有集合元素的总数。返回差集结果。
SDIFF key [key ...]

SDIFFSTORE
提取目标 set 中与给定 set 的差集元素并保存,返回差集元素的数量。
⽰
SDIFFSTORE destination key [key ...]

3.5 Zset(有序集合)
有序集合相较于字符串、列表、哈希和集合可能会显得陌生。它继承了集合不允许重复元素的特性,但其独特之处在于:每个元素都关联着一个唯一的浮点型分数(score)。正是通过这个分数值,有序集合实现了元素的排序功能(而非基于下标索引)。此外,有序集合还支持按分数范围查询、获取特定分数元素以及计算成员排名等实用功能。
- 对外用途:存储带权重的有序元素,可用于排行榜、延时队列。
- 底层内部编码:
ziplist:元素数量少、分值小时使用,压缩列表存储,节省内存。skiplist(跳表):当元素数量多或分值跨度大时使用,保证 O(logN) 的读写和排序性能。
3.5.1、常用命令
ZADD
将指定元素及其关联分数添加到有序集合(zset)中,分数应为 double 类型,允许使用 +inf/-inf 表示正负无穷。
可选参数:
• XX:仅更新已存在的元素,不添加新元素
• NX:仅添加新元素,不更新已存在的元素
• CH:默认返回新增元素数量,指定该选项后同时返回更新元素数量
• INCR:使命令具备 ZINCRBY 功能,对元素分数进行增量操作(此时仅支持单个元素操作)
返回值:本次添加成功的元素个数。
zset以score为依据按照升序排列,若分数相同则按照member 的字典序进行比较
ZADD key [NX | XX] [GT | LT] [CH] [INCR] score member [score member ...]



这个选项自己尝试吧
ZRANGE
获取指定key对应的Zset成员,若添加WITHSCORES参数则同时返回成员对应的分数
ZRANGE key start end [WITHSCORES]

ZCARD
获取有序集合(zset)的元素数量
ZCARD key
v
ZCOUNT
统计数值在 [min, max] 区间内的元素数量(默认包含边界值),或使用开区间符号排除边界值。
ZCOUNT key min max

ZREVRANGE
返回指定区间内的元素(按分数降序排列)。使用 WITHSCORES 参数可同时返回元素对应的分数值。
注意:该命令可能在 6.2.0 版本后被废弃,其功能将整合至 ZRANGE 命令中。
ZREVRANGE key start stop [WITHSCORES]

ZRANGEBYSCORE
筛选分数在 min 和 max 之间的元素(默认包含边界值,可用 ( 符号排除边界)。
注:该命令可能在 6.2.0 版本后被弃用,其功能将整合至 ZRANGE 命令中。
ZRANGEBYSCORE key min max [WITHSCORES]

ZPOPMAX
删除并返回分数最高的 count 个元素及其对应分数。
ZPOPMAX key [count]

BZPOPMAX
ZPOPMAX 的阻塞版本会立即返回弹出的元素列表(支持多键操作,只要有一个键不为空即返回结果)。
BZPOPMAX key [key ...] timeout

ZPOPMIN
移除并返回分数最低的 count 个元素及其对应分数。
ZPOPMIN key [count]
BZPOPMIN
ZPOPMIN 的阻塞版本会返回一个元素列表支持多键操作,只要有一个键不为空即返回结果)。
BZPOPMIN key [key ...] timeout
ZRANK
获取指定元素的升序排名
ZRANK key member

ZREVRANK
返回指定元素的降序排名
ZREVRANK key member

ZSCORE
获取指定元素的分数值
ZSCORE key member

ZREM
移除指定元素并返回实际删除的个数
ZREM key member [member ...]

ZREMRANGEBYRANK
按升序排列后,删除指定区间内的元素(闭区间),并返回被删除的元素数量。
ZREMRANGEBYRANK key start stop

ZREMRANGEBYSCORE
移除指定区间内的元素(含边界值),并返回被移除的元素数量。
ZREMRANGEBYSCORE key min max

ZINCRBY
为指定元素的关联分数添加指定分值(支持浮点数),返回更新后的分数值。
⽰例:
ZINCRBY key increment member

ZINTERSTORE
求出给定有序集合元素的交集并保存进目标有序集合,在合并过程中以元素为单位进行合并,元素对应的分数按照不同的聚合方式和权重得到新的分数,返回目标集合中的元素个数
- destination:结果存放的目标有序集合
- numkeys:参与计算的有序集合数量
- WEIGHTS:为每个集合设置分数权重,计算时分数先乘以权重再聚合(权重和key顺序对应)
- AGGREGATE:分数聚合规则
- SUM:相加(默认)
- MIN:取最小值(乘权重后再取值)
- MAX:取最大值




ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE <SUM | MIN | MAX>]
ZUNIONSTORE
计算给定有序集合的并集,并将结果保存至目标有序集合。合并时以元素为单位,根据指定聚合方式和权重计算新分数。返回目标集合的元素总数。
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight
[weight ...]] [AGGREGATE <SUM | MIN | MAX>]

若不指定AGGREGATE ,则默认使用SUM
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)