Options
All
  • Public
  • Public/Protected
  • All
Menu

Class RedisGenericClient

Hierarchy

Index

Constructors

constructor

Connection Methods

echo

  • echo(message: string): Promise<string>
  • 直接返回 msg 本身。

    例子:

    await client.echo('Hello World!')
    // "Hello World!"
    

    Parameters

    • message: string

    Returns Promise<string>

ping

  • ping(msg?: string): Promise<string>
  • 如果没有提供参数返回 PONG。否则返回 msg 本身。

    例子:

    await client.ping()
    // "PONG"
    await client.ping('Hello World!')
    // "Hello World!"
    

    Parameters

    • Optional msg: string

      需要发送的信息,

    Returns Promise<string>

quit

  • quit(): Promise<"OK">
  • 请求 Redis server 关闭连接。

    • Redis Server 会在前面的命令都处理完后立刻关闭连接。

    始终返回 OK。

    Returns Promise<"OK">

select

  • select(db: number): Promise<string>
    • 起始版本:1.0.0

    选择从 0 开始计数的 Redis 逻辑数据库。

    Redis 的可选数据库是一种命名空间格式。所有的数据仍然存在相同的 RDB / AOF 文件中。不同的数据库可以有相同的 key。
    FLUSHDB [[RedisClient.swapdb | SWAPDB]] RANDOMKEY 可以在指定的数据库工作。

    Parameters

    • db: number

    Returns Promise<string>

    查看原始定义

Generic Methods

copy

  • copy(source: string | Buffer, destination: string | Buffer): Promise<0 | 1>
  • copy(source: string | Buffer, destination: string | Buffer, db: number): Promise<0 | 1>
  • copy(source: string | Buffer, destination: string | Buffer, replace: boolean): Promise<0 | 1>
  • copy(source: string | Buffer, destination: string | Buffer, db: number, replace: boolean): Promise<0 | 1>
    • Redis官方文档https://redis.io/commands/copy
    • 起始版本:6.2.0
    • 时间复杂度:对于 string 类型是 O(1), 对于集合类型的值为 O(N), N 为嵌套元素个数。

    将 source 的值复制到 destination。

    默认情况下,destination 会创建在连接当前所持有的逻辑 database 上。通过 db 选项,可以指定需要创建在哪个逻辑 database。

    当 destination 已经存在的情况下,COPY 命令会返回一个错误。可以通过 replace 选项移除原来的 destination。

    返回值

    • 0 复制失败。
    • 1 复制成功。

    例子:

    await client.set('dolly', 'sheep')
    // "OK"
    await client.copy('dolly', 'clone')
    // 1
    await client.get('clone')
    // "sheep"
    

    Parameters

    • source: string | Buffer
    • destination: string | Buffer

    Returns Promise<0 | 1>

    • Redis官方文档https://redis.io/commands/copy
    • 起始版本:6.2.0
    • 时间复杂度:对于 string 类型是 O(1), 对于集合类型的值为 O(N), N 为嵌套元素个数。

    将 source 的值复制到 destination。

    默认情况下,destination 会创建在连接当前所持有的逻辑 database 上。通过 db 选项,可以指定需要创建在哪个逻辑 database。

    当 destination 已经存在的情况下,COPY 命令会返回一个错误。可以通过 replace 选项移除原来的 destination。

    返回值

    • 0 复制失败。
    • 1 复制成功。

    例子:

    await client.set('dolly', 'sheep')
    // "OK"
    await client.copy('dolly', 'clone')
    // 1
    await client.get('clone')
    // "sheep"
    

    Parameters

    • source: string | Buffer
    • destination: string | Buffer
    • db: number

      默认将 destination 创建在当前 db,如果需要更换 db 可以使用此选项。

    Returns Promise<0 | 1>

    • Redis官方文档https://redis.io/commands/copy
    • 起始版本:6.2.0
    • 时间复杂度:对于 string 类型是 O(1), 对于集合类型的值为 O(N), N 为嵌套元素个数。

    将 source 的值复制到 destination。

    默认情况下,destination 会创建在连接当前所持有的逻辑 database 上。通过 db 选项,可以指定需要创建在哪个逻辑 database。

    当 destination 已经存在的情况下,COPY 命令会返回一个错误。可以通过 replace 选项移除原来的 destination。

    返回值

    • 0 复制失败。
    • 1 复制成功。

    例子:

    await client.set('dolly', 'sheep')
    // "OK"
    await client.copy('dolly', 'clone')
    // 1
    await client.get('clone')
    // "sheep"
    

    Parameters

    • source: string | Buffer
    • destination: string | Buffer
    • replace: boolean

      是否添加 REPLACE 标签。

    Returns Promise<0 | 1>

    • Redis官方文档https://redis.io/commands/copy
    • 起始版本:6.2.0
    • 时间复杂度:对于 string 类型是 O(1), 对于集合类型的值为 O(N), N 为嵌套元素个数。

    将 source 的值复制到 destination。

    默认情况下,destination 会创建在连接当前所持有的逻辑 database 上。通过 db 选项,可以指定需要创建在哪个逻辑 database。

    当 destination 已经存在的情况下,COPY 命令会返回一个错误。可以通过 replace 选项移除原来的 destination。

    返回值

    • 0 复制失败。
    • 1 复制成功。

    例子:

    await client.set('dolly', 'sheep')
    // "OK"
    await client.copy('dolly', 'clone')
    // 1
    await client.get('clone')
    // "sheep"
    

    Parameters

    • source: string | Buffer
    • destination: string | Buffer
    • db: number

      默认将 destination 创建在当前 db,如果需要更换 db 可以使用此选项。

    • replace: boolean

      是否添加 REPLACE 标签。

    Returns Promise<0 | 1>

del

  • del(...keys: [string | Buffer, ...(string | Buffer)[]]): Promise<number>
  • 从当前 db 删除 key,不存在的 key 会被忽略。

    返回值

    返回删除的成员数,不包括不存在的 key。

    例子:

    await client.set('key1', 'Hello')
    // "OK"
    await client.set('key2', 'World')
    // "OK"
    await client.del('key1', 'key2', 'nonexists')
    // 2
    

    Parameters

    • Rest ...keys: [string | Buffer, ...(string | Buffer)[]]

      需要删除的 key 列表。

    Returns Promise<number>

dump

  • dump(key: string | Buffer): Promise<Buffer>
    • Redis官方文档https://redis.io/commands/dump
    • 起始版本:2.6.0
    • 时间复杂度:访问 key 为 O(1), 之后需要额外的 O(N * M) 进行序列化。N 为 组成该值的 Redis 对象数量,M 为他们的平均大小。对于小的 string 类型的值,时间复杂度为 O(1) + O(1 * M),而 M 又很小,可以简化为 O(1)。

    序列化导出 key 处的值。当 key 不存在返回 null。
    可以使用 RESTORE 命令可以进行反序列化并存储。

    Redis 采用了一种非标准不透明的序列化方式,它的语义上有一些特点,如下

    • 带有 64 位校验和,用于检测错误。 RESTORE 反序列化之前会先进行校验。
    • 值的编码格式和 RDB 保持一致。
    • RDB 版本会被编码在序列化值当中,如果因为 Redis 的版本不同造成 RDB 格式不兼容,那么 Redis 会拒绝对这个值进行反序列化。

    序列化的值不包含任何 TTL 信息。

    返回值

    序列化后的结果,可能无法编码为字符串,所以直接返回 Buffer。对于不存在的 key 返回 null。

    例子:

    await client.set('mykey', '10')
    // "OK"
    await client.dump('mykey')
    // <Buffer 00 c0 0a 09 00 be 6d 06 89 5a 28 00 0a>
    

    Parameters

    • key: string | Buffer

    Returns Promise<Buffer>

exists

  • exists(...keys: [string | Buffer, ...(string | Buffer)[]]): Promise<number>
  • 判断 key 是否存在

    3.0.3 版本开始可以传递多个 key。此时会返回存在的 key 的个数。 因为对于单个 key 的使用场景,1 表示存在一个 key,所以这个改动是完全向后兼容的。

    注意:如果在参数中有重复的 key 并且这个 key 是存在的,那么最终计数会对这个 key 统计多次。

    返回值

    • 1:当 key 存在。
    • 0:当 key 不存在。
    • 3.0.3 版本开始,返回存在的 key 的个数。

    例子:

    await client.set('key1', 'Hello')
    // "OK"
    await client.exists('key1')
    // 1
    await client.exists('nosuchkey')
    // 0
    await client.set('key2', 'World')
    // "OK"
    await client.exists('key1', 'key2', 'nosuchkey')
    // 2
    await client.exists('key1', 'key1', 'key1')
    // 3
    

    Parameters

    • Rest ...keys: [string | Buffer, ...(string | Buffer)[]]

      需要检查的 key。3.0.3 版本开始支持传递多个 key。

    Returns Promise<number>

expire

  • expire(key: string | Buffer, ttl: number): Promise<0 | 1>
  • 对 key 设置一个过期时间。当 key 到期后会被自动删除。

    在 Redis 术语中,这种带有过期时间的 key 被称为 volatile 的 key。

    在执行重写 key 值的命令的时候,比如 DELSETGETSET 和 *STORE 的命令,会清除过期时间。
    这意味着所有在概念上更改存储在 key 上的值而不是用新 key 替换旧 key 的操作都将保持过期时间不变。
    例如:INCRLPUSHHSET

    可以使用 PERSIST 命令清除过期时间。

    如果通过 RENAME 命令进行重命名,则旧 key 的过期时间会被赋给新的 key。
    此时如果新的 key 已经存在,则它的过期时间会被旧的 key 覆盖。

    注意:使用一个负数参数调用 EXPIRE/PEXPIRE 命令时,实际执行的是删除操作。此时收到的 key event 是删除,而不是过期。

    刷新过期时间

    EXPIRE 命令可以作用于一进存在过期时间的 key。此时会用新的过期时间覆盖旧的。
    一个常见的例子是【导航会话】模式。

    2.1.3 版本差异

    2.1.3 版本之前,修改一个带有过期时间的 key 会导致这个 key 被删除,这是受当时复制层的限制而导致的。而这一限制已经被修复,所以 2.1.3 版本开始可以修改带有过期时间的 key。

    返回值

    • 1:ttl 设置成功。
    • 0:key 不存在,或者不能设置过期时间时。

    例子:

    await client.set('mykey', 'Hello')
    // "OK"
    await client.expire('mykey', 10)
    // 1
    await client.ttl('mykey')
    // 10
    await client.set('mykey', 'Hello World')
    // "OK"
    await client.ttl('mykey')
    // -1
    

    Parameters

    • key: string | Buffer
    • ttl: number

      需要设置的超时时间。

    Returns Promise<0 | 1>

expireat

  • expireat(key: string | Buffer, timestamp: number): Promise<0 | 1>
  • EXPIREAT 的行为和语义跟 EXPIRE 一样,区别是 EXPIREAT 的超时参数是时间戳形式。

    它使用 UNIX Timestamp(1970年1月1日0时开始的秒数)。
    传递一个过去的时间戳会导致直接删除这个 key。

    关于过期时间的语义详情参考 EXPIRE 命令。

    背景

    EXPIREAT 的引入是为了在 AOF 持久化模式中,将相对过期时间转换为绝对过期时间。当然,它也可以用来直接指定一个 key 的过期时间点。

    返回值

    • 1:ttl 设置成功。
    • 0:key 不存在,或者不能设置过期时间。

    例子:

    await client.set('mykey', 'Hello')
    // "OK"
    await client.exists('mykey')
    // 1
    await client.expireat('mykey', 1293840000)
    // 1
    await client.exists('mykey')
    // 0
    

    Parameters

    • key: string | Buffer
    • timestamp: number

      需要设置的过期时间戳。

    Returns Promise<0 | 1>

keys

  • keys(pattern: string | Buffer): Promise<string[]>
  • keys(pattern: string | Buffer, return_buffer: true): Promise<Buffer[]>
  • 查找匹配 pattern 的 key。

    这个命令的时间复杂度是 O(N),常量部分很小。举个例子,在一般入门级笔记本上,Redis 可以在 40 毫秒的时间内浏览 100 万个 key。

    警告: 这是一个方便调试的命令,当你对一个庞大的库使用这个命令时,会导致性能极其低下。

    支持的 glob 风格 patterns:

    • h?llo 匹配 hello, hallohxllo
    • h*llo 匹配 hlloheeeello
    • h[ae]llo 匹配 hellohallo,但是 hillo 不行。
    • h[^e]llo 匹配 hallohbllo,但是 hello 不行。
    • h[a-b]llo 匹配 hallohbllo

    返回值

    返回匹配 pattern 的字符串数组。

    例子:

    await client.mset({ firstname: 'Jack', lastname: 'Stuntman', age: '35' })
    // "OK"
    await client.keys('*name*')
    // ["lastname", "firstname"]
    await client.keys('a??')
    // ["age"]
    await client.keys('*')
    // ["lastname", "firstname", "age"]
    

    Parameters

    • pattern: string | Buffer

      glob 风格匹配模式。

    Returns Promise<string[]>

  • 查找匹配 pattern 的 key。

    这个命令的时间复杂度是 O(N),常量部分很小。举个例子,在一般入门级笔记本上,Redis 可以在 40 毫秒的时间内浏览 100 万个 key。

    警告: 这是一个方便调试的命令,当你对一个庞大的库使用这个命令时,会导致性能极其低下。

    支持的 glob 风格 patterns:

    • h?llo 匹配 hello, hallohxllo
    • h*llo 匹配 hlloheeeello
    • h[ae]llo 匹配 hellohallo,但是 hillo 不行。
    • h[^e]llo 匹配 hallohbllo,但是 hello 不行。
    • h[a-b]llo 匹配 hallohbllo

    返回值

    返回匹配 pattern 的字符串数组。

    例子:

    await client.mset({ firstname: 'Jack', lastname: 'Stuntman', age: '35' })
    // "OK"
    await client.keys('*name*')
    // ["lastname", "firstname"]
    await client.keys('a??')
    // ["age"]
    await client.keys('*')
    // ["lastname", "firstname", "age"]
    
    category

    Generic

    Parameters

    • pattern: string | Buffer

      glob 风格匹配模式。

    • return_buffer: true

      是否以 Buffer 形式返回结果。

    Returns Promise<Buffer[]>

migrate

  • migrate(host: string, port: number, keys: [string | Buffer, ...(string | Buffer)[]], destination_db: number, timeout: number, options?: MigrateOptions): Promise<"OK" | "NOKEY">
    • Redis官方文档https://redis.io/commands/migrate
    • 起始版本:2.6.0
    • 时间复杂度:该命令实际上在源实例中执行了 DUMP + DEL,之后在目标实例中执行 RESTORE
      这部分的时间复杂度,请参见这些命令的页面。在两个实例之间数据传输的复杂度为O(N)。

    将 key 原子性的传输到目标 Redis 实例,成功后删除源 key。

    在传输 key 的过程中,MIGRATE 命令会阻塞源实例和目标实例,任意时间 key 会存在源实例和目标实例中的一个。除非发生超时错误。

    MIGRATE 内部使用了 DUMP 进行序列化,之后使用 RESTORE 将值同步到目标实例上。
    如果收到了目标实例上执行 RESTORE 命令返回的 "OK",则使用 DEL 删除源值。

    timeout 参数指定了与目标实例交互的最长空闲时间,单位毫秒。这意味着这个命令不是必须在 timeout 时间内执行完,但是传输阻塞时间不能超过 timeout。

    MIGRATE 命令需要执行带有超时限制的 I/O 操作。当 I/O 超时,或者发生了 I/O 异常,操作会被终止。此时可能出现两种情况。

    • key 在两个实例上都有。
    • key 只出现在源实例上。

    超时并不会导致 key 丢失,但是需要检查是否已经存在于目标实例,并采取相应的措施。

    当返回除此之外的其他异常时,MIGRATE 命令保证任何时刻 key 会且只会存在于源或者目标中的一个实例上(除非目标实例中已经存在相同 key)。

    如果指定的一系列 key 在源实例上都不存在,会返回 "NOKEY"。因为正常情况下可能会丢失 key,比如因为到期。所以没有 key 可以传输并不是一个异常。

    通过一次命令迁移多个 key

    在 3.0.6 版本开始增加了批量迁移模式,通过管道批量进行迁移,以节省往返通信及其他间接的消耗。RedisGenericClient.migrate 会自动检测传入的 key 个数,判断是否使用批量迁移模式。

    当启用了批量迁移模式时,只有当没有任何一个 key 可以被迁移时才会返回 NOKEY 状态,否则只要有至少一个 key 可以迁移,就会执行命令。

    历史版本

    >= 3.0.0:添加了 copy 和 replace 选项。
    >= 3.0.6:支持批量迁移模式。
    >= 4.0.7:增加了 auth 选项,可以通过 password 进行认证。
    >= 6.0.0:增加了新的 auth 模式,可以同时提供 username 和 password。

    返回值

    • 成功返回 "OK"
    • 如果没有任何 key 执行了迁移返回 "NOKEY"

    Parameters

    • host: string

      目标实例地址。

    • port: number

      目标实例端口号。

    • keys: [string | Buffer, ...(string | Buffer)[]]

      需要传输的 key 列表,在 3.0.6 以上的版本可以支持多个 key 传输。

    • destination_db: number

      目标实例的数据库。

    • timeout: number

      超时时间,单位毫秒。

    • Optional options: MigrateOptions

      选项

    Returns Promise<"OK" | "NOKEY">

move

  • move(key: string | Buffer, db: number): Promise<0 | 1>
  • 将密钥从当前选定的数据库(请参见[[@link RedisClient.select | SELECT]])移动到指定的目标数据库。

    如果目标数据库中已经存在密钥,或者源数据库中不存在密钥,则它什么都不做。 因此,可以将 MOVE 用作锁定原语。

    返回值

    • 1 key 移动成功。
    • 0 key 没有移动。

    Parameters

    • key: string | Buffer
    • db: number

    Returns Promise<0 | 1>

object

  • object(subcommand: "REFCOUNT", key: string | Buffer): Promise<null | number>
  • object(subcommand: "ENCODING", key: string | Buffer): Promise<null | "raw" | "embstr" | "int" | "ziplist" | "linkedlist" | "intset" | "hashtable" | "skiplist">
  • object(subcommand: "IDLETIME", key: string | Buffer): Promise<null | number>
  • object(subcommand: "FREQ", key: string | Buffer): Promise<null | number>
  • object(subcommand: "HELP"): Promise<string>
  • OBJECT 命令允许检查 Redis 对象的内部形式。这对于调试或者需要了解 key 是否使用了特殊编码来节省空间时特别有用。 将 Redis 用作缓存时,还可以根据 OBJECT 命令的报告实现应用级的密钥回收策略。

    OBJECT 命令支持下列四种子命令:

    • REFCOUNT 返回值的引用数,主要用于调试。

    • ENCODING 返回内部存储值使用的编码形式。

    • IDLETIME 返回指定 key 的空闲(没有读写操作)时间,单位秒。但是此计时器的实际分辨率是 10 秒。未来可能会做改进。 当 maxmemory-policy 设置为 LRU 或者 noeviction 并且设置了
      maxmemory 时,此子命令可用。

    • FREQ 返回 key 对应的对数访问频率计数器。当 maxmemory-policy 设为 LFU 可用。

    • HELP 返回简单的帮助文本。

    对象编码格式

    • string 可以编码为 raw(常规字符串编码),embstr (专门用于保存短字符串)或 int(以64位有符号间隔表示整数的字符串以这种方式编码,以节省空间)。
    • list 可以编码为 ziplistlinkedlist。ziplist 是一种特殊的表示形式,用于节省小 list 的空间。
    • set 可以编码为 intsethashtable。intset 是一种特殊的编码,用于仅由整数组成的小 set
    • hash 可以编码为 ziplisthashtable。ziplist 是用于小 hash 的特殊编码。
    • zset 可以编码为 ziplistskiplist 格式。ziplist 适用于小的 listzset,skiplist 编码则适用于任何大小的 zset

    一旦执行了使 Redis 无法保留节省空间编码的操作,所有特殊编码类型会被自动转换为通用编码类型。

    返回值

    不同的子命令有不同的返回值。详见不同子命令的定义。 当要检查的 object 不存在,会返回 null。

    例子:

    await client.lpush('mylist', 'Hello World')
    // 1
    await client.object('REFCOUNT', 'mylist')
    // 1
    await client.object('ENCODING', 'mylist')
    // "quicklist"
    await client.object('IDLETIME', 'mylist')
    // 0
    

    下面的例子展示了编码是如何变化的:

    await client.set('foo', '1000')
    // "OK"
    await client.object('ENCODING', 'foo')
    // "int"
    await client.append('foo', 'bar')
    // 7
    await client.get('foo')
    // "1000bar"
    await client.object('ENCODING', 'foo')
    // "raw"
    

    调试命令:返回与指定 key 关联的值的引用计数。

    Parameters

    • subcommand: "REFCOUNT"
    • key: string | Buffer

    Returns Promise<null | number>

  • OBJECT 命令允许检查 Redis 对象的内部形式。这对于调试或者需要了解 key 是否使用了特殊编码来节省空间时特别有用。 将 Redis 用作缓存时,还可以根据 OBJECT 命令的报告实现应用级的密钥回收策略。

    OBJECT 命令支持下列四种子命令:

    • REFCOUNT 返回值的引用数,主要用于调试。

    • ENCODING 返回内部存储值使用的编码形式。

    • IDLETIME 返回指定 key 的空闲(没有读写操作)时间,单位秒。但是此计时器的实际分辨率是 10 秒。未来可能会做改进。 当 maxmemory-policy 设置为 LRU 或者 noeviction 并且设置了
      maxmemory 时,此子命令可用。

    • FREQ 返回 key 对应的对数访问频率计数器。当 maxmemory-policy 设为 LFU 可用。

    • HELP 返回简单的帮助文本。

    对象编码格式

    • string 可以编码为 raw(常规字符串编码),embstr (专门用于保存短字符串)或 int(以64位有符号间隔表示整数的字符串以这种方式编码,以节省空间)。
    • list 可以编码为 ziplistlinkedlist。ziplist 是一种特殊的表示形式,用于节省小 list 的空间。
    • set 可以编码为 intsethashtable。intset 是一种特殊的编码,用于仅由整数组成的小 set
    • hash 可以编码为 ziplisthashtable。ziplist 是用于小 hash 的特殊编码。
    • zset 可以编码为 ziplistskiplist 格式。ziplist 适用于小的 listzset,skiplist 编码则适用于任何大小的 zset

    一旦执行了使 Redis 无法保留节省空间编码的操作,所有特殊编码类型会被自动转换为通用编码类型。

    返回值

    不同的子命令有不同的返回值。详见不同子命令的定义。 当要检查的 object 不存在,会返回 null。

    例子:

    await client.lpush('mylist', 'Hello World')
    // 1
    await client.object('REFCOUNT', 'mylist')
    // 1
    await client.object('ENCODING', 'mylist')
    // "quicklist"
    await client.object('IDLETIME', 'mylist')
    // 0
    

    下面的例子展示了编码是如何变化的:

    await client.set('foo', '1000')
    // "OK"
    await client.object('ENCODING', 'foo')
    // "int"
    await client.append('foo', 'bar')
    // 7
    await client.get('foo')
    // "1000bar"
    await client.object('ENCODING', 'foo')
    // "raw"
    

    返回用于存储与键关联的值的内部表示形式的类型。

    Parameters

    • subcommand: "ENCODING"
    • key: string | Buffer

    Returns Promise<null | "raw" | "embstr" | "int" | "ziplist" | "linkedlist" | "intset" | "hashtable" | "skiplist">

  • OBJECT 命令允许检查 Redis 对象的内部形式。这对于调试或者需要了解 key 是否使用了特殊编码来节省空间时特别有用。 将 Redis 用作缓存时,还可以根据 OBJECT 命令的报告实现应用级的密钥回收策略。

    OBJECT 命令支持下列四种子命令:

    • REFCOUNT 返回值的引用数,主要用于调试。

    • ENCODING 返回内部存储值使用的编码形式。

    • IDLETIME 返回指定 key 的空闲(没有读写操作)时间,单位秒。但是此计时器的实际分辨率是 10 秒。未来可能会做改进。 当 maxmemory-policy 设置为 LRU 或者 noeviction 并且设置了
      maxmemory 时,此子命令可用。

    • FREQ 返回 key 对应的对数访问频率计数器。当 maxmemory-policy 设为 LFU 可用。

    • HELP 返回简单的帮助文本。

    对象编码格式

    • string 可以编码为 raw(常规字符串编码),embstr (专门用于保存短字符串)或 int(以64位有符号间隔表示整数的字符串以这种方式编码,以节省空间)。
    • list 可以编码为 ziplistlinkedlist。ziplist 是一种特殊的表示形式,用于节省小 list 的空间。
    • set 可以编码为 intsethashtable。intset 是一种特殊的编码,用于仅由整数组成的小 set
    • hash 可以编码为 ziplisthashtable。ziplist 是用于小 hash 的特殊编码。
    • zset 可以编码为 ziplistskiplist 格式。ziplist 适用于小的 listzset,skiplist 编码则适用于任何大小的 zset

    一旦执行了使 Redis 无法保留节省空间编码的操作,所有特殊编码类型会被自动转换为通用编码类型。

    返回值

    不同的子命令有不同的返回值。详见不同子命令的定义。 当要检查的 object 不存在,会返回 null。

    例子:

    await client.lpush('mylist', 'Hello World')
    // 1
    await client.object('REFCOUNT', 'mylist')
    // 1
    await client.object('ENCODING', 'mylist')
    // "quicklist"
    await client.object('IDLETIME', 'mylist')
    // 0
    

    下面的例子展示了编码是如何变化的:

    await client.set('foo', '1000')
    // "OK"
    await client.object('ENCODING', 'foo')
    // "int"
    await client.append('foo', 'bar')
    // 7
    await client.get('foo')
    // "1000bar"
    await client.object('ENCODING', 'foo')
    // "raw"
    

    返回指定 key 处的对象自存储以来处于空闲状态的秒数(读或写操作未请求)。
    虽然以秒为单位返回该值,但此计时器的实际分辨率为 10 秒,这在将来的实现中可能会有所不同。
    当 maxmemory-policy 设置为 LRU 策略或 noeviction 并且设置了 maxmemory 时,此子命令可用。

    Parameters

    • subcommand: "IDLETIME"
    • key: string | Buffer

    Returns Promise<null | number>

  • OBJECT 命令允许检查 Redis 对象的内部形式。这对于调试或者需要了解 key 是否使用了特殊编码来节省空间时特别有用。 将 Redis 用作缓存时,还可以根据 OBJECT 命令的报告实现应用级的密钥回收策略。

    OBJECT 命令支持下列四种子命令:

    • REFCOUNT 返回值的引用数,主要用于调试。

    • ENCODING 返回内部存储值使用的编码形式。

    • IDLETIME 返回指定 key 的空闲(没有读写操作)时间,单位秒。但是此计时器的实际分辨率是 10 秒。未来可能会做改进。 当 maxmemory-policy 设置为 LRU 或者 noeviction 并且设置了
      maxmemory 时,此子命令可用。

    • FREQ 返回 key 对应的对数访问频率计数器。当 maxmemory-policy 设为 LFU 可用。

    • HELP 返回简单的帮助文本。

    对象编码格式

    • string 可以编码为 raw(常规字符串编码),embstr (专门用于保存短字符串)或 int(以64位有符号间隔表示整数的字符串以这种方式编码,以节省空间)。
    • list 可以编码为 ziplistlinkedlist。ziplist 是一种特殊的表示形式,用于节省小 list 的空间。
    • set 可以编码为 intsethashtable。intset 是一种特殊的编码,用于仅由整数组成的小 set
    • hash 可以编码为 ziplisthashtable。ziplist 是用于小 hash 的特殊编码。
    • zset 可以编码为 ziplistskiplist 格式。ziplist 适用于小的 listzset,skiplist 编码则适用于任何大小的 zset

    一旦执行了使 Redis 无法保留节省空间编码的操作,所有特殊编码类型会被自动转换为通用编码类型。

    返回值

    不同的子命令有不同的返回值。详见不同子命令的定义。 当要检查的 object 不存在,会返回 null。

    例子:

    await client.lpush('mylist', 'Hello World')
    // 1
    await client.object('REFCOUNT', 'mylist')
    // 1
    await client.object('ENCODING', 'mylist')
    // "quicklist"
    await client.object('IDLETIME', 'mylist')
    // 0
    

    下面的例子展示了编码是如何变化的:

    await client.set('foo', '1000')
    // "OK"
    await client.object('ENCODING', 'foo')
    // "int"
    await client.append('foo', 'bar')
    // 7
    await client.get('foo')
    // "1000bar"
    await client.object('ENCODING', 'foo')
    // "raw"
    

    返回存储在指定键处的对象的对数访问频率计数器。
    当 maxmemory-policy 设置为 LFU 策略时,此子命令可用。

    Parameters

    • subcommand: "FREQ"
    • key: string | Buffer

    Returns Promise<null | number>

  • OBJECT 命令允许检查 Redis 对象的内部形式。这对于调试或者需要了解 key 是否使用了特殊编码来节省空间时特别有用。 将 Redis 用作缓存时,还可以根据 OBJECT 命令的报告实现应用级的密钥回收策略。

    OBJECT 命令支持下列四种子命令:

    • REFCOUNT 返回值的引用数,主要用于调试。

    • ENCODING 返回内部存储值使用的编码形式。

    • IDLETIME 返回指定 key 的空闲(没有读写操作)时间,单位秒。但是此计时器的实际分辨率是 10 秒。未来可能会做改进。 当 maxmemory-policy 设置为 LRU 或者 noeviction 并且设置了
      maxmemory 时,此子命令可用。

    • FREQ 返回 key 对应的对数访问频率计数器。当 maxmemory-policy 设为 LFU 可用。

    • HELP 返回简单的帮助文本。

    对象编码格式

    • string 可以编码为 raw(常规字符串编码),embstr (专门用于保存短字符串)或 int(以64位有符号间隔表示整数的字符串以这种方式编码,以节省空间)。
    • list 可以编码为 ziplistlinkedlist。ziplist 是一种特殊的表示形式,用于节省小 list 的空间。
    • set 可以编码为 intsethashtable。intset 是一种特殊的编码,用于仅由整数组成的小 set
    • hash 可以编码为 ziplisthashtable。ziplist 是用于小 hash 的特殊编码。
    • zset 可以编码为 ziplistskiplist 格式。ziplist 适用于小的 listzset,skiplist 编码则适用于任何大小的 zset

    一旦执行了使 Redis 无法保留节省空间编码的操作,所有特殊编码类型会被自动转换为通用编码类型。

    返回值

    不同的子命令有不同的返回值。详见不同子命令的定义。 当要检查的 object 不存在,会返回 null。

    例子:

    await client.lpush('mylist', 'Hello World')
    // 1
    await client.object('REFCOUNT', 'mylist')
    // 1
    await client.object('ENCODING', 'mylist')
    // "quicklist"
    await client.object('IDLETIME', 'mylist')
    // 0
    

    下面的例子展示了编码是如何变化的:

    await client.set('foo', '1000')
    // "OK"
    await client.object('ENCODING', 'foo')
    // "int"
    await client.append('foo', 'bar')
    // 7
    await client.get('foo')
    // "1000bar"
    await client.object('ENCODING', 'foo')
    // "raw"
    

    返回 OBJECT 命令的一个简洁说明。

    Parameters

    • subcommand: "HELP"

    Returns Promise<string>

persist

  • persist(key: string | Buffer): Promise<0 | 1>
  • 移除存在于 key 上的过期时间,将 key 从 volatile 变成 persistent。

    返回值

    • 1 成功清除 ttl。
    • 0 当 key 不存在或存在但未设置 ttl。

    例子:

    await client.set('mykey', 'Hello')
    // "OK"
    await client.expire('mykey', 10)
    // 1
    await client.ttl('mykey')
    // 10
    await client.persist('mykey')
    // 1
    await client.ttl('mykey')
    // -1
    

    Parameters

    • key: string | Buffer

    Returns Promise<0 | 1>

pexpire

  • pexpire(key: string | Buffer, ttl: number): Promise<0 | 1>
  • 效果和 EXPIRE 一样,区别是 PEXPIRE 的 ttl 是毫秒单位。

    返回值含义:

    • 1 ttl 设置成功。
    • 0 key 不存在,设置失败。

    例子:

    await client.set('mykey', 'Hello')
    // "OK"
    await client.pexpire('mykey', 1500)
    // 1
    await client.ttl('mykey')
    // 1
    await client.pttl('mykey')
    // 1411
    

    Parameters

    • key: string | Buffer
    • ttl: number

      需要设置的超时时间,单位毫秒。

    Returns Promise<0 | 1>

pexpireat

  • pexpireat(key: string | Buffer, timestamp: number): Promise<0 | 1>
  • 效果和 EXPIREAT 一样,区别是 PEXPIREAT 的到期时间戳是毫秒单位的。

    返回值含义:

    • 1 ttl 设置成功。
    • 0 key 不存在,设置失败。

    例子:

    await client.set('mykey', 'Hello')
    // "OK"
    await client.pexpireat('mykey', 1555555555005)
    // 1
    await client.ttl('mykey')
    // -2
    await client.pttl('mykey')
    // -2
    

    Parameters

    • key: string | Buffer
    • timestamp: number

      需要设置的过期时间戳,单位毫秒。

    Returns Promise<0 | 1>

pttl

  • pttl(key: string | Buffer): Promise<number>
  • TTL 命令一样,返回剩余有效时间。唯一区别是,PTTL 使用毫秒级时间戳。

    2.6 及更早的版本中,key 不存在或者未设置过期时间,都会返回 -1。
    从 2.8 版本开始:

    • 当 key 不存在时,返回 -2。
    • 当 key 存在但是没有设置过期时间,返回 -1。

    例子:

    await client.set('mykey', 'Hello')
    // "OK"
    await client.expire('mykey', 1)
    // 1
    await client.pttl('mykey')
    // 957
    

    Parameters

    • key: string | Buffer

    Returns Promise<number>

randomkey

  • randomkey(): Promise<null | string | Buffer>

rename

  • rename(key: string | Buffer, newkey: string | Buffer): Promise<"OK">
  • 重命名 key 到 newkey。当 key 不存在时抛出异常。

    • 如果 newkey 已经存在,则会对其进行重写。
    • 由于 RENAME 的执行包含隐式的 DEL 操作。所以尽管 RENAME 的耗时通常是常量的,但如果需要删除的值很大,也会引起很高的延迟。

    在集群模式中,key 和 newkey 都必须在同一个 hash slot 中,这意味着在集群中,具有相同的 hash tag 的的 key 才能被可靠的重命名。

    历史版本

    <= 3.2.0:如果 key 和 newkey 相同,会抛出异常。

    例子:

    await client.set('mykey', 'Hello')
    // "OK"
    await client.rename('mykey', 'myotherkey')
    // "OK"
    await client.get('myotherkey')
    // "Hello"
    

    Parameters

    • key: string | Buffer
    • newkey: string | Buffer

    Returns Promise<"OK">

renamenx

  • renamenx(key: string | Buffer, newkey: string | Buffer): Promise<0 | 1>
  • 当 newkey 不存在时重命名 key 到 newkey。当 key 不存在时抛出异常。

    在集群模式中,key 和 newkey 都必须在同一个 hash slot 中,这意味着在集群中,具有相同的 hash tag 的的 key 才能被可靠的重命名。

    历史版本

    <= 3.2.0:如果 key 和 newkey 相同,会抛出异常。

    返回值

    • 1 如果重命名成功。
    • 0 如果新的 key 已经存在。

    例子:

    await client.set('mykey', 'Hello')
    // "OK"
    await client.set('myotherkey', 'World')
    // "OK"
    await client.renamenx('mykey', 'myotherkey')
    // 0
    await client.get('myotherkey')
    // "World"
    

    Parameters

    • key: string | Buffer
    • newkey: string | Buffer

    Returns Promise<0 | 1>

restore

  • restore(key: string | Buffer, ttl: number, serialized_value: Buffer, options?: RestoreOptions): Promise<0 | 1>
    • Redis官方文档https://redis.io/commands/restore
    • 起始版本:2.6.0
    • 时间复杂度:O(1) 创建新 key,O(N * M)进行反序列化,其中 N 是组成该值的 Redis 对象的数量,M 是其平均大小。 对于较小的 string 值,时间复杂度为O(1) + O(1 * M),其中 M 很小,可以简单地认为复杂度为 O(1)。 对于 zset,复杂度为 O(N * M * log(N)),因为将值插入排序的集合中的复杂度为 O(log(N))。

    通过反序列化在 key 上创建新值。一般通过 DUMP 得到序列化的值。

    如果 ttl 参数设置为 0,则 key 不会设置过期时间,否则设置为指定的毫秒级过期时间。

    如果设置了 absttl 选项,ttl 参数会被解析为一个毫秒级的 UNIX 时间戳。

    出于驱逐策略的目的,可以使用 idletime 参数和 freq 参数。相关信息参考 OBJECT 命令(需要 Redis 5.0 及以上)。

    可以使用 replace 选项指定是否覆盖已经存在的 key,如果未使用 replace 选项,且 key 已经存在,会返回 Target key name is busy 错误(需要 Redis 3.0 及以上)。

    RESTORE 会检查序列化值的校验和。如果不匹配会抛出异常。

    例子:

    await client.del('mykey')
    // 0
    await client.restore('mykey', 0,  Buffer.from([0x0e, 0x01, 0x11, 0x11, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0xf4, 0x02, 0xf3, 0x02, 0xf2, 0xff, 0x09, 0x00, 0xcb, 0xe7, 0x54, 0x27, 0x45, 0xe3, 0x3b, 0x2a]))
    // "OK"
    await client.type('mykey')
    // "list"
    await client.lrange('mykey', 0, -1)
    // ["3", "2", "1"]
    

    Parameters

    • key: string | Buffer
    • ttl: number
    • serialized_value: Buffer
    • Optional options: RestoreOptions

    Returns Promise<0 | 1>

scan

    • Redis官方文档https://redis.io/commands/scan
    • 起始版本:2.8.0
    • 时间复杂度:每次调用复杂度为 O(1),一次包括足够命令调用使游标回到 0 的完整迭代的复杂度为 O(N)。N 是集合内元素数量。

    SCAN 命令和近似的 SSCANHSCANZSCAN
    命令,是用来迭代集合内元素的。

    • SCAN 用于迭代当前连接持有的 database 内的 key。
    • SSCAN 用于迭代集合(set)内的成员。
    • HSCAN 用于迭代哈希表(hash)内的成员及其值。
    • ZSCAN 用于迭代排序集(zset)内的成员和分数。

    由于这些命令允许增量迭代,每次调用只返回一小部分元素,所以在处理大集合类型时, 这些命令没有像 KEYS
    SMEMBERS 那样长时间阻塞服务的缺点,可以用于生产环境。

    然而不像 SMEMBERS 这样的命令可以提供指定时间点的全部元素,SSCAN
    只对返回的数据提供有限的保证,因为在增量迭代的过程中,集合可能发生改变。

    SCAN,SSCANHSCANZSCAN
    工作的方式十分近似,所以关于这部分文档包含了这四个命令。 另外还有一个显而易见的区别是,SSCANHSCAN
    ZSCAN 的第一个参数始终是这些集合类型对应的 key。SCAN 不需要提供任何 key 的参数,所以它迭代的是这个 database 本身。

    SCAN 的基础用法

    SCAN 是一种基于游标的迭代。这意味着每次调用都会返回新的游标位置用于下次调用。

    当游标设置为 0 时,表示开始一次新的迭代。而当返回的游标也是 0 的时候表示迭代结束。下面是一个 SCAN 的调用例子:

    await client.scan('0')
    // { "cursor": "14", "keys": [
    //     "key:14", "key:6", "key:13", "key:5", "key:2",
    //     "key:18", "key:0",  "key:16", "key:10", "key:17"
    // ] }
    await client.scan('14')
    // { "cursor": "0", "keys": [
    //     "key:7",  "key:8", "key:4",  "key:3", "key:11",
    //     "key:9", "key:19", "key:1", "key:12", "key:15"
    // ] }
    

    在上面的例子中,第一次调用使用 0 作为游标值,表示开始一次迭代。 第二次调用的游标值,使用前一次调用返回的游标值 '14'
    你可以看到 SCAN 的返回值是一个二元组,第一个值是游标,第二个值是这次迭代的返回内容。

    第二次调用时返回的游标是 0,意味着这次迭代已经结束,集合已经被完整遍历过。从使用 0 调用 SCAN 开始,到返回的 cursor 变为 0,这被称为一次完整迭代(full iteration)

    SCAN 的保证

    SCAN 家族的命令可以提供一些列的保证:

    • 如果一个元素在迭代的过程中始终在集合里,则它一定会被返回给用户。
    • 如果一个元素在迭代的过程中始终没有出现在集合里,则它一定不会被返回给用户。

    由于 SCAN 命令仅保存了很少的关联状态(仅限游标),因此具有以下缺点:

    • 给定的元素可能被多次返回。这取决于应用如何处理重复元素,例如只用返回值执行幂等操作。
    • 在完整迭代过程中不是一直出现的元素,不一定会被返回。它的行为是未定义的。

    每次迭代返回的元素个数

    SCAN 家族命令不保证每次调用的返回数量是指定值。命令也可能返回 0 个元素,但只要返回的游标不是 0,客户端就不应该认为迭代结束。

    SCAN 命令返回数量也有一些规则,从实用角度出发,对于一个大型的集合,每次可能只返回几十条数据,而对于一些足够小的集合,可能一次返回全部数据。

    用户可以使用 count 选项调整每次返回元素的数量级。

    count 选项

    尽管 SCAN 不保证每次迭代返回的元素数量,但是可以使用 count 选项根据经验调整 SCAN 的行为。
    基本上 count 指定的是每次调用时从集合中检索元素的工作量。这只是实现方式的一个比喻,但一般情况下,你可以期望它的行为就是这样。

    • 默认的 count 值为 0。
    • 对于哈希类型的数据结构,假设没有使用 match 选项,每次调用服务器一般会返回 count 或者比 count 稍多一些的元素。
    • 当 set 的编码为 intset(又整数组成的小集合)时,或者 hash 和 zset 编码为 ziplist(由个别小型值组成的 hash 或者 zset),不管 count 设置何值,在第一次调用时就会返回全部元素。

    注意不需要为每次调用传递相同的 count 参数。只要每次调用的游标值是从上次一调用结果获得的,调用者可以按需调整 count 值。

    match 选项

    可以使用 glob 风格的模式对 scan 的返回结果进行过滤。它的行为类似于 KEYS

    使用 match 选项可以启用这种过滤模式,SCAN 家族的命令都支持这个选项。

    下面是使用 match 选项的一个例子:

    await client.sadd('myset', '1', '2', '3', 'foo', 'foobar', 'feelsgood')
    // 6
    await client.sscan('myset', '0', { match: 'f*' })
    // { "cursor": "0", "keys": [
    //     "foo", "feelsgood", "foobar"
    // ] }
    

    需要注意的是,match 是在已经获取了元素之后,返回之前进行的过滤。这意味着如果 match 只匹配了集合重很小一部分元素,SCAN 命令可能在大多数的迭代中返回空数组。下面是一个例子:

        const a: string[] = []
        for (let i = 0; i < 1000; i++) {
            a.push('key:' + i)
        }
        await Promise.all(a.map(k => client.set(k, '1')))
        let res: { cursor: string, keys: string[] } | undefined
        while (true) {
            res = await client.scan(res?.cursor ?? 0, { match: '*11*', count: 100 })
            console.log(res)
            if (res.cursor === '0') {
                break
            }
        }
        /**
         * { cursor: '792', keys: [ 'key:611' ] }
         * { cursor: '780', keys: [ 'key:116', 'key:511' ] }
         * { cursor: '914', keys: [ 'key:114', 'key:119', 'key:711' ] }
         * { cursor: '358', keys: [ 'key:112', 'key:411', 'key:118', 'key:211' ] }
         * { cursor: '62', keys: [] }
         * { cursor: '617', keys: [ 'key:110' ] }
         * { cursor: '141', keys: [ 'key:311', 'key:11' ] }
         * { cursor: '179', keys: [ 'key:911', 'key:113', 'key:115' ] }
         * { cursor: '487', keys: [ 'key:111' ] }
         * { cursor: '0', keys: [ 'key:117', 'key:811' ] }
         */
    

    如上所示,在一个 1000 个元素的集合中进行迭代,指定每次迭代的数量大致为 100 个,此时只返回几个 key 甚至还有空的结果。

    type 选项

    在 Redis 6.0 版本开始,你可以使用 type 选项根据值类型进行返回值过滤。type 选项只在 SCAN 命令中生效,因为 SCAN 家族其他命令迭代的值对应的都是固定类型。

    type 参数的可选项跟 TYPE 命令的返回值一样。

    但是请注意,一些 Redis 的值类型实际上的存储类型为几个基本类型,比如 GeoHashs,HyperLogLogs,Bitmaps,Bitfields,他们的实现方式就是其他的内置类型,
    比如 string 或者 zset,所以它们不能通过 type 选项区分。例如 GeoHash 和 zset:

    
    

    type 的过滤时机和 match 选项一样,所以 type 选项同样不能减少服务器遍历集合的工作量,而且对于一些比较少的类型,会得到很多空数组的返回结果。

    多次并行迭代

    同一时间可以有不限个数的客户端同时进行迭代,因为迭代的状态只有游标值,他只是在每次调用和返回时出现,而服务器不保存任何迭代状态。

    中途终止迭代

    鉴于全部迭代信息都保存在游标中,服务端没有保存任何迭代信息,调用者可以随时终止迭代而不需要通知服务端。存在任意数量的未完成迭代不会引起服务端的任何问题。

    使用非法游标调用 SCAN 命令

    使用错误的,超出范围的,负的,或者其他非法的游标会导致未定义的行为,但并不会导致崩溃。未定义的只是所有 SCAN 命令对于返回值的保证不再有效。

    有效的游标:

    • 游标值 '0' 表示迭代开始。
    • 前次调用返回的游标值。

    终止保证

    只有在迭代集合的大小保持在一定范围内时,才能保证 SCAN 算法的终止,否则,对一直增长的集合进行迭代可能会导致 SCAN 算法永不终止。
    这很好理解,随着集合增长,遍历集合需要执行的工作就越来越多,所以能否终止取决于 SCAN 的调用次数和 count 参数跟集合的增长率相比谁大谁小。

    为什么 SCAN 有可能在一次调用中返回聚合数据类型的全部元素

    在前面 count 相关的文档中提到又是在 set,hash,zset 中使用 SCAN 家族命令时可能在单次调用中返回全部元素,而不管 count 设置为多少。
    原因是只有当我们要扫描的聚合数据类型表示为哈希表时,才可以实现基于游标的迭代器。
    然而 Redis 在聚合数据类型比较小的时候使用紧凑型的一次性打包编码方式,这样可以节省内存,直到元素的数量达到一定等级,或者单个元素大小超过限制。
    在这种情况下,Redis 无法返回有效的游标,又必须迭代完整的数据,此时能做的只有将元素全部返回。

    然而一旦数据大小超过限制,改为使用哈希表存储的方式,SCAN 命令就会执行正常的迭代操作。这种特殊的行为仅发生在小型数据类型上,所以它对命令的复杂度没有实际意义的影响。
    转换为真实哈希表的限制是用户可配置的,所以单次调用中返回的最大元素数量实际上取决于打包格式的最大限制大小。
    还有就是,这种特殊的行为只发生在 SSCAN HSCAN ZSCAN 上,SCAN 本身绝不会发生这种行为,因为 database 的 key 始终是以哈希表形式存储的。

    返回值

    Parameters

    • cursor: string | number
    • Optional options: ScanOptions

    Returns Promise<ScanResult<string>>

    • Redis官方文档https://redis.io/commands/scan
    • 起始版本:2.8.0
    • 时间复杂度:每次调用复杂度为 O(1),一次包括足够命令调用使游标回到 0 的完整迭代的复杂度为 O(N)。N 是集合内元素数量。

    SCAN 命令和近似的 SSCANHSCANZSCAN
    命令,是用来迭代集合内元素的。

    • SCAN 用于迭代当前连接持有的 database 内的 key。
    • SSCAN 用于迭代集合(set)内的成员。
    • HSCAN 用于迭代哈希表(hash)内的成员及其值。
    • ZSCAN 用于迭代排序集(zset)内的成员和分数。

    由于这些命令允许增量迭代,每次调用只返回一小部分元素,所以在处理大集合类型时, 这些命令没有像 KEYS
    SMEMBERS 那样长时间阻塞服务的缺点,可以用于生产环境。

    然而不像 SMEMBERS 这样的命令可以提供指定时间点的全部元素,SSCAN
    只对返回的数据提供有限的保证,因为在增量迭代的过程中,集合可能发生改变。

    SCAN,SSCANHSCANZSCAN
    工作的方式十分近似,所以关于这部分文档包含了这四个命令。 另外还有一个显而易见的区别是,SSCANHSCAN
    ZSCAN 的第一个参数始终是这些集合类型对应的 key。SCAN 不需要提供任何 key 的参数,所以它迭代的是这个 database 本身。

    SCAN 的基础用法

    SCAN 是一种基于游标的迭代。这意味着每次调用都会返回新的游标位置用于下次调用。

    当游标设置为 0 时,表示开始一次新的迭代。而当返回的游标也是 0 的时候表示迭代结束。下面是一个 SCAN 的调用例子:

    await client.scan('0')
    // { "cursor": "14", "keys": [
    //     "key:14", "key:6", "key:13", "key:5", "key:2",
    //     "key:18", "key:0",  "key:16", "key:10", "key:17"
    // ] }
    await client.scan('14')
    // { "cursor": "0", "keys": [
    //     "key:7",  "key:8", "key:4",  "key:3", "key:11",
    //     "key:9", "key:19", "key:1", "key:12", "key:15"
    // ] }
    

    在上面的例子中,第一次调用使用 0 作为游标值,表示开始一次迭代。 第二次调用的游标值,使用前一次调用返回的游标值 '14'
    你可以看到 SCAN 的返回值是一个二元组,第一个值是游标,第二个值是这次迭代的返回内容。

    第二次调用时返回的游标是 0,意味着这次迭代已经结束,集合已经被完整遍历过。从使用 0 调用 SCAN 开始,到返回的 cursor 变为 0,这被称为一次完整迭代(full iteration)

    SCAN 的保证

    SCAN 家族的命令可以提供一些列的保证:

    • 如果一个元素在迭代的过程中始终在集合里,则它一定会被返回给用户。
    • 如果一个元素在迭代的过程中始终没有出现在集合里,则它一定不会被返回给用户。

    由于 SCAN 命令仅保存了很少的关联状态(仅限游标),因此具有以下缺点:

    • 给定的元素可能被多次返回。这取决于应用如何处理重复元素,例如只用返回值执行幂等操作。
    • 在完整迭代过程中不是一直出现的元素,不一定会被返回。它的行为是未定义的。

    每次迭代返回的元素个数

    SCAN 家族命令不保证每次调用的返回数量是指定值。命令也可能返回 0 个元素,但只要返回的游标不是 0,客户端就不应该认为迭代结束。

    SCAN 命令返回数量也有一些规则,从实用角度出发,对于一个大型的集合,每次可能只返回几十条数据,而对于一些足够小的集合,可能一次返回全部数据。

    用户可以使用 count 选项调整每次返回元素的数量级。

    count 选项

    尽管 SCAN 不保证每次迭代返回的元素数量,但是可以使用 count 选项根据经验调整 SCAN 的行为。
    基本上 count 指定的是每次调用时从集合中检索元素的工作量。这只是实现方式的一个比喻,但一般情况下,你可以期望它的行为就是这样。

    • 默认的 count 值为 0。
    • 对于哈希类型的数据结构,假设没有使用 match 选项,每次调用服务器一般会返回 count 或者比 count 稍多一些的元素。
    • 当 set 的编码为 intset(又整数组成的小集合)时,或者 hash 和 zset 编码为 ziplist(由个别小型值组成的 hash 或者 zset),不管 count 设置何值,在第一次调用时就会返回全部元素。

    注意不需要为每次调用传递相同的 count 参数。只要每次调用的游标值是从上次一调用结果获得的,调用者可以按需调整 count 值。

    match 选项

    可以使用 glob 风格的模式对 scan 的返回结果进行过滤。它的行为类似于 KEYS

    使用 match 选项可以启用这种过滤模式,SCAN 家族的命令都支持这个选项。

    下面是使用 match 选项的一个例子:

    await client.sadd('myset', '1', '2', '3', 'foo', 'foobar', 'feelsgood')
    // 6
    await client.sscan('myset', '0', { match: 'f*' })
    // { "cursor": "0", "keys": [
    //     "foo", "feelsgood", "foobar"
    // ] }
    

    需要注意的是,match 是在已经获取了元素之后,返回之前进行的过滤。这意味着如果 match 只匹配了集合重很小一部分元素,SCAN 命令可能在大多数的迭代中返回空数组。下面是一个例子:

        const a: string[] = []
        for (let i = 0; i < 1000; i++) {
            a.push('key:' + i)
        }
        await Promise.all(a.map(k => client.set(k, '1')))
        let res: { cursor: string, keys: string[] } | undefined
        while (true) {
            res = await client.scan(res?.cursor ?? 0, { match: '*11*', count: 100 })
            console.log(res)
            if (res.cursor === '0') {
                break
            }
        }
        /**
         * { cursor: '792', keys: [ 'key:611' ] }
         * { cursor: '780', keys: [ 'key:116', 'key:511' ] }
         * { cursor: '914', keys: [ 'key:114', 'key:119', 'key:711' ] }
         * { cursor: '358', keys: [ 'key:112', 'key:411', 'key:118', 'key:211' ] }
         * { cursor: '62', keys: [] }
         * { cursor: '617', keys: [ 'key:110' ] }
         * { cursor: '141', keys: [ 'key:311', 'key:11' ] }
         * { cursor: '179', keys: [ 'key:911', 'key:113', 'key:115' ] }
         * { cursor: '487', keys: [ 'key:111' ] }
         * { cursor: '0', keys: [ 'key:117', 'key:811' ] }
         */
    

    如上所示,在一个 1000 个元素的集合中进行迭代,指定每次迭代的数量大致为 100 个,此时只返回几个 key 甚至还有空的结果。

    type 选项

    在 Redis 6.0 版本开始,你可以使用 type 选项根据值类型进行返回值过滤。type 选项只在 SCAN 命令中生效,因为 SCAN 家族其他命令迭代的值对应的都是固定类型。

    type 参数的可选项跟 TYPE 命令的返回值一样。

    但是请注意,一些 Redis 的值类型实际上的存储类型为几个基本类型,比如 GeoHashs,HyperLogLogs,Bitmaps,Bitfields,他们的实现方式就是其他的内置类型,
    比如 string 或者 zset,所以它们不能通过 type 选项区分。例如 GeoHash 和 zset:

    
    

    type 的过滤时机和 match 选项一样,所以 type 选项同样不能减少服务器遍历集合的工作量,而且对于一些比较少的类型,会得到很多空数组的返回结果。

    多次并行迭代

    同一时间可以有不限个数的客户端同时进行迭代,因为迭代的状态只有游标值,他只是在每次调用和返回时出现,而服务器不保存任何迭代状态。

    中途终止迭代

    鉴于全部迭代信息都保存在游标中,服务端没有保存任何迭代信息,调用者可以随时终止迭代而不需要通知服务端。存在任意数量的未完成迭代不会引起服务端的任何问题。

    使用非法游标调用 SCAN 命令

    使用错误的,超出范围的,负的,或者其他非法的游标会导致未定义的行为,但并不会导致崩溃。未定义的只是所有 SCAN 命令对于返回值的保证不再有效。

    有效的游标:

    • 游标值 '0' 表示迭代开始。
    • 前次调用返回的游标值。

    终止保证

    只有在迭代集合的大小保持在一定范围内时,才能保证 SCAN 算法的终止,否则,对一直增长的集合进行迭代可能会导致 SCAN 算法永不终止。
    这很好理解,随着集合增长,遍历集合需要执行的工作就越来越多,所以能否终止取决于 SCAN 的调用次数和 count 参数跟集合的增长率相比谁大谁小。

    为什么 SCAN 有可能在一次调用中返回聚合数据类型的全部元素

    在前面 count 相关的文档中提到又是在 set,hash,zset 中使用 SCAN 家族命令时可能在单次调用中返回全部元素,而不管 count 设置为多少。
    原因是只有当我们要扫描的聚合数据类型表示为哈希表时,才可以实现基于游标的迭代器。
    然而 Redis 在聚合数据类型比较小的时候使用紧凑型的一次性打包编码方式,这样可以节省内存,直到元素的数量达到一定等级,或者单个元素大小超过限制。
    在这种情况下,Redis 无法返回有效的游标,又必须迭代完整的数据,此时能做的只有将元素全部返回。

    然而一旦数据大小超过限制,改为使用哈希表存储的方式,SCAN 命令就会执行正常的迭代操作。这种特殊的行为仅发生在小型数据类型上,所以它对命令的复杂度没有实际意义的影响。
    转换为真实哈希表的限制是用户可配置的,所以单次调用中返回的最大元素数量实际上取决于打包格式的最大限制大小。
    还有就是,这种特殊的行为只发生在 SSCAN HSCAN ZSCAN 上,SCAN 本身绝不会发生这种行为,因为 database 的 key 始终是以哈希表形式存储的。

    返回值

    category

    Generic

    Parameters

    • cursor: string | number
    • return_buffer: true

      以 Buffer 形式返回结果。

    • Optional options: ScanOptions

    Returns Promise<ScanResult<Buffer>>

sort

  • sort(key: string | Buffer): Promise<string[]>
  • sort(key: string | Buffer, store: string | Buffer): Promise<string[]>
  • sort(key: string | Buffer, options: SortOptions): Promise<string[]>
  • sort(key: string | Buffer, store: string | Buffer, options: SortOptions): Promise<string[]>
    • Redis官方文档https://redis.io/commands/sort
    • 起始版本:1.0.0
    • 时间复杂度:O(N + M * log(M)) 其中 N 是要排序的元素的数量,M 是返回的元素的数量。 如果不对元素进行排序,则当前的复杂度为 O(N),在下一版本中将避免复制步骤。

    返回或者存储集合类型的值的成员排序结果。
    集合类型是值 list set zset 这种包含多个成员的类型。
    默认情况下排序是数字形式的比较,成员名会被解释为一个双精度浮点数。

    假设 mylist 是一个数字列表,此命令将返回与 mylist 相同的列表,从小到大排序。如果需要逆序,可以使用 desc 选项。

    await client.sort('mylist', { desc: true })

    假设 mylist 是一个字符串列表,你需要让他们按照字典序排列,可以使用 alpha 选项。

    await client.sort('mylist', { alpha: true })

    如果你正确设置了 !LC_COLLATE 环境变量,Redis 可以识别 UTF-8 编码。

    通过使用 limit 选项,可以限制返回的成员数量。格式为 limit: [offset, count],offset 表示要跳过的元素个数,count 表示需要返回的元素个数。

    await client.sort('mylist', { limit: [0, 10] })

    上述各个选项可以同时使用,下面的例子表示,按照字典序倒序排列,取前 5 个。

    await client.sort('mylist', { limit: [0, 5], desc: true, alpha: true })

    通过外部键排序

    又是你希望通过外部的 key 的值替代实际成员的值作为权重进行排序。
    比如说列表 mylist 包含了元素 1, 2, 3,代表对象 object_1object_2object_3 的唯一 ID。
    当这些对象的权重存储在 weight_1weight_2weight_3 的时候,SORT 命令可以利用这些权重对 mylist 进行排序。

    await client.sort('mylist', { by: 'weight_*' })

    by 选项接收一个 pattern 格式(在这个例子中是 weight_*),用来生成需要排序的 key。通过将列表中的实际成员值替换,首次出现的 *,得到需要使用的 key。

    跳过排序

    by 选项也可以接受一个不存在的 key,这会导致 SORT 命令跳过排序操作。当你只需要提取外部 key(参考下面的 get 选项),而不需要排序时很有用。

    await client.sort('mylist', { by: 'nosort' })

    获取外部 key

    上一个例子中只是返回了排好序的 ID 列表。在一些场景中,获取实际的对象比只获取 ID 更有用。
    通过使用 get 选项可以修改返回值为外部 key 的值。

    await client.sort('mylist', { by: 'weight_*', get: ['object_*'] })

    get 选项可以包含多组数据。在使用 get 选项的同时如果也需要返回本身的值,可以使用 #

    await client.sort('mylist', { by: 'weight_*', get: ['object_*', '#'] })

    将 sort 的结果存储到其他的 key

    默认情况下,sort 会返回排序结果。使用 store 参数可以将结果存储到指定的 key。

    await client.sort('mylist', 'resultkey', { by: 'weight_*' })

    一个有趣的使用场景是,将排序结果存储到其他 key 之后,设置过期时间。这样就不用对每个请求执行排序了。当过期之后,通过再次调用排序命令生成新的排序结果。

    对 by 和 get 选项使用哈希表

    byget 选项可以指定哈希表的字段。语法如下:

    await client.sort('mylist', { by: 'weight_*->fieldname', get: ['object_*->fieldname'] })

    字符串 -> 用于分割 key 和 hash field。key 的值会如上文所述进行替换,之后获取 hash 中的指定 field。

    返回值

    • 不传递 store 参数,列表形式返回排序结果。
    • 传递 store 参数,返回存储到 destination 的列表长度。

    Parameters

    • key: string | Buffer

    Returns Promise<string[]>

    • Redis官方文档https://redis.io/commands/sort
    • 起始版本:1.0.0
    • 时间复杂度:O(N + M * log(M)) 其中 N 是要排序的元素的数量,M 是返回的元素的数量。 如果不对元素进行排序,则当前的复杂度为 O(N),在下一版本中将避免复制步骤。

    返回或者存储集合类型的值的成员排序结果。
    集合类型是值 list set zset 这种包含多个成员的类型。
    默认情况下排序是数字形式的比较,成员名会被解释为一个双精度浮点数。

    假设 mylist 是一个数字列表,此命令将返回与 mylist 相同的列表,从小到大排序。如果需要逆序,可以使用 desc 选项。

    await client.sort('mylist', { desc: true })

    假设 mylist 是一个字符串列表,你需要让他们按照字典序排列,可以使用 alpha 选项。

    await client.sort('mylist', { alpha: true })

    如果你正确设置了 !LC_COLLATE 环境变量,Redis 可以识别 UTF-8 编码。

    通过使用 limit 选项,可以限制返回的成员数量。格式为 limit: [offset, count],offset 表示要跳过的元素个数,count 表示需要返回的元素个数。

    await client.sort('mylist', { limit: [0, 10] })

    上述各个选项可以同时使用,下面的例子表示,按照字典序倒序排列,取前 5 个。

    await client.sort('mylist', { limit: [0, 5], desc: true, alpha: true })

    通过外部键排序

    又是你希望通过外部的 key 的值替代实际成员的值作为权重进行排序。
    比如说列表 mylist 包含了元素 1, 2, 3,代表对象 object_1object_2object_3 的唯一 ID。
    当这些对象的权重存储在 weight_1weight_2weight_3 的时候,SORT 命令可以利用这些权重对 mylist 进行排序。

    await client.sort('mylist', { by: 'weight_*' })

    by 选项接收一个 pattern 格式(在这个例子中是 weight_*),用来生成需要排序的 key。通过将列表中的实际成员值替换,首次出现的 *,得到需要使用的 key。

    跳过排序

    by 选项也可以接受一个不存在的 key,这会导致 SORT 命令跳过排序操作。当你只需要提取外部 key(参考下面的 get 选项),而不需要排序时很有用。

    await client.sort('mylist', { by: 'nosort' })

    获取外部 key

    上一个例子中只是返回了排好序的 ID 列表。在一些场景中,获取实际的对象比只获取 ID 更有用。
    通过使用 get 选项可以修改返回值为外部 key 的值。

    await client.sort('mylist', { by: 'weight_*', get: ['object_*'] })

    get 选项可以包含多组数据。在使用 get 选项的同时如果也需要返回本身的值,可以使用 #

    await client.sort('mylist', { by: 'weight_*', get: ['object_*', '#'] })

    将 sort 的结果存储到其他的 key

    默认情况下,sort 会返回排序结果。使用 store 参数可以将结果存储到指定的 key。

    await client.sort('mylist', 'resultkey', { by: 'weight_*' })

    一个有趣的使用场景是,将排序结果存储到其他 key 之后,设置过期时间。这样就不用对每个请求执行排序了。当过期之后,通过再次调用排序命令生成新的排序结果。

    对 by 和 get 选项使用哈希表

    byget 选项可以指定哈希表的字段。语法如下:

    await client.sort('mylist', { by: 'weight_*->fieldname', get: ['object_*->fieldname'] })

    字符串 -> 用于分割 key 和 hash field。key 的值会如上文所述进行替换,之后获取 hash 中的指定 field。

    返回值

    • 不传递 store 参数,列表形式返回排序结果。
    • 传递 store 参数,返回存储到 destination 的列表长度。

    Parameters

    • key: string | Buffer
    • store: string | Buffer

      指定 key 用来存储排序结果。当指定的 key 已经存在时,会被覆盖。

    Returns Promise<string[]>

    • Redis官方文档https://redis.io/commands/sort
    • 起始版本:1.0.0
    • 时间复杂度:O(N + M * log(M)) 其中 N 是要排序的元素的数量,M 是返回的元素的数量。 如果不对元素进行排序,则当前的复杂度为 O(N),在下一版本中将避免复制步骤。

    返回或者存储集合类型的值的成员排序结果。
    集合类型是值 list set zset 这种包含多个成员的类型。
    默认情况下排序是数字形式的比较,成员名会被解释为一个双精度浮点数。

    假设 mylist 是一个数字列表,此命令将返回与 mylist 相同的列表,从小到大排序。如果需要逆序,可以使用 desc 选项。

    await client.sort('mylist', { desc: true })

    假设 mylist 是一个字符串列表,你需要让他们按照字典序排列,可以使用 alpha 选项。

    await client.sort('mylist', { alpha: true })

    如果你正确设置了 !LC_COLLATE 环境变量,Redis 可以识别 UTF-8 编码。

    通过使用 limit 选项,可以限制返回的成员数量。格式为 limit: [offset, count],offset 表示要跳过的元素个数,count 表示需要返回的元素个数。

    await client.sort('mylist', { limit: [0, 10] })

    上述各个选项可以同时使用,下面的例子表示,按照字典序倒序排列,取前 5 个。

    await client.sort('mylist', { limit: [0, 5], desc: true, alpha: true })

    通过外部键排序

    又是你希望通过外部的 key 的值替代实际成员的值作为权重进行排序。
    比如说列表 mylist 包含了元素 1, 2, 3,代表对象 object_1object_2object_3 的唯一 ID。
    当这些对象的权重存储在 weight_1weight_2weight_3 的时候,SORT 命令可以利用这些权重对 mylist 进行排序。

    await client.sort('mylist', { by: 'weight_*' })

    by 选项接收一个 pattern 格式(在这个例子中是 weight_*),用来生成需要排序的 key。通过将列表中的实际成员值替换,首次出现的 *,得到需要使用的 key。

    跳过排序

    by 选项也可以接受一个不存在的 key,这会导致 SORT 命令跳过排序操作。当你只需要提取外部 key(参考下面的 get 选项),而不需要排序时很有用。

    await client.sort('mylist', { by: 'nosort' })

    获取外部 key

    上一个例子中只是返回了排好序的 ID 列表。在一些场景中,获取实际的对象比只获取 ID 更有用。
    通过使用 get 选项可以修改返回值为外部 key 的值。

    await client.sort('mylist', { by: 'weight_*', get: ['object_*'] })

    get 选项可以包含多组数据。在使用 get 选项的同时如果也需要返回本身的值,可以使用 #

    await client.sort('mylist', { by: 'weight_*', get: ['object_*', '#'] })

    将 sort 的结果存储到其他的 key

    默认情况下,sort 会返回排序结果。使用 store 参数可以将结果存储到指定的 key。

    await client.sort('mylist', 'resultkey', { by: 'weight_*' })

    一个有趣的使用场景是,将排序结果存储到其他 key 之后,设置过期时间。这样就不用对每个请求执行排序了。当过期之后,通过再次调用排序命令生成新的排序结果。

    对 by 和 get 选项使用哈希表

    byget 选项可以指定哈希表的字段。语法如下:

    await client.sort('mylist', { by: 'weight_*->fieldname', get: ['object_*->fieldname'] })

    字符串 -> 用于分割 key 和 hash field。key 的值会如上文所述进行替换,之后获取 hash 中的指定 field。

    返回值

    • 不传递 store 参数,列表形式返回排序结果。
    • 传递 store 参数,返回存储到 destination 的列表长度。

    Parameters

    Returns Promise<string[]>

    • Redis官方文档https://redis.io/commands/sort
    • 起始版本:1.0.0
    • 时间复杂度:O(N + M * log(M)) 其中 N 是要排序的元素的数量,M 是返回的元素的数量。 如果不对元素进行排序,则当前的复杂度为 O(N),在下一版本中将避免复制步骤。

    返回或者存储集合类型的值的成员排序结果。
    集合类型是值 list set zset 这种包含多个成员的类型。
    默认情况下排序是数字形式的比较,成员名会被解释为一个双精度浮点数。

    假设 mylist 是一个数字列表,此命令将返回与 mylist 相同的列表,从小到大排序。如果需要逆序,可以使用 desc 选项。

    await client.sort('mylist', { desc: true })

    假设 mylist 是一个字符串列表,你需要让他们按照字典序排列,可以使用 alpha 选项。

    await client.sort('mylist', { alpha: true })

    如果你正确设置了 !LC_COLLATE 环境变量,Redis 可以识别 UTF-8 编码。

    通过使用 limit 选项,可以限制返回的成员数量。格式为 limit: [offset, count],offset 表示要跳过的元素个数,count 表示需要返回的元素个数。

    await client.sort('mylist', { limit: [0, 10] })

    上述各个选项可以同时使用,下面的例子表示,按照字典序倒序排列,取前 5 个。

    await client.sort('mylist', { limit: [0, 5], desc: true, alpha: true })

    通过外部键排序

    又是你希望通过外部的 key 的值替代实际成员的值作为权重进行排序。
    比如说列表 mylist 包含了元素 1, 2, 3,代表对象 object_1object_2object_3 的唯一 ID。
    当这些对象的权重存储在 weight_1weight_2weight_3 的时候,SORT 命令可以利用这些权重对 mylist 进行排序。

    await client.sort('mylist', { by: 'weight_*' })

    by 选项接收一个 pattern 格式(在这个例子中是 weight_*),用来生成需要排序的 key。通过将列表中的实际成员值替换,首次出现的 *,得到需要使用的 key。

    跳过排序

    by 选项也可以接受一个不存在的 key,这会导致 SORT 命令跳过排序操作。当你只需要提取外部 key(参考下面的 get 选项),而不需要排序时很有用。

    await client.sort('mylist', { by: 'nosort' })

    获取外部 key

    上一个例子中只是返回了排好序的 ID 列表。在一些场景中,获取实际的对象比只获取 ID 更有用。
    通过使用 get 选项可以修改返回值为外部 key 的值。

    await client.sort('mylist', { by: 'weight_*', get: ['object_*'] })

    get 选项可以包含多组数据。在使用 get 选项的同时如果也需要返回本身的值,可以使用 #

    await client.sort('mylist', { by: 'weight_*', get: ['object_*', '#'] })

    将 sort 的结果存储到其他的 key

    默认情况下,sort 会返回排序结果。使用 store 参数可以将结果存储到指定的 key。

    await client.sort('mylist', 'resultkey', { by: 'weight_*' })

    一个有趣的使用场景是,将排序结果存储到其他 key 之后,设置过期时间。这样就不用对每个请求执行排序了。当过期之后,通过再次调用排序命令生成新的排序结果。

    对 by 和 get 选项使用哈希表

    byget 选项可以指定哈希表的字段。语法如下:

    await client.sort('mylist', { by: 'weight_*->fieldname', get: ['object_*->fieldname'] })

    字符串 -> 用于分割 key 和 hash field。key 的值会如上文所述进行替换,之后获取 hash 中的指定 field。

    返回值

    • 不传递 store 参数,列表形式返回排序结果。
    • 传递 store 参数,返回存储到 destination 的列表长度。

    Parameters

    • key: string | Buffer
    • store: string | Buffer

      指定 key 用来存储排序结果。当指定的 key 已经存在时,会被覆盖。

    • options: SortOptions

    Returns Promise<string[]>

touch

  • touch(...keys: [string | Buffer, ...(string | Buffer)[]]): Promise<string[]>
  • 此命令会修改 key 的最后访问时间。返回存在的 key 的个数。

    返回值

    返回触碰到(touched)的 key 的数量。

    例子:

    await client.set('key1', 'Hello')
    // "OK"
    await client.set('key2', 'World')
    // "OK"
    await client.touch('key1', 'key2')
    // 2
    

    Parameters

    • Rest ...keys: [string | Buffer, ...(string | Buffer)[]]

    Returns Promise<string[]>

ttl

  • ttl(key: string | Buffer): Promise<number>
  • 返回 key 的过期时间剩余秒数。这项自我检查的功能可以让 Redis 的客户端检查 key 作为数据库的一部分还有多长时间。

    2.6 及更早的版本中,key 不存在或者未设置过期时间,都会返回 -1。 从 2.8 版本开始:

    • 当 key 不存在时,返回 -2。
    • 当 key 存在但是没有设置过期时间,返回 -1。

    另请参阅 PTTL 命令,他会返回毫秒级的相同信息。

    返回值

    以整数形式返回过期时间。 以及负数表示不同的过期时间状态。

    例子:

    await client.set('mykey', 'Hello')
    // "OK"
    await client.expire('mykey', 10)
    // 1
    await client.ttl('mykey')
    // 10
    

    Parameters

    • key: string | Buffer

    Returns Promise<number>

type

  • type(key: string | Buffer): Promise<"string" | "list" | "set" | "zset" | "hash" | "stream" | "none">
  • 查询值得存储类型。

    返回值

    字符串形式返回 key 处的值类型,如 stringlistsetzsethashstream
    当 key 不存在时 返回字符串 none

    例子:

    await client.set('key1', 'value')
    // "OK"
    await client.lpush('key2', 'value')
    // 1
    await client.sadd('key3', 'value')
    // 1
    await client.type('key1')
    // "string"
    await client.type('key2')
    // "list"
    await client.type('key3')
    // "set"
    

    Parameters

    • key: string | Buffer

    Returns Promise<"string" | "list" | "set" | "zset" | "hash" | "stream" | "none">

unlink

  • unlink(...keys: [string | Buffer, ...(string | Buffer)[]]): Promise<number>
    • Redis官方文档https://redis.io/commands/unlink
    • 起始版本:4.0.0
    • 时间复杂度:删除每个键的复杂度为 O(1) 和值大小无关。在之后的回收内存操作的复杂度为 O(N),N 为组成待回收对象的分配空间大小。

    此命令和 DEL 作用相似,删除指定的 key(s),不存在则被跳过。
    区别是 UNLINK 只会同步的从 keyspace 中删除 key,回收内存的工作是在另外的线程中异步执行的。所以性能会比 DEL 好一些。

    例子:

    await client.set('key1', 'Hello')
    // "OK"
    await client.set('key2', 'World')
    // "OK"
    await client.unlink('key1', 'key2', 'key3')
    // 2
    

    Parameters

    • Rest ...keys: [string | Buffer, ...(string | Buffer)[]]

    Returns Promise<number>

    查看原始定义

wait

  • wait(numreplicas: number, timeout: number): Promise<number>

Other Methods

on

  • Parameters

    • event: string | symbol
    • listener: (...args: any[]) => void
        • (...args: any[]): void
        • Parameters

          • Rest ...args: any[]

          Returns void

    Returns RedisGenericClient

once

  • Parameters

    • event: string | symbol
    • listener: (...args: any[]) => void
        • (...args: any[]): void
        • Parameters

          • Rest ...args: any[]

          Returns void

    Returns RedisGenericClient

Server Methods

info

  • info(section?: "server" | "clients" | "memory" | "persistence" | "stats" | "replication" | "cpu" | "commandstats" | "cluster" | "keyspace" | "all" | "defaultƒ"): Promise<RedisServerInfo>

Generated using TypeDoc