Redis 安装及基础数据类型
2024-03-28 10:32:53 # Technical # Redis

docker-compose 安装 Redis

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
version: '3'
services:
redis:
image: redis:latest
container_name: redis
restart: always
environment:
- TZ=Asia/Shanghai
volumes:
- /opt/redis/data:/data
- /opt/redis/redis.conf:/etc/redis/redis.conf
- /opt/redis/logs:/logs
ports:
- "6379:6379"
command: /bin/bash -c "
echo 511 > /proc/sys/net/core/somaxconn
&& echo never > /sys/kernel/mm/transparent_hugepage/enabled
&& redis-server /etc/redis/redis.conf --requirepass venom"
privileged: true

基础命令

redis-cli

连接到 Redis,以下所有命令都是基于此 redis 客户端执行

1
redis-cli

AUTH

如果设置了密码,需要先验证密码

1
2
> auth venom
OK

SELECT

选择数据库

1
2
> select 0
OK

DEL

语法规则:DEL key [key ...]

删除给定的一个或多个 key,并返回删除成功的个数

1
2
3
4
> mset venom:test 10 venom:test2 20
OK
> del venom:test venom:test2 venom:test3
(integer) 2

EXISTS

语法规则:EXISTS key [key ...]

检查给定 key 是否存在,返回待检查 key 中存在的个数

1
2
> exists venom:test venom:test2
(integer) 1

EXPIRE

语法规则:EXPIRE key seconds

设置 key 的过期时间(秒)

1
2
> expire venom:test 10
(integer) 1

PEXPIRE

语法规则:PEXPIRE key milliseconds

EXPIRE 类似,不同的是 PEXPIRE 设置的过期时间单位为毫秒

1
2
> pexpire venom:test 10000
(integer) 1

EXPIREAT

语法规则:EXPIREAT key timestamp

EXPIRE 类似,不同的是 EXPIREAT 设置在指定的时间戳(秒)过期

如果使用过去的时间戳将会立即删除该 key

1
2
3
4
> expireat venom:test 1697772235
(integer) 1
> ttl venom:test
(integer) 3583

KEYS

语法规则:KEYS pattern

查看所有匹配的 key

1
2
3
4
5
6
7
8
9
# 查找所有 key
> keys *
"venom:test"
# 模糊搜索 abc 开头的key
> keys abc*
(empty array)
# 模糊搜索 v 开头 m 结尾的 4 个字符串的 key
> keys v??m
(empty array)

TTL

语法规则:TTL key

查看 key 的过期时间(秒)

key 不存在返回 -2

key 存在但没超时时间返回 -1

1
2
3
4
5
6
7
8
9
# 存在且有超时时间
> ttl venom:test
(integer) 3095
# 不存在
> ttl venom
(integer) -2
# 存在但没超时时间
> ttl hello
(integer) -1

PTTL

语法规则:PTTL key

TTL 类似,不同的是 PTTL 是以毫秒为单位

1
2
3
4
5
6
7
8
9
# 存在且有超时时间
> pttl venom:test
(integer) 3003090
# 不存在
> pttl venom
(integer) -2
# 存在但没超时时间
> pttl hello
(integer) -1

TYPE

语法规则:TYPE key

查看指定 key 的值的类型

  • string:键对应的值是字符串
  • list:键对应的值是列表
  • set:键对应的值是集合
  • zset:键对应的值是有序集合(Sorted Set)
  • hash:键对应的值是哈希表
  • stream:键对应的值是流(Redis Streams)
  • none:键不存在
1
2
> type venom:test
string

MOVE

语法规则:MOVE key db

将当前数据库的 key 移动到选定的数据库 db 当中

1
2
3
4
5
6
7
8
9
10
11
12
# 将 venom:test 从数据库 0 移动至数据库 1
> move venom:test 1
(integer) 1
> get venom:test
(nil)
> select 1
OK
> get venom:test
"0"
# 过期时间也一同迁移了
> ttl venom:test
(integer) 2570

OBJECT

语法规则:OBJECT subcommand [arguments [arguments ...]]

从内部察看给定 key 的 Redis 对象, 它通常用在除错(debugging)或者为了节省空间而对 key 使用特殊编码的情况。 当将 Redis 用作缓存程序时,也可以通过 OBJECT 命令中的信息,决定 key 的驱逐策略(eviction policies)

OBJECT 命令有多个子命令:

  • OBJECT REFCOUNT 返回给定 key 引用所储存的值的次数。此命令主要用于 debugging
  • OBJECT ENCODING 返回给定 key 锁储存的值所使用的内部表示(representation)
  • OBJECT IDLETIME 返回给定 key 自储存以来的空闲时间(idle, 没有被读取也没有被写入),以秒为单位

对象可以以多种方式编码:

  • 字符串可以被编码为 raw (一般字符串)或 int (为了节约内存,Redis 会将字符串表示的 64 位有符号整数编码为整数来进行储存)
  • 列表可以被编码为 ziplistlinkedlistziplist 是为节约大小较小的列表空间而作的特殊表示
  • 集合可以被编码为 intset 或者 hashtableintset 是只储存数字的小集合的特殊表示
  • 哈希表可以编码为 zipmap 或者 hashtablezipmap 是小哈希表的特殊表示
  • 有序集合可以被编码为 ziplist 或者 skiplist 格式。 ziplist 用于表示小的有序集合,而 skiplist 则用于表示任何大小的有序集合

假如你做了什么让 Redis 没办法再使用节省空间的编码时(比如将一个只有 1 个元素的集合扩展为一个有 100 万个元素的集合),特殊编码类型(specially encoded types)会自动转换成通用类型(general type)

1
2
3
4
5
6
7
8
9
10
11
12
> object refcount venom:hash
(integer) 1
> object encoding venom:hash
"listpack"
> object idletime venom:hash
(integer) 91040
> object refcount venom:zset
(integer) 1
> object encoding venom:zset
"listpack"
> object idletime venom:zset
(integer) 3234

PERSIST

语法规则:PERSIST key

用于删除给定 key 的过期时间,使得 key 永不过期

1
2
3
4
5
6
> ttl venom:test
(integer) 1691
> persist venom:test
(integer) 1
> ttl venom:test
(integer) -1

RANDOMKEY

语法规则:RANDOMKEY

从当前数据库中随机返回一个 key

1
2
> randomkey
"venom:test"

RENAME

语法规则:RENAME key newkey

修改 key 的名字

如果 newkey 存在则会被覆盖,即旧的 key 被删除

在集群模式下,keynewkey 需要在同一个 hash slotkeynewkey有相同的 hash tag 才能重命名

1
2
3
4
5
6
> mset venom:test 0 venom:test2 1
OK
> rename venom:test2 venom:test
OK
> get venom:test
"1"

RENAMENX

语法规则:RENAMENX key newkey

RENAME 类似,RENAMENX 可以避免旧 key 被覆盖的情况

1
2
3
4
5
6
7
8
> set venom:test2 123
OK
# newkey 已存在,重命名失败
> renamenx venom:test2 venom:test
(integer) 0
# 重命名成功
> renamenx venom:test2 venom:test3
(integer) 1

SCAN

语法规则:SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]

  • cursor:游标
  • patter:匹配的模式
  • count:返回指定元素,默认 10

增量遍历当前数据库中的 key

对于一个较大的数据库,SCANKEYS 更高效,KEYS 可能会阻塞服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# cursor=0 从头开始遍历
> scan 0
1) "25"
2) 1) "venom:zset4"
2) "venom:set"
3) "venom:zset3"
4) "venom:hash"
5) "venom:test"
6) "count"
7) "venom:set2"
8) "venom:test3"
9) "user"
10) "venom:list"
# cursor = 25 接着上次的遍历
> scan 25
1) "0"
2) 1) "venom:test2"
2) "hello"
3) "venom:set6"
4) "venom:zset"
5) "venom:list2"
6) "venom:set4"
7) "venom:set5"
8) "venom:zset2"

SORT

语法规则:SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]

返回或存储 listsetzset 中的元素,默认按元素值升序

  • BY:按 pattern 进行排序
  • LIMIT:同 mysql 中的 LIMIT 指定元素数量
  • GET:获取其他键的值并将其包含在结果中
  • ASC|DESC:升序或降序
  • ALPHA:按字母顺序进行排序
  • STORE:将排序结果保存到指定键中
1
2
3
4
5
6
7
8
9
10
11
> sort venom:list0
"1"
"2"
"3"
"4"
"5"
"6"
"7"
"8"
"9"
"10"

TOUCH

语法规则:TOUCH key [key ...]

修改指定 key 的 最后访问时间

1
2
3
4
5
6
> object idletime venom:test
(integer) 2434
> touch venom:test
(integer) 1
> object idletime venom:test
(integer) 14

语法规则:UNLINK key [key ...]

DEL 类似,用于删除指定的 key,不过 UNLINK 会执行命令之外的线程中执行实际的内存回收,因此它不是阻塞,而 DEL 是阻塞的

1
2
>  unlink 
(integer) 1

WATI

语法规则:WAIT numreplicas timeout

用来阻塞当前客户端,直到所有先前的写入命令成功传输并且至少由指定数量的从节点复制完成

如果执行超过超时时间 (以毫秒为单位),则即使尚未完成指定数量的从结点复制,该命令也会返回

WAIT 命令通常在 Redis 的集群环境中使用,用于等待数据在多个节点之间的同步。它对于确保数据的可用性和一致性非常有用。通常会将 WAIT 命令与数据修改命令(如SET)一起使用,以确保在修改数据后等待数据在主节点和从节点之间同步

DUMP

语法规则:DUMP key

序列化给定 key ,并返回被序列化的值

使用 restore 命令可以将DUMP 的结果反序列化回 Redis

序列化的值不包括任何过期(expire)信息

1
2
3
4
> set venom:test 123
OK
> dump venom:test
"\x00\xc0{\x0b\x00!=\xee\x92\xfd\xe5\x8e0"

RESTORE

语法规则:RESTORE key ttl serialized-value [REPLACE] [ABSTTL] [IDLETIME seconds] [FREQ frequency]

反序列化给定的序列化值(由 DUMP 生成),并将它和给定的 key 关联

相关参数:

  • -b<区块大小>: 设置区块大小,单位是Byte
  • -c:不检查dump操作的备份格式,仅准许读取使用旧格式的备份文件
  • -C:使用对比模式,将备份的文件与现行的文件相互对比
  • -D<文件系统>: 允许用户指定文件系统的名称
  • -f<备份文件>:从指定的文件中读取备份数据,进行还原操作
  • -h:仅解出目录而不包括与该目录相关的所有文件
  • -i:使用互动模式,在进行还原操作时,restore指令将依序询问用户
  • -m:解开符合指定的inode编号的文件或目录而非采用文件名称指定
  • -r:进行还原操作
  • -R:全面还原文件系统时,检查应从何处开始进行
  • -s<文件编号>:当备份数据超过一卷磁带时,您可以指定备份文件的编号
  • -t:指定文件名称,若该文件已存在备份文件中,则列出它们的名称
  • -v:显示指令执行过程
  • -x:设置文件名称,且从指定的存储媒体里读入它们,若该文件已存在在备份文件中,则将其还原到文件系统内
  • -y:不询问任何问题,一律以同意回答并继续执行指令
1
2
3
4
> restore venom:test2 0 "\x00\xc0{\x0b\x00!=\xee\x92\xfd\xe5\x8e0"
OK
> get venom:test2
"123"

MIGRATE

语法规则:MIGRATE host port key|"" destination-db timeout [COPY] [REPLACE] [AUTH password] [AUTH2 username password] [KEYS key [key ...]]

  • host:目标 Redis 实例的主机名或 IP 地址
  • port:目标 Redis 实例的端口号
  • key:要迁移的键的名称
  • destination-db:目标数据库的索引(通常是整数,0表示默认数据库)
  • timeout:以毫秒为单位的迁移超时时间
  • copy:指定是否进行拷贝,如果提供该参数,则源实例上的键不会被删除
  • replace:如果目标实例上已存在同名的键,是否替换
  • auth password:如果目标 Redis 实例需要密码认证,可以提供密码

用于将指定键从一个Redis实例迁移到另一个Redis实例

MIGRATE 通常用于数据迁移、数据备份和Redis实例之间的数据交互

常见的值类型

Strings 字符串

Redis 中最简单的值类型,可以存储文本、序列化对象和二进制数组。可以对整个字符串或字符串的一部分进行操作,也可以对整形或者浮点型进行自增或自减操作

SET

语法规则:SET key value [EX seconds|PX milliseconds|KEEPTTL] [NX|XX] [GET]

  • EX:设置 key 的过期时间,单位:秒
  • PX:设置 key 的过期时间,单位:毫秒
  • NX:只有 key 不存在的时候才会设置 key 的值
  • XX:只有键 key 存在的时候才会设置 key 的值
  • KEEPTTL:获取 key 的过期时间
  • GET:返回 key 存储的值,如果 key 不存在返回空

注: 由于SET命令加上选项已经可以完全取代 SETNXSETEXPSETEXGETSET 的功能,所以在将来的版本中,redis 可能会不推荐使用并且最终抛弃这几个命令

1
2
> SET hello world
OK

GET

语法规则:GET key

用于获取指定 key 的值。 返回与 key 相关联的字符串值

1
2
> GET hello
"world"

GETRANGE

语法规则:GETRANGE key start end

返回存储在 key 中的字符串的子串,由 startend 偏移决定(都包括在内)。负数偏移提供相对字符串结尾的偏移。所以, -1 表示最后一个字符, -2 表示倒数第二个字符,以此类推

1
2
3
# 获取 hello 值的 [1, 3)
> GETRANGE hello 1 3
"orl"

SETRANGE

语法规则:SETRANGE key offset value

从偏移量 offset 开始,用 value 参数覆盖键 key 中储存的字符串值。如果键 key 不存在,当作空白字符串处理

如果键 key 中原来所储存的字符串长度比偏移量小(比如字符串只有 5 个字符长,但要设置的 offset10 ), 那么原字符和偏移量之间的空白将用零字节 "\x00" 进行填充

1
2
3
4
5
# 将 hello 值的第 2 个字符开始的子串设置为“test”
> SETRANGE hello 2 "test"
(integer) 6
> GET hello
"wotest"

SETEX

语法规则:SETEX key seconds value

将键 key 的值设置为 value , 并将键 key 的生存时间设置为 seconds 秒钟

SETEX = SET + EXPIRE

SETEX 是一个原子操作, 它可以在同一时间内完成设置值和设置过期时间这两个操作

1
2
3
4
> setex aaa 10 "bbb"
OK
> ttl aaa
(integer) 7

SETNX

语法规则:SETNX key value

在指定的 key 不存在时,为 key 设置指定的值

1
2
3
4
5
6
# 设置成功
> setnx lock "lock"
(integer) 1
# 设置失败
> setnx lock "lock"
(integer) 0

APPEND

语法规则:APPEND key value

为指定的 key 追加值

如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾

如果 key 不存在,APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样

1
2
3
4
5
# 将 hello 值后面追加“ is ok!”
> APPEND hello " is ok!"
(integer) 13
> GET hello
"wotest is ok!"

STRLEN

语法规则:STRLEN key

获取指定 key 所储存的字符串值的长度。当 key 储存的不是字符串类型时,返回错误

1
2
> STRLEN hello
(integer) 13

INCY

语法规则:INCR key

将 key 中储存的数字值增一

如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作

1
2
3
4
5
> set count 0
ok
# 原子自增
> incr count
(integer) 1

INCRBY

语法规则:INCRBY key increment

将 key 中储存的数字加上指定的增量值

如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令

1
2
3
# 原子加指定整数
> incrby count 10
(integer) 11

注:默认情况下,单个 Redis 字符串最大可为 512 MB

DECR

语法规则:DECR key

将 key 中储存的数字值减一

1
2
> decr count
(integer) 10

DECRBY

语法规则:DECRBY key decrement

将 key 中储存的数字减去上指定的减量值

1
2
> decrby count 6
(integer) 4

GETSET

语法规则:GETSET key value

将键 key 的值设为 value , 并返回键 key 在被设置之前的旧值

如果键 key 没有旧值, 也即是说, 键 key 在被设置之前并不存在, 那么命令返回 nil

1
2
> getset count 100
"4"

INCRBYFLOAT

语法规则:INCRBYFLOAT key increment

为键 key 中储存的值加上浮点数增量 increment ,key 中的浮点数是以字符串形式存储的

1
2
> incrbyfloat count 0.1
"100.1"

MGET

语法规则:MGET key [key ...]

返回一个或多个给定 key 的值

1
2
3
> mget hello count
"wotest is ok!"
"100.1"

MSET

语法规则:MSET key value [key value ...]

设置多个 key 的值为各自对应的 value

1
2
> mset k1 v1 k2 v2
OK

MSETNX

语法规则:MSETNX key value [key value ...]

当且仅当所有给定键都不存在时, 为所有给定键设置值,即使只有一个给定键已经存在,MSETNX 也会拒绝执行对所有键的设置操作

MSETNX 是一个原子性(atomic)操作, 所有给定键要么就全部都被设置, 要么就全部都不设置

1
2
3
4
5
6
7
8
9
10
# 所有 key 设置成功
> msetnx k3 v3 k4 v4
(integer) 1
# 未设置成功
> msetnx k4 v4 k5 v5
(integer) 0
> mget k3 k4 k5
"v3"
"v4"
(nil)

PSETEX

语法规则:PSETEX key milliseconds value

SETEX 命令相似, 但它以毫秒为单位设置 key 的生存时间

1
2
3
4
> psetex newkey 10000 "newv"
OK
> pttl newkey
(integer) 6491

STRALGO

STRALGO 命令并不是一个原生的 Redis 命令,要使用 STRALGO 命令,需要确保 RedisGears 插件已经正确安装和配置,并且正在使用支持该插件的 Redis 版本

语法规则:STRALGO LCS [KEYS ...] [STRINGS ...] [LEN] [IDX] [MINMATCHLEN <len>] [WITHMATCHLEN]

来实现基于字符串的复杂算法。目前的唯一实现是 LCS 算法「Longest Common Subsequence」(最长公共子序列)

第一个参数是选择使用的算法名字,目前支持一个算法,所以只能是 LCS

LCS 的最大作用使计算两个字符串的相似度。字符串可以用来表示许多事情。例如两个字符串是DNA序列, LCS 可以计算出两个 DNS 序列的相似度。如果字符串用来表示一段文本,那么 LCS 可以用来查找新旧文本的差异等等

LCS 算法的时间复杂度是 O(N*M) ,N 表示首字符串的长度,M 是第二个字符串的长度。所以最好使用独立的 Redis 实例来提供算法那计算,或者确保字符串不太长

1
2
3
4
5
6
7
8
# 计算 ohmytext 和 mynewtext 两个字符串的 lcs
> stralgo LCS STRINGS ohmytext mynewtext
"mytext"
# 计算存储在 key 中的字符串值的 LCS
> MSET key1 ohmytext key2 mynewtext
OK
> stralgo LCS KEYS key1 key2
"mytext"

应用场景

  • 缓存:将高频字符串、图片、视频等放入 Redis 中,提高性能

  • 计数器:Redis 的原子性可以很好的保证安全

  • session:分布式环境下将 session 放入 Redis 中,实现 session 一致性

  • 分布式锁:利用 setnx 插入是否成功控制是否获取到锁

    1
    set <lock_key> <value> NX PX 10000
    • NX:不存在才能插入
    • PX:10s 后过期

Lists 列表

Redis 中的 Lists 其实就是链表(Redis 用双向链表或压缩列表实现的)

如果列表的元素小于 512 个(可由 list-max-ziplist-entries 配置),列表每个元素的值都小于 64 个字节(可由 list-max-ziplist-value 配置),Redis 会使用压缩列表作为 List 的数据结构

如果列表的元素不满足上面的条件,Redis 会使用双向链表作为 List 的数据结构

Redis 在 3.2 版本后,List 的数据结构只由 quicklist 实现,代替了双向链表和压缩列表

LPUSH

语法规则:LPUSH key element [element ...]

将给定值添加到列表的头部

1
2
> lpush venom:list 1 2 3
(integer) 3

RPUSH

语法规则:RPUSH key element [element ...]

将给定值添加到列表的尾部

1
2
> rpush venom:list 4 5 6
(integer) 6

LPOP

语法规则:LPOP key

从列表头部删除并返回一个元素

1
2
> lpop venom:list
"3"

RPOP

语法规则:RPOP key

从列表尾部删除并返回一个元素

1
2
> rpop venom:list
"6"

LLEN

语法规则:LLEN key

返回列表的长度

1
2
> llen venom:list
(integer) 4

LRANGE

语法规则:LRANGE key start stop

返回列表指定区间内的元素

0 表示列表的第一个元素,1 表示第二个,-1 表示最后一个,-2 表示倒数第二个

1
2
3
4
5
> lrange venom:list 0 -1
"2"
"1"
"4"
"5"

LMOVE

语法规则:LMOVE source destination LEFT|RIGHT LEFT|RIGHT

以原子的方式将元素从一个列表移动到另一个列表

1
2
3
4
5
6
7
8
9
# 将 venom:list 的头元素 移到 venom:list 的尾部
> lmove venom:list venom:list2 LEFT RIGHT
"2"
> lrange venom:list 0 -1
"1"
"4"
"5"
> lrange venom:list2 0 -1
"2"

LTRIM

语法规则:LTRIM key start stop

将列表缩小到指定的元素范围

1
2
3
4
5
6
# 截取列表第 1 个到第 2 元素
> ltrim venom:list 0 1
OK
> lrange venom:list 0 -1
"1"
"4"

BLPOP

语法规则:BLPOP key [key ...] timeout

LPOP 的阻塞版本,移出并获取列表的第一个元素,如果没有元素则阻塞列表直到等待超时或发现有可弹出元素为止

当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的头元素

timeoust 为 0 则表示一直阻塞永不超时,单位为 s

1
2
3
4
5
6
7
8
# 空列表
> BLPOP venom:list3 10
(nil)
(10.02s)
# 有值列表 + 空列表
> BLPOP venom:list venom:list3 10
"venom:list"
"1"

BRPOP

语法规则:BRPOP key [key ...] timeout

同上

BLMOVE

语法规则:BLMOVE source destination LEFT|RIGHT LEFT|RIGHT timeout

LMOVE 的阻塞版本,如果 source 非空时,效果和 LMOVE 一样,如果 source 为空,Redis 会阻塞客户端连接,直到另一个客户端向 source 列表插入新值或 timeout 超时时间到达

LINDEX

语法规则:LINDEX key index

返回列表中指定 index 处的元素

1
2
3
4
5
6
# venom:list 中的第一个元素
> lindex venom:list 0
"4"
# venom:list 中的最后一个元素
> lindex venom:list -1
"4"

LINSERT

语法规则:LINSERT key BEFORE|AFTER pivot element

  • key:列表

  • BEFORE|AFTER:前或后

  • pivot:参考值

  • element:插入值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> lrange venom:list 0 -1
"3"
"4"
"5"
> linsert venom:list before "4" "3.5"
(integer) 4
> linsert venom:list after "4" "4.5"
(integer) 5
> lrange venom:list 0 -1
"3"
"3.5"
"4"
"4.5"
"5"

LPUSHX

语法规则:LPUSHX key element [element ...]

当 key 存在并且存储着一个 list 类型值的时候,向值 list 的头部插入 element,当 key 不存在的时候不会进行任何操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# venom:list 存在
> LPUSHX venom:list 2 1
(integer) 7
> lrange venom:list 0 -1
"1"
"2"
"3"
"3.5"
"4"
"4.5"
"5"
# venom:list3 不存在
> LPUSHX venom:list3 1 2
(integer) 0
> lrange venom:list3 0 -1
(empty array)

LREM

语法规则:LREM key count element

从列表 key 中删除前 count 个值等于 element 的元素

count > 0:从头到尾删除值为 v 的元素

count < 0:从尾到头删除值为 v 的元素

count = 0:移除所有值为 v 的元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 移除 venom:list 中前 3 个元素中为 2 的元素
> lrem venom:list 3 "2"
(integer) 1
> lrange venom:list 0 -1
"1"
"3"
"3.5"
"4"
"4.5"
"5"
# 移除 venom:list 中最后 3 个元素中为 4 的元素
> lrem venom:list -3 "4"
(integer) 1
> lrange venom:list 0 -1
"1"
"3"
"3.5"
"4"
"4.5"
# 移除 venom:list 中值为 3.5 的元素
> lrem venom:list 0 "3.5"
(integer) 1
> lrange venom:list 0 -1
"1"
"3"
"4"
"4.5"

LSET

语法规则:LSET key index element

设置列表 key 中 index 位置的元素值为 element

1
2
3
4
5
6
7
> lset venom:list 1 "2"
OK
> lrange venom:list 0 -1
"1"
"2"
"4"
"4.5"

应用场景

  • 栈:lpush + lpop(FILO)
  • 队列:lpush + rpop(FIFO)
  • 有限集合:lpush + ltrim
  • 消息队列:lpush + brpop

注:列表的最大长度为 2^32 - 1,每个列表最多支持 40亿 个元素

Hashes 哈希

Hash 是一个键值对集合,其中 value 的形式如:[{field1, value1}, ...{fieldN, valueN}]

Hash 与 String 的区别

Hash 的底层是由压缩列表或哈希表实现

如果元素个数小于 512 个(可由 hash-max-ziplist-entries 配置),所有的值小于 64 个字节(可由 hash-max-ziplist-value 配置)的话,Redis 会使用压缩列表作为 Hash 的底层数据结构

如果上面的条件不满足,Redis 会使用哈希表作为 Hash 的底层数据结构

Redis 7.0 后,压缩列表数据结构已废弃,由 listpack 数据结构实现

HSET

语法规则:HSET key field value [field value ...]

为存储在 key 中的哈希表的 field 字段赋值 value

如果哈希表不存在,一个新的哈希表被创建并进行 HSET 操作

如果字段(field)已经存在于哈希表中,旧值将被覆盖

1
2
> hset venom:hash name venom age 18
(integer) 2

HGET

语法规则:HGET key field

返回哈希表中指定字段 field 的值

1
2
3
4
5
> hget venom:hash name
"venom"
# 不存在的字段
> hget venom:hash abc
(nil)

HGETALL

语法规则:HGETALL key

返回存储在 key 中的哈希表中所有的字段和值

1
2
3
4
5
> hgetall venom:hash
"name"
"venom"
"age"
"18"

HDEL

语法规则:HDEL key field [field ...]

删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略

1
2
3
4
> hdel venom:hash name age
(integer) 2
> hgetall venom:hash
(empty array)

HEXISTS

语法规则:HEXISTS key field

判断哈希表的指定 field 是否存在

1
2
3
4
5
6
7
8
# 不存在
> hexists venom:hash name
(integer) 0
> hset venom:hash name venom
(integer) 1
# 存在
> hexists venom:hash name
(integer) 1

HINCRBY

语法规则:HINCRBY key field increment

为哈希表 key 中的域 field 的值加上增量 increment

增量也可以为负数,相当于对给定域进行减法操作

如果域 field 不存在,那么在执行命令前,域的值被初始化为 0

1
2
3
4
> hincrby venom:hash age 18
(integer) 18
> hincrby venom:hash age 6
(integer) 24

HINCRBYFLOAT

语法规则:HINCRBYFLOAT key field increment

为哈希表 key 中的域 field 加上浮点数增量 increment

1
2
3
4
> hincrbyfloat venom:hash height 188.8
"188.8"
> hincrbyfloat venom:hash height 0.2
"189"

HKEYS

语法规则:HKEYS key

返回存储在 key 中哈希表的所有域

1
2
3
4
> hkeys venom:hash
"name"
"age"
"height"

HLEN

语法规则:HLEN key

获取哈希表中字段(fields)的数量

1
2
> hlen venom:hash
(integer) 3

HMGET

语法规则:HMGET key field [field ...]

返回哈希表中,一个或多个给定字段(field)的值

1
2
3
4
> hmget venom:hash name age height
"venom"
"24"
"189"

HMSET

语法规则:HMSET key field value [field value ...]

同时将多个 field-value 对设置到哈希表中

1
2
3
4
5
6
7
8
9
10
11
12
13
> hmset venom:hash gender male job programmer
OK
> hgetall venom:hash
"name"
"venom"
"age"
"24"
"height"
"189"
"gender"
"male"
"job"
"programmer"

HSCAN

语法规则:HSCAN key cursor [MATCH pattern] [COUNT count]

遍历哈希表中的键值对

  • cursor:游标
  • pattern:匹配模式(匹配 key)
  • count:返回多少元素,默认 10
1
2
3
4
5
6
7
8
> hset venom:hash email "[email protected]"
(integer) 1
> hscan venom:hash 0 MATCH "*m*"
1) "0"
2) 1) "name"
2) "venom"
3) "email"
4) "[email protected]"

HSETNX

语法规则:HSETNX key field value

为哈希表中不存在的字段赋值

1
2
3
# 已存在,赋值失败
> hsetnx venom:hash name venom24
(integer) 0

HSTRLEN

语法规则:HSTRLEN key field

返回存储在 key 中的哈希表里,与给定域 field 相关联的值的字符串长度

1
2
> hstrlen venom:hash name
(integer) 5

HVALS

语法规则:HVALS key

返回哈希表所有字段(field)的值

1
2
3
4
5
6
> hvals venom:hash
"venom"
"24"
"189"
"male"
"programmer"

应用场景

  • 缓存: 相比 string 更节省空间,更直观

Sets 集合

Set 类型是一个无序并唯一的键值集合,它的存储顺序不会按照插入的先后顺序进行存储

Set 类型除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集

Set 类型的底层是 Hash

SADD

语法规则:SADD key member [member ...]

将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略

1
2
> sadd venom:set 1 2 3
(integer) 3

SCARD

语法规则:SCARD key

返回集合中元素的数量

1
2
> scard venom:set
(integer) 3

SDIFF

语法规则:SDIFF key [key ...]

返回第一个集合与其他集合之间的差异,或者说是,第一个集合特有的元素

1
2
3
4
5
6
> sadd venom:set2 2 3 4
(integer) 3
> sadd venom:set3 3 4 5
(integer) 3
> sdiff venom:set venom:set2 venom:set3
"1"

SDIFFSTORE

语法规则:SDIFFSTORE destination key [key ...]

作用和SDIFF类似,不同的是它将结果保存到 destination 集合

如果 destination 集合存在, 则会被覆盖

1
2
3
4
> sdiffstore venom:set4 venom:set venom:set2 venom:set3
(integer) 1
> scard venom:set4
(integer) 1

SINTER

语法规则:SINTER key [key ...]

返回所有给定集合的成员交集

如果给定的key中有一个空集合,那么结果集一定是空集合

1
2
> sinter venom:set venom:set2 venom:set3
"3"

SINTERSTORE

语法规则:SINTERSTORE destination key [key ...]

作用和SINTER类似,不同的是它将结果保存到 destination 集合

如果 destination 集合存在, 则会被覆盖

1
2
3
4
> sinterstore venom:set5 venom:set venom:set2 venom:set3
(integer) 1
> scard venom:set5
(integer) 1

SISMEMBER

语法规则:SISMEMBER key member

判断元素 member 是否集合 key 的成员

1
2
3
4
5
6
# 存在
> sismember venom:set 2
(integer) 1
# 不存在
> sismember venom:set 5
(integer) 0

SMEMBERS

语法规则:SMEMBERS key

返回存储在 key 中的集合的所有的成员

1
2
3
4
> smembers venom:set
"1"
"2"
"3"

SINTER 也能实现同样的效果

1
2
3
4
> sinter venom:set
"1"
"2"
"3"

SMISMEMBER

语法规则:SMISMEMBER key member [member ...]

SISMEMBER 功能类似,判断多个元素是否集合 key 的成员

1
2
3
4
5
> smismember venom:set 1 2 9 0
(integer) 1
(integer) 1
(integer) 0
(integer) 0

SMOVE

语法规则:SMOVE source destination member

从集合source 中移动成员member 到集合 destination

如果集合source 不存在,或者要移动的成员不是集合source 的成员,什么也不执行并返回 0

如果要移动的元素在集合 destination中已经存在,那么只是从集合source中删除该成员

如果 sourcedestination 不是集合类型则返回错误

1
2
3
4
5
> smove venom:set venom:set5 1
(integer) 1
> sinter venom:set5
"1"
"3"

SPOP

语法规则:SPOP key [count]

从集合 key中删除并返回 count随机元素

1
2
3
4
5
6
7
> sinter venom:set
"2"
"3"
> spop venom:set 1
"3"
> sinter venom:set
"2"

SRANDMEMBER

语法规则:SRANDMEMBER key [count]

类似于SPOP命令,不同的是 SRANDMEMBER 不会移除元素

如果 count 是整数且小于元素的个数,返回含有 count 个元素的数组

如果 count 是个大于集合中元素的个数时,返回整个集合的所有元素

如果 count 是负数,则取 count 的绝对值

如果 count 是负数且绝对值大于元素个数,则会出现一个元素出现多次的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# venom:set2 的元素个数
> scard venom:set2
(integer) 3
# count < 元素个数
> srandmember venom:set2 2
"3"
"2"
# count > 元素个数
> srandmember venom:set2 10
"2"
"3"
"4"
# count 为负数
> srandmember venom:set2 -2
"2"
"2"
# count 为负数且大于元素个数
> srandmember venom:set2 -10
"3"
"4"
"3"
"4"
"3"
"2"
"3"
"3"
"2"
"2"

SREM

语法规则:SREM key member [member ...]

在集合中删除指定的元素。如果指定的元素不是集合成员则被忽略

1
2
3
4
5
6
7
8
> sinter venom:set2
"2"
"3"
"4"
> srem venom:set2 2 4 9 0
(integer) 2
> sinter venom:set2
"3"

SSCAN

语法规则:SSCAN key cursor [MATCH pattern] [COUNT count]

遍历集合中键的元素

1
2
3
> sscan venom:set3 0 MATCH "4"
1) "0"
2) 1) "4"

SUNION

语法规则:SUNION key [key ...]

返回所有给定集合的并集

1
2
3
4
5
6
> sunion venom:set venom:set2 venom:set3 venom:set4 venom:set5
"1"
"2"
"3"
"4"
"5"

SUNIONSTORE

语法规则:SUNIONSTORE destination key [key ...]

功能类似于 SUNION,不同的是不反回结果集,而是存储在 destination

1
2
3
4
5
6
7
8
> sunionstore venom:set6 venom:set venom:set2 venom:set3 venom:set4 venom:set5
(integer) 5
> sinter venom:set6
"1"
"2"
"3"
"4"
"5"

注:Set 的差集、并集和交集的计算复杂度较高,在数据量较大的情况下,如果直接执行这些计算,会导致 Redis 实例阻塞。主从集群中,为了避免主库因为 Set 做聚合计算(交集、差集、并集)时导致主库被阻塞,我们可以选择一个从库完成聚合统计,或者把数据返回给客户端,由客户端来完成聚合统计

应用场景

  • 标签(tag):给用户添加标签,或者用户给消息添加标签,这样有同一标签或者类似标签的可以给推荐关注的事或者关注的人
  • 点赞、踩、收藏等: Set 类型可以保证一个用户只能操作一次,第二次就取消
  • 共同关注:Set 类型支持交集运算,所以可以用来计算共同关注的好友、公众号等
  • 抽奖:如果允许重复中奖,可以使用 SRANDMEMBER 命令,如果不允许重复中奖,可以使用 SPOP 命令

Sorted sets 有序集合(Zset)

Zset 类型(有序集合类型)相比于 Set 类型多了一个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序集合的元素值,一个是排序值

有序集合保留了集合不能有重复成员的特性(分值可以重复),但不同的是,有序集合中的元素可以排序

当多个成员有相同的分数时,他们将是按字典排序(ordered lexicographically)(仍由分数作为第一排序条件,然后,相同分数的成员按照字典序排序)

Zset 类型的底层数据结构是由压缩列表或跳表实现的

如果有序集合的元素个数小于 128 个,并且每个元素的值小于 64 字节时,Redis 会使用压缩列表作为 Zset 类型的底层数据结构

如果有序集合的元素不满足上面的条件,Redis 会使用跳表作为 Zset 类型的底层数据结构

Redis 7.0 中,压缩列表数据结构已经废弃了,交由 listpack 数据结构来实现了

ZADD

语法规则:ZADD key [NX|XX] [CH] [INCR] score member [score member …]

  • XX:仅更新存在的成员,不添加新成员
  • NX:不更新存在的成员。只添加新成员
  • LT:更新新的分值比当前分值小的成员,不存在则新增
  • GT:更新新的分值比当前分值大的成员,不存在则新增
  • CH:返回变更成员的数量。变更的成员是指 新增成员score值更新的成员,命令指明的和之前score值相同的成员不计在内。 注意: 在通常情况下,ZADD返回值只计算新添加成员的数量
  • INCRZADD 使用该参数与 ZINCRBY 功能一样,一次只能操作一个 score-element 对
  • score:分数使用双精度64位浮点数表示,它能包括的整数范围是-(2^53)+(2^53)

注: GT, LTNX 三者互斥不能同时使用

1
2
3
4
5
6
# 添加单个元素
> zadd venom:zset 0 hello
(integer) 1
# 添加多个元素
> zadd venom:zset 1 world 2 test 3 zset
(integer) 3

ZRANGE

语法规则:ZRANGE key start stop [WITHSCORES]

返回有序集中,指定区间内的成员,其中成员的按分数值递增(从小到大)来排序,具有相同分数值的成员按字典序来排列

如果 start 参数的值大于有序集合中的最大索引,或者 start > stop ,将会返回一个空列表

如果 stop 的值大于有序集合的末尾,Redis 会将其视为有序集合的最后一个元素

可以传递 WITHSCORES 选项,以便将元素的分数与元素一起返回

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 获取 venom:zset 第一个到最后一个元素
> zrange venom:zset 0 -1
"hello"
"world"
"test"
"zset"
# 将元素的分数与元素一起返回
> zrange venom:zset 0 -1 withscores
"hello"
"0"
"world"
"1"
"test"
"2"
"zset"
"3"

ZCARD

语法规则:ZCARD key

返回有序集的成员个数

1
2
> zcard venom:zset
(integer) 4

ZCOUNT

语法规则:ZCOUNT key min max

有序集 key 中, score 值在 minmax 之间(默认包括 score 值等于 minmax )的成员的数量

1
2
> zcount venom:zset 1 5
(integer) 3

ZRANK

语法规则:ZRANK key member

返回有序集 key 中成员 member 的升序排名

1
2
> zrank venom:zset test
(integer) 2

ZINCRBY

语法规则:ZINCRBY key increment member

有序集 key 的成员 memberscore 值加上增量 increment

key 不存在,或 member 不是 key 的成员时, 等同于 ZADD key increment member

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# key 存在且 member 为 key 的成员
> zincrby venom:zset 2 "hello"
"2"
> zrange venom:zset 0 -1
"world"
"hello"
"test"
"zset"
# key 存在但 member 不为 key 的成员
> zincrby venom:zset 3 "unexpected"
"3"
> zrange venom:zset 0 -1 withscores
"world"
"1"
"hello"
"2"
"test"
"2"
"unexpected"
"3"
"zset"
"3"

ZINTER

语法规则:ZINTER numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]

计算 numkeys 个有序集合的交集, 在给定要计算的 key 和其它参数之前,必须先给定 key 个数(numberkeys)

默认情况下,结果集中元素的分数是各有序集合中该元素分数之和

  • WEIGHTS:为每个给定的有序集指定一个乘法因子,意思就是,每个给定有序集的所有成员的 score 值在传递给聚合函数之前都要先乘以该因子。如果WEIGHTS没有给定,默认是 1
  • AGGREGATE:指定并集的结果集的聚合方式。默认使用的参数SUM,可以将所有集合中某个成员的 score 值之和作为结果集中该成员的 score 值。如果使用参数 MIN 或者 MAX ,结果集就是所有集合中该元素最小或最大 score
1
2
3
4
5
6
7
8
9
10
11
12
13
# 新增一个 zset
> zadd venom:zset2 0 "hello" 1 "world" 2 "zset2"
(integer) 3
# venom:zset venom:zset2 取交集
> zinter 2 venom:zset venom:zset2
"hello"
"world"
# 结果添加 scores
> zinter 2 venom:zset venom:zset2 withscores
"hello"
"2"
"world"
"2"

ZINTERSTORE

语法规则:ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]

ZINTER 相似,不同的是 ZINTERSTORE 会将结果放到 destination 中

1
2
3
4
5
6
7
8
# 取 venom:zset 和 venom:zset2 的交集放入 venom:zset3 并取最小的 scores 为结果集元素的 scores
> zinterstore venom:zset3 2 venom:zset venom:zset2 AGGREGATE MIN
(integer) 3
> zrange venom:zset3 0 -1 withscores
"hello"
"0"
"world"
"1"

ZLEXCOUNT

语法规则:ZLEXCOUNT key min max

返回有序集中值在 minmax之间的成员个数

minmax 参数可以使用以下格式

  • -:表示负无穷(最小值)
  • +:表示正无穷(最大值)
  • [value:表示大于等于 value 的值
  • value]:表示小于等于 value 的值
  • (value:表示大于 value 的值
  • value):表示小于 value 的值
1
2
3
4
5
6
7
8
9
10
11
12
# 新增 zset venom:zset4
> zadd venom:zset4 0 a 1 b 2 c 3 d 4 e 5 f
(integer) 6
# 计算有序集合中所有成员小于等于「c」的数量
> zlexcount venom:zset4 - [c
(integer) 3
# 计算有序集合中所有成员大于等于「c」的数量
> zlexcount venom:zset4 [c +
(integer) 4
# 计算有序集合中所有成员在区间「(b」,「[f」之间的数量
> zlexcount venom:zset4 (b [f
(integer) 4

ZRANGEBYLEX

语法规则:ZRANGEBYLEX key min max [LIMIT offset count]

升序返回有序集中 score 在 minmax之间的成员

可选的 LIMIT 参数指定返回结果的数量及区间(就像SQL中的 SELECT LIMIT offset, count),注意当 offset 很大时,定位 offset 的操作可能需要遍历整个有序集,此过程最坏复杂度为 O(N) 时间

minmax 的参数格式与 ZLEXCOUNT 相同

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 获取有序集合中所有成员小于等于「c」的元素
> zrangebylex venom:zset4 - [c
"a"
"b"
"c"
# 获取有序集合中所有成员大于等于「c」的元素
> zrangebylex venom:zset4 [c +
"c"
"d"
"e"
"f"
# 获取有序集合中所有成员在区间「(b」,「[f」之间的元素
> zrangebylex venom:zset4 (b [f
"c"
"d"
"e"
"f"

ZRANGEBYSCORE

语法规则:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]

返回有序集 key 中,所有 score 值介于 minmax 之间的成员。有序集成员按 score 升序排列

具有相同 score 值的成员按字典序排列

minmax 的参数格式与 ZLEXCOUNT 相同

1
2
3
4
5
6
7
8
9
10
# 返回 -1 ≤ score ≤ 1
> zrangebyscore venom:zset4 -1 1 withscores
"a"
"0"
"b"
"1"
# 返回 -1 < score < 1
> zrangebyscore venom:zset4 (-1 (1 withscores
"a"
"0"

ZMSCORE

语法规则:ZMSCORE key member [member ...]

返回有序集中指定成员的 membersscores

1
2
> zmscore venom:zset hello
"2"

ZPOPMAX

语法规则:ZPOPMAX key [count]

删除并返回有序集合 key 中的最高得分 count 个成员

count 默认为 1

如果 count 大于集合的元素总数,则按 score 降序删除并返回整个集合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> zcard venom:zset
(integer) 5
> zpopmax venom:zset
"zset"
"3"
> zpopmax venom:zset 10
"unexpected"
"3"
"test"
"2"
"hello"
"2"
"world"
"1"

ZPOPMIN

语法规则:ZPOPMIN key [count]

规则与 ZPOPMAX 类似,不同的是删除和返回的是最小值

1
2
3
> zpopmin venom:zset2
"hello"
"0"

ZREM

语法规则:ZREM key member [member ...]

从有序集合key中删除指定的成员member

1
2
> zrem venom:zset4 f
(integer) 1

ZREMRANGEBYLEX

语法规则:ZREMRANGEBYLEX key min max

用于删除成员名称按字典由低到高排序介于minmax 之间的所有成员

不要在成员分数不同的有序集合中使用此命令,因为它是基于分数一致的有序集合设计的,如果使用,会导致删除的结果不正确

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
> zrange venom:zset4 0 -1 withscores
"a"
"0"
"b"
"1"
"c"
"2"
"d"
"3"
"e"
"4"
# 往 venom:zset4 中加入几个 score 相同的 member
> zadd venom:zset4 1 bb 2 cc 3 dd
(integer) 3
# 先用 zrangebylex 查询一下
> zrangebylex venom:zset4 (a (e
"b"
"bb"
"c"
"cc"
"d"
"dd"
> zremrangebylex venom:zset4 (a (e
(integer) 6
> zrange venom:zset4 0 -1 withscores
"a"
"0"
"e"
"4"

ZREMRANGEBYRANK

语法规则:ZREMRANGEBYRANK key start stop

移除有序集 key 中,指定排名区间 startstop 内的所有成员

startstop 都是从 0 开始计数,0 是分数最小的元素,-1 是分数最大的元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 往 venom:zset4 中加入几个 member
> zadd venom:zset4 1 b 2 c 3 d 5 f
(integer) 4
> zrange venom:zset4 0 -1 withscores
"a"
"0"
"b"
"1"
"c"
"2"
"d"
"3"
"e"
"4"
"f"
"5"
# 移除排名 2 - 4 的 member
> zremrangebyrank venom:zset4 1 3
(integer) 3
> zrange venom:zset4 0 -1 withscores
"a"
"0"
"e"
"4"
"f"
"5"

ZREMRANGEBYSCORE

语法规则:ZREMRANGEBYSCORE key min max

移除有序集 key 中,所有 score 值介于 min 和 max 之间的成员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 往 venom:zset4 中加入几个 member
> zadd venom:zset4 1 b 2 c 3 d
(integer) 3
> zrange venom:zset4 0 -1 withscores
"a"
"0"
"b"
"1"
"c"
"2"
"d"
"3"
"e"
"4"
"f"
"5"
# 先执行 zrangebyscore 查询 1 ≤ score ≤ 3 的 member
> zrangebyscore venom:zset4 1 3
"b"
"c"
"d"
> zremrangebyscore venom:zset4 1 3
(integer) 3
> zrange venom:zset4 0 -1 withscores
"a"
"0"
"e"
"4"
"f"
"5"

ZREVRANGE

语法规则:ZREVRANGE key start stop [WITHSCORES]

返回有序集key中,指定区间内的成员,其中成员的位置按 score 降序

ZREVRANGEZRAGNE 的倒序版本

1
2
3
4
5
6
7
> zrevrange venom:zset4 0 -1 withscores
"f"
"5"
"e"
"4"
"a"
"0"

ZREVRANGEBYLEX

语法规则:ZREVRANGEBYLEX key max min [LIMIT offset count]

ZREVRANGEBYLEXZRANGEBYLEX 的倒序版本,二者的 maxmin 相反

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 往 venom:zset4 中加入几个 member
> zadd venom:zset4 1 b 2 c 3 d
(integer) 3
# 获取有序集合中所有成员大于等于「c」的元素
> zrevrangebylex venom:zset4 + [c
"f"
"e"
"d"
"c"
# 获取有序集合中所有成员小于等于「c」的元素
> zrevrangebylex venom:zset4 [c -
"c"
"b"
"a"
# 获取有序集合中所有成员在区间「(b」,「[f」之间的元素
> zrevrangebylex venom:zset4 (b [f
"f"
"e"
"d"
"c"

ZREVRANGEBYSCORE

语法规则:ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]

ZREVRANGEBYSCOREZRANGEBYSCORE 的倒序版本

1
2
3
4
5
6
7
8
9
10
# 返回 -1 ≤ score ≤ 1
> zrevrangebyscore venom:zset4 1 -1 withscores
"b"
"1"
"a"
"0"
# 返回 -1 < score < 1
> zrevrangebyscore venom:zset4 (1 (-1 withscores
"a"
"0"

ZREVRANK

语法规则:ZREVRANK key member

ZRANK 的倒序版本

1
2
> zrevrank venom:zset4 d
(integer) 2

ZSCAN

语法规则:ZSCAN key cursor [MATCH pattern] [COUNT count]

用法同 SCAN

1
2
3
4
5
6
7
8
9
10
11
12
13
14
> zscan venom:zset4 0
1) "0"
2) 1) "f"
2) "5"
3) "e"
4) "4"
5) "d"
6) "3"
7) "c"
8) "2"
9) "a"
10) "0"
11) "b"
12) "1"

ZSCORE

语法规则:ZSCORE key member

返回有序集 key.中成员 member 的分数

1
2
> zscore venom:zset4 c
"2"

ZUNION

语法规则:ZUNION numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] [WITHSCORES]

  • WEIGHTS:乘法因子,每个给定有序集的所有成员的score值在传递给聚合函数之前都要先乘以该因子,默认为 1
  • AGGREGATE:指定并集的结果集的聚合方式,默认为 SUM, 可以将所有集合中某个成员的 score 值之和作为结果集中该成员的 score 值。如果使用参数 MIN 或者 MAX,结果集就是所有集合中该元素最小或最大 score

计算给定的numkeys个有序集合的并集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# venom:zset0
> zrange venom:zset0 0 -1 withscores
"f"
"0.1"
"e"
"2.9"
"d"
"3.4"
"b"
"8.8"
"c"
"9.1"
# venom:zset4
> zrange venom:zset5 0 -1 withscores
"a"
"0"
"b"
"1"
"c"
"2"
"d"
"3"
"e"
"4"
"f"
"5"
# 并集 score 之和排序
> zunion 2 venom:zset0 venom:zset4 AGGREGATE SUM withscores
"a"
"0"
"f"
"5.1"
"d"
"6.4"
"e"
"6.9"
"b"
"9.8"
"c"
"11.1"
# 并集 score 最小值排序
> zunion 2 venom:zset0 venom:zset4 AGGREGATE MIN withscores
"a"
"0"
"f"
"0.1"
"b"
"1"
"c"
"2"
"e"
"2.9"
"d"
"3"

应用场景

  • 排行榜: 学生成绩的排名榜、游戏积分排行榜、视频播放排名、电商系统中商品的销量排名等

Thanks