API的理解和使用

本文全面介绍了Redis,包括全局命令、数据结构内部编码、单线程架构等。详细阐述了字符串、哈希、列表、集合、有序集合等数据结构的命令和内部编码,还介绍了键管理,如单个键管理、遍历键和数据库管理等内容,为开发者提供了Redis使用的全面指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.全局命令

keys *查看所有键
dbsize键总数
exists key检查键是否存在
del key [key ...]删除键
expire key seconds.键过期
type key键的数据结构类型

dbsize命令在计算键总数时不会遍历所有键,而是直接获取Redis内置的 键总数变量,所以dbsize命令的时间复杂度是O(1)。而keys命令会遍历所 有键,所以它的时间复杂度是O(n),当Redis保存了大量键时,线上环境禁止使用

Redis支持对键添加过期时间,当超过过期时间后,会自动删除键,例如为键hello设置了10秒过期时间:expire hello 10

  • ttl命令会返回键的剩余过期时间,它有3种返回值:
    • 大于等于0的整数:键剩余的过期时间。
    • ·-1:键没设置过期时间。
    • ·-2:键不存在

2.数据结构内部编码

过object encoding key查询内部编码

Redis这样设计有两个好处:第一,可以改进内部编码,而对外的数据结构和命令没有影响,这样一旦开发出更优秀的内部编码,无需改动外部数据结构和命令,例如Redis3.2提供了quicklist,结合了ziplist和linkedlist两者的优势,为列表类型提供了一种更为优秀的内部编码实现,而对外部用户来说基本感知不到。第二,多种内部编码实现可以在不同场景下发挥各自的优势,例如ziplist比较节省内存,但是在列表元素比较多的情况下,性能会有所下降,这时候Redis会根据配置选项将列表类型的内部实现转换为 linkedlist。

3.单线程架构

Redis使用了单线程架构和I/O多路复用模型来实现高性能的内存数据库服务。

  • 为什么Redis使用单线程模 型会达到每秒万级别的处理能力呢?
    • 第一,纯内存访问。
    • 第二,非阻塞I/O。
    • 第三,单线程避免了线程切换和竞态产生的消耗。

4.字符串

字符串类型是Redis最基础的数据结构。首先键都是字符串类型,而且 其他几种数据结构都是在字符串类型基础上构建的。字符串类型的值实际可以 是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字 (整数、浮点数),甚至是二进制(图片、音频、视频),但是值最大不能 超过512MB

4.1 命令

4.1.1常用命令

设置值

set key value [ex seconds] [px milliseconds] [nx|xx]设置值

 例如设置键为hello,值为world的键值对,返回结果为OK代表设置 成功:set hello world

  • 选项
    • ·ex seconds:为键设置秒级过期时间。
    • ·px milliseconds:为键设置毫秒级过期时间。
    • ·nx:键必须不存在,才可以设置成功,用于添加
    • ·xx:与nx相反,键必须存在,才可以设置成功,用于更新

除了set选项,Redis还提供了setexsetnx两个命令:setex key seconds value
                                                                                     
   setnx key value
它们的作用和ex和nx选项是一样的。

指令使用例子:set hello world

                        setnx hello redis

                        set hello jedis xx

获取值

get key获取值

 例如:127.0.0.1:6379> get hello
            "world"

如果要获取的键不存在,则返回nil(空):

批量设置值

mset key value [key value ...]批量设置值

下面操作通过mset命令一次性设置4个键值对:mset a 1 b 2 c 3 d 4

批量获取值

mget key [key ...]批量获取值

下面操作批量获取了键a、b、c、d的值:mget a b c d

批量处理可以省时间,因为对于客户端来说,一次命令除了命令时间还是有网络时间,Redis的处理能力已经足够高,对于开发人员来说,网络可能会成为性能的瓶颈。要注意的是每次批量操作所发送的命令数不是无节制的,如果数量过多可能造成Redis阻塞或者网络拥塞。

计数

incr key计数
decr key 自减
incrby key  increment自增指定数字
decrby key  decrement自减指定数字
incrbyfloat key increment自增浮点数
  • incr命令用于对值做自增操作,返回结果分为三种情况:
    • ·值不是整数,返回错误。
    • 值是整数,返回自增后的结果。
    • 键不存在,按照值为0自增,返回结果为1。

4.1.2不常用命令

追加值

append key value追加值

 append可以向字符串尾部追加值,例如:append key world

字符串长度

strlen key字符串长度

设置并返回原值

getset key value设置并返回原值

设置指定位置的字符

setrange key offeset value设置指定位置的字符

offeste为要改变位置字符的位置

获取部分字符串

getrange key start end获取部分字符串

start和end分别是开始和结束的偏移量,偏移量从0开始计算,例如下面操作获取了值best的前两个字符:getrange redis 0 1


 表2-2是字符串类型命令的时间复杂度,开发人员可以参考此表,结合 自身业务需求和数据大小选择适合的命令。

4.2内部编码

  • 字符串类型的内部编码有3种:
    • ·int:8个字节的长整型。
    • ·embstr:小于等于39个字节的字符串。
    • raw:大于39个字节的字符串。

Redis会根据当前值的类型和长度决定使用哪种内部编码实现。

5. 哈希

5.1命令

设置值

hset key field value设置值

下面为user:1添加一对field-value:hset user:1 name tom

如果设置成功会返回1,反之会返回0。此外Redis提供了hsetnx命令,它 们的关系就像set和setnx命令一样,只不过作用域由键变为field。

获取值

hget key field获取值

例如,下面操作获取user:1的name域(属性)对应的值:hget user:1 name

如果键或field不存在,会返回nil:

删除field

hdel key field [field ...]删除field

hdel会删除一个或多个field,返回结果为成功删除field的个数,例如:hdel user:1 name

计算field个数

hlen key计算field个数

批量设置或获取field-value

hmget key field [field ...]批量获取field-value
hmset key field value [field value ...]批量设置field-value

判断field是否存在

hexists key field判断field是否存在

获取所有field

hkeys key获取所有field

获取所有的field-value

hgetall key获取所有的field-value

在使用hgetall时,如果哈希元素个数比较多,会存在阻塞Redis的可能。 如果开发人员只需要获取部分field,可以使用hmget,如果一定要获取全部 field-value,可以使用hscan命令,该命令会渐进式遍历哈希类型。

hincrby hincrbyfloat

hincrby key field自增指定数字
hincrbyfloat key field自增浮点数

计算value的字符串长度(需要Redis3.2以上)

hstrlen key field计算value的字符串长度

5.2内部编码

·ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries 配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64 字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的 结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀。

·hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使 用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而 hashtable的读写时间复杂度为O(1)。

6. 列表

列表(list)类型是用来存储多个有序的字符串,列表中的每个字符串 称为元素(element),一个列表最多可以存储2^{32}  -1个元素。

在Redis中,可 以对列表两端插入(push)和弹出(pop),还可以获取指定范围的元素列表、获取指定索引下标的元素等。列表是一种比 较灵活的数据结构,它可以充当栈和队列的角色,在实际开发上有很多应用 场景。

  • 列表类型有两个特点:
    • 第一、列表中的元素是有序的,这就意味着可以 通过索引下标获取某个元素或者某个范围内的元素列表
    • 列表中的元素可以是重复的

6.1 命令

操作类型操作
添加rpush         lpush        linsert 
查找lrange        lindex        llen
删除lpop        rpop        lrem        ltrim
修改lset
阻塞操作blpop        brpop

添加操作

从右边插入元素

rpush key value [value ...]

从左边插入元素

lpush key value [value ...]

向某个元素前或者后插入元素

linsert key before|after pivot value

linsert命令会从列表中找到等于pivot的元素,在其前(before)或者后 (after)插入一个新的元素value。

.查找

获取指定范围内的元素列表

lrange key start end

  • lrange操作会获取列表指定索引范围所有的元素。索引下标有三个特点:
    • 第一,索引下标从左到右分别是0到N-1,但是从右到左分别是-1到-N。
    • 第二,lrange中的end选项包含了自身
    • 第三,lrange 0 -1命令可以从左到右获取列表的所有元素:

获取列表指定索引下标的元素

lindex key index

获取列表长度

llen key

删除

从列表左侧弹出元素

lpop key

从列表右侧弹出

rpop key

删除指定元素

lrem key count value

  • lrem命令会从列表中找到等于value的元素进行删除,根据count的不同 分为三种情况:
    • count>0,从左到右,删除最多count个元素。
    • count<0,从右到左,删除最多count绝对值个元素。
    • count=0,删除所有

按照索引范围修剪列表

ltrim key start end

只保留列表第start个到第end个元素

修改

修改指定索引下标的元素

lset key index newValue

阻塞操作

阻塞式弹出如下:

blpop key [key ...] timeout

brpop key [key ...] timeout

blpop和brpop是lpop和rpop的阻塞版本,它们除了弹出方向不同,使用方法基本相同,

  • brpop命令包含两个参数:
    • key[key...]:多个列表的键。
    • ·timeout:阻塞时间(单位:秒)。
  • 1)列表为空:如果timeout=3,那么客户端要等到3秒后返回,如果 timeout=0,那么客户端一直阻塞等下去:brpop list:test 3           brpop list:test 0
    如果此期间添加了数据element1,客户端立即返回:
  • 列表不为空:客户端会立即返回。brpop list:test 0
  • 两点需要注意
    • 第一点,如果是多个键,那么brpop会从左至右遍历键,一旦有一个键能弹出元素,客户端立即返回:
    • 第二点,如果多个客户端对同一个键执行brpop,那么最先执行brpop命 令的客户端可以获取到弹出的值。

6.2 内部编码

·ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使用。

·linkedlist(链表):当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。

使用场景

  • ·lpush+lpop=Stack(栈)
  • ·lpush+rpop=Queue(队列)
  • ·lpsh+ltrim=Capped Collection(有限集合)
  • ·lpush+brpop=Message Queue(消息队列)

7.集合

集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一 样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素。

7.1 命令

下面将按照集合内和集合间两个维度对集合的常用命令进行介绍。

7.1.1集合内命令

添加元素

sadd key element [element ...]

返回结果为添加成功的元素个数

删除元素

srem key element [element ...]

返回结果为成功删除元素个数

计算元素个数

scard key

scard的时间复杂度为O(1),它不会遍历集合所有元素,而是直接用 Redis内部的变量。

判断元素是否在集合中

sismember key element

如果给定元素element在集合内返回1,反之返回0

随机从集合返回指定个数元素

srandmember key [count]

[count]是可选参数,如果不写默认为1,例如:

从集合随机弹出元素

spop key

需要注意的是Redis从3.2版本开始,spop也支持[count]参数。

srandmember和spop都是随机从集合选出元素,两者不同的是spop命令 执行后,元素会从集合中删除,而srandmember不会。

获取所有元素

smembers key

smembers和lrange、hgetall都属于比较重的命令,如果元素过多存在阻 塞Redis的可能性,这时候可以使用sscan来完成。

7.1.2 集合间操作

求多个集合的交集

sinter key [key ...]

求多个集合的并集

suinon key [key ...]

求多个集合的差集

sdiff key [key ...]

将交集、并集、差集的结果保存

sinterstore destination key [key ...]

suionstore destination key [key ...]

sdiffstore destination key [key ...]

7.2 内部编码

intset(整数集合):当集合中的元素都是整数且元素个数小于set-maxintset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实现,从而减少内存的使用。

hashtable(哈希表):当集合类型无法满足intset的条件时,Redis会使 用hashtable作为集合的内部实现。

使用场景

  • sadd=Tagging(标签) 
  • spop/srandmember=Random item(生成随机数,比如抽奖)
  • sadd+sinter=Social Graph(社交需求)

8. 有序集合

它保留了集合不能有重复成员的特性, 但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下标作为排序依据不同的是,它给每个元素设置一个分数(score)作为排序的依据。

有序集合中的元素不能重复,但是score可以重复。

8.1 命令

本节依旧按照集合内和集合外两个维度对有序集合的命令进行介绍。

8.1.1集合内

添加成员

zadd key score member [score member ...]

  • 有关zadd命令有两点需要注意:
    • Redis3.2为zadd命令添加了nx、xx、ch、incr四个选项:
      • nx:member必须不存在,才可以设置成功,用于添加。
      • xx:member必须存在,才可以设置成功,用于更新。
      • ch:返回此次操作后,有序集合元素和分数发生变化的个数
      • incr:对score做增加,相当于后面介绍的zincrby。
    • ·有序集合相比集合提供了排序字段,但是也产生了代价,zadd的时间 复杂度为O(log(n)),sadd的时间复杂度为O(1)。

 计算成员个数

zcard key

计算某个成员的分数

zscore key member

计算成员的排名

zrank key member

zrevrank key member

zrank是从分数从低到高返回排名,zrevrank反之。

删除成员

zrem key member [member ...]

增加成员的分数

zincrby key increment member

返回指定排名范围的成员

zrange key start end [withscores]

zrevrange key start end [withscores]

如果加上withscores选项,同时会返回成员的分数:zrange user:ranking 0 2 withscores

返回指定分数范围的成员

zrangebyscore key min max [withscores] [limit offset count]

zrevrangebyscore key max min [withscores] [limit offset count]

[limit offset count]选项可以限制输出的起始位置和个数:同时min和max还支持开区间(小括号)和闭区间(中括号),-inf和 +inf分别代表无限小和无限大:

返回指定分数范围成员个数

zcount key min max

删除指定排名内的升序元素

zremrangebyrank key start end

删除指定分数范围的成员

zremrangebyscore key min max

8.1.2集合间的操作

交集

zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]

  • 这个命令参数较多,下面分别进行说明:
    • destination:交集计算结果保存到这个键。
    • numkeys:需要做交集计算键的个数。
    • key[key...]:需要做交集计算的键。
    • weights weight[weight...]:每个键的权重,在做交集计算时,每个键中 的每个member会将自己分数乘以这个权重,每个键的权重默认是1。
    • aggregate sum|min|max:计算成员交集后,分值可以按照sum(和)、 min(最小值)、max(最大值)做汇总,默认值是sum。

并集

zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]

该命令的所有参数和zinterstore是一致的,只不过是做并集计算,

8.2 内部编码

·ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplistentries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist 可以有效减少内存的使用。

·skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作 为内部实现,因为此时ziplist的读写效率会下降。

9. 键管理

本节将按照单个键遍历键数据库管理三个维度对一些通用命令进行介绍。

9.1 单个键管理

键重命名

rename key newkey

为了防止被强行rename,Redis提供了renamenx命令,确保只有newKey 不存在时候才被覆盖,

  • 在使用重命名命令时,有两点需要注意:
    • 由于重命名键期间会执行del命令删除旧的键,如果键对应的值比较大,会存在阻塞Redis的可能性,这点不要忽视。
    • 如果rename和renamenx中的key和newkey如果是相同的,在Redis3.2和之 前版本返回结果略有不同。Redis3.2中会返回OK:Redis3.2之前的版本会提示错误:

.随机返回一个键

randomkey

键过期

expire key seconds:键在seconds秒后过期

expireat key timestamp:键在秒级时间戳timestamp后过期。

pexpire key milliseconds:键在milliseconds毫秒后过期。

pexpireat key milliseconds-timestamp键在毫秒级时间戳timestamp后过期。

ttl命令和pttl都可以查询键的剩余过期时间,但是pttl精度更高可以达到毫秒级别,

  • 有3种返回值:
    • 大于等于0的整数:键剩余的过期时间(ttl是秒,pttl是毫秒)。
    • -1:键没有设置过期时间。
    • -2:键不存在。
  • 在使用Redis相关过期命令时,需要注意以下几点。
    • 如果expire key的键不存在,返回结果为0:
    • 如果过期时间为负值,键会立即被删除,犹如使用del命令一样:
    • persist命令可以将键的过期时间清除:
    • 对于字符串类型键,执行set命令会去掉过期时间:
    • Redis不支持二级数据结构(例如哈希、列表)内部元素的过期功 能,例如不能对列表类型的一个元素做过期时间设置。
    • setex命令作为set+expire的组合,不但是原子执行,同时减少了一次 网络通讯的时间。

迁移键

Redis发展历程中提 供了move、dump+restore、migrate三组迁移键的方法,它们的实现方式以及 使用的场景不太相同,下面分别介绍。

move

move key db

dump+restore

dump key

restore key ttl value

  • dump+restore可以实现在不同的Redis实例之间进行数据迁移的功能,整 个迁移的过程分为两步:
    • 在源Redis上,dump命令会将键值序列化,格式采用的是RDB格式。
    • 在目标Redis上,restore命令将上面序列化的值进行复原,其中ttl参数代表过期时间,如果ttl=0代表没有过期时间。
  • 有关dump+restore有两点需要注意:
    • 第一,整个迁移过程并非原子性 的,而是通过客户端分步完成的。
    • 第二,迁移过程是开启了两个客户端连 接,所以dump的结果不是在源Redis和目标Redis之间进行传输。

migrate

migrate host port key|"" destination-db timeout [copy] [replace] [keys key [key

migrate命令也是用于在Redis实例间进行数据迁移的,实际上migrate命令就是将dump、restore、del三个命令进行组合,从而简化了操作流程。 migrate命令具有原子性,而且从Redis3.0.6版本以后已经支持迁移多个键的 功能,有效地提高了迁移效率

  • 下面对migrate的参数进行逐个说明:
    • host:目标Redis的IP地址。
    • port:目标Redis的端口。
    • key|"":在Redis3.0.6版本之前,migrate只支持迁移一个键,所以此处是 要迁移的键,但Redis3.0.6版本之后支持迁移多个键,如果当前需要迁移多 个键,此处为空字符串""。
    • destination-db:目标Redis的数据库索引。
    • ·timeout:迁移的超时时间(单位为毫秒)。
    • ·[copy]:如果添加此选项,迁移后并不删除源键。
    • [replace]:如果添加此选项,migrate不管目标Redis是否存在该键都会正常迁移进行数据覆盖。
    • ·[keys key[key...]]:迁移多个键,例如要迁移key1、key2、key3,此处填 写“keys key1 key2 key3”。

下面用示例演示migrate命令,为了方便演示源Redis使用6379端口,目 标Redis使用6380端口,现要将源Redis的键hello迁移到目标Redis中,会分为 如下几种情况:

源Redis有键hello,目标Redis没有:

migrate 127.0.0.1 6380 hello 0 1000

源Redis和目标Redis都有键hello:

如果migrate命令没有加replace选项会收到错误提示,如果加了replace会 返回OK表明迁移成功:

migrate 127.0.0.1 6379 hello 0 1000

migrate 127.0.0.1 6379 hello 0 1000 replace

源Redis没有键hello。如下所示,此种情况会收到nokey的提示:

migrate 127.0.0.1 6380 hello 0 1000

源Redis批量添加多个键:

mset key1 value1 key2 value2 key3 value3

源Redis执行如下命令完成多个键的迁移:

migrate 127.0.0.1 6380 "" 0 5000 keys key1 key2 key3

9.2 遍历键

全量遍历键

keys pattern

实际上keys命令是支持pattern匹配的,

  • 通配符:
    • *代表匹配任意字符
    • ·代表匹配一个字符。
    • ·[]代表匹配部分字符,例如[1,3]代表匹配1,3,[1-10]代表匹配1到10 的任意数字。
    • \x用来做转义,例如要匹配星号、问号需要进行转义。

渐进式遍历

scan cursor [match pattern] [count number]

  • cursor是必需参数,实际上cursor是一个游标,第一次遍历从0开始,每 次scan遍历完都会返回当前游标的值,直到游标值为0,表示遍历结束。
  • match pattern是可选参数,它的作用的是做模式的匹配,这点和keys的 模式匹配很像。
  • ·count number是可选参数,它的作用是表明每次要遍历的键个数,默认 值是10,此参数可以适当增大。

除了scan以外,Redis提供了面向哈希类型、集合类型、有序集合的扫 描遍历命令,解决诸如hgetall、smembers、zrange可能产生的阻塞问题,对 应的命令分别是hscan、sscan、zscan,它们的用法和scan基本类似,

9.3数据库管理

Redis提供了几个面向Redis数据库的操作,它们分别是dbsize、select、 flushdb/flushall命令,本节将通过具体的使用场景介绍这些命令。

切换数据库

select dbIndex

Redis只是用数 字作为多个数据库的实现。Redis默认配置中是有16个数据库:

清除数据库

.flushdb/flushall

两者的区别的是flushdb只清除当 前数据库,flushall会清除所有数据库。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值