docker-compose 安装 Redis
1 | version: '3' |
基础命令
redis-cli
连接到 Redis,以下所有命令都是基于此 redis 客户端执行
1 | redis-cli |
AUTH
如果设置了密码,需要先验证密码
1 | > auth venom |
SELECT
选择数据库
1 | > select 0 |
DEL
语法规则:DEL key [key ...]
删除给定的一个或多个 key
,并返回删除成功的个数
1 | > mset venom:test 10 venom:test2 20 |
EXISTS
语法规则:EXISTS key [key ...]
检查给定 key
是否存在,返回待检查 key 中存在的个数
1 | > exists venom:test venom:test2 |
EXPIRE
语法规则:EXPIRE key seconds
设置 key 的过期时间(秒)
1 | > expire venom:test 10 |
PEXPIRE
语法规则:PEXPIRE key milliseconds
与 EXPIRE
类似,不同的是 PEXPIRE
设置的过期时间单位为毫秒
1 | > pexpire venom:test 10000 |
EXPIREAT
语法规则:EXPIREAT key timestamp
与 EXPIRE
类似,不同的是 EXPIREAT
设置在指定的时间戳(秒)过期
如果使用过去的时间戳将会立即删除该 key
1 | > expireat venom:test 1697772235 |
KEYS
语法规则:KEYS pattern
查看所有匹配的 key
1 | # 查找所有 key |
TTL
语法规则:TTL key
查看 key 的过期时间(秒)
key 不存在返回 -2
key 存在但没超时时间返回 -1
1 | # 存在且有超时时间 |
PTTL
语法规则:PTTL key
与 TTL
类似,不同的是 PTTL
是以毫秒为单位
1 | # 存在且有超时时间 |
TYPE
语法规则:TYPE key
查看指定 key 的值的类型
- string:键对应的值是字符串
- list:键对应的值是列表
- set:键对应的值是集合
- zset:键对应的值是有序集合(Sorted Set)
- hash:键对应的值是哈希表
- stream:键对应的值是流(Redis Streams)
- none:键不存在
1 | > type venom:test |
MOVE
语法规则:MOVE key db
将当前数据库的 key 移动到选定的数据库 db 当中
1 | # 将 venom:test 从数据库 0 移动至数据库 1 |
OBJECT
语法规则:OBJECT subcommand [arguments [arguments ...]]
从内部察看给定 key
的 Redis 对象, 它通常用在除错(debugging)或者为了节省空间而对 key
使用特殊编码的情况。 当将 Redis 用作缓存程序时,也可以通过 OBJECT
命令中的信息,决定 key
的驱逐策略(eviction policies)
OBJECT 命令有多个子命令:
OBJECT REFCOUNT
返回给定key
引用所储存的值的次数。此命令主要用于 debuggingOBJECT ENCODING
返回给定key
锁储存的值所使用的内部表示(representation)OBJECT IDLETIME
返回给定key
自储存以来的空闲时间(idle, 没有被读取也没有被写入),以秒为单位
对象可以以多种方式编码:
- 字符串可以被编码为
raw
(一般字符串)或int
(为了节约内存,Redis 会将字符串表示的 64 位有符号整数编码为整数来进行储存) - 列表可以被编码为
ziplist
或linkedlist
。ziplist
是为节约大小较小的列表空间而作的特殊表示 - 集合可以被编码为
intset
或者hashtable
。intset
是只储存数字的小集合的特殊表示 - 哈希表可以编码为
zipmap
或者hashtable
。zipmap
是小哈希表的特殊表示 - 有序集合可以被编码为
ziplist
或者skiplist
格式。ziplist
用于表示小的有序集合,而skiplist
则用于表示任何大小的有序集合
假如你做了什么让 Redis 没办法再使用节省空间的编码时(比如将一个只有 1 个元素的集合扩展为一个有 100 万个元素的集合),特殊编码类型(specially encoded types)会自动转换成通用类型(general type)
1 | > object refcount venom:hash |
PERSIST
语法规则:PERSIST key
用于删除给定 key 的过期时间,使得 key 永不过期
1 | > ttl venom:test |
RANDOMKEY
语法规则:RANDOMKEY
从当前数据库中随机返回一个 key
1 | > randomkey |
RENAME
语法规则:RENAME key newkey
修改 key 的名字
如果 newkey
存在则会被覆盖,即旧的 key 被删除
在集群模式下,key
和newkey
需要在同一个 hash slot。key
和newkey
有相同的 hash tag 才能重命名
1 | > mset venom:test 0 venom:test2 1 |
RENAMENX
语法规则:RENAMENX key newkey
与 RENAME
类似,RENAMENX
可以避免旧 key 被覆盖的情况
1 | > set venom:test2 123 |
SCAN
语法规则:SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
- cursor:游标
- patter:匹配的模式
- count:返回指定元素,默认 10
增量遍历当前数据库中的 key
对于一个较大的数据库,SCAN
比 KEYS
更高效,KEYS
可能会阻塞服务器
1 | # cursor=0 从头开始遍历 |
SORT
语法规则:SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]
返回或存储 list
、set
、zset
中的元素,默认按元素值升序
- BY:按 pattern 进行排序
- LIMIT:同 mysql 中的 LIMIT 指定元素数量
- GET:获取其他键的值并将其包含在结果中
- ASC|DESC:升序或降序
- ALPHA:按字母顺序进行排序
- STORE:将排序结果保存到指定键中
1 | > sort venom:list0 |
TOUCH
语法规则:TOUCH key [key ...]
修改指定 key 的 最后访问时间
1 | > object idletime venom:test |
UNLINK
语法规则:UNLINK key [key ...]
和 DEL
类似,用于删除指定的 key,不过 UNLINK
会执行命令之外的线程中执行实际的内存回收,因此它不是阻塞,而 DEL
是阻塞的
1 | > unlink |
WATI
语法规则:WAIT numreplicas timeout
用来阻塞当前客户端,直到所有先前的写入命令成功传输并且至少由指定数量的从节点复制完成
如果执行超过超时时间 (以毫秒为单位),则即使尚未完成指定数量的从结点复制,该命令也会返回
WAIT
命令通常在 Redis 的集群环境中使用,用于等待数据在多个节点之间的同步。它对于确保数据的可用性和一致性非常有用。通常会将 WAIT
命令与数据修改命令(如SET
)一起使用,以确保在修改数据后等待数据在主节点和从节点之间同步
DUMP
语法规则:DUMP key
序列化给定 key
,并返回被序列化的值
使用 restore
命令可以将DUMP
的结果反序列化回 Redis
序列化的值不包括任何过期(expire)信息
1 | > set venom:test 123 |
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 | > restore venom:test2 0 "\x00\xc0{\x0b\x00!=\xee\x92\xfd\xe5\x8e0" |
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
命令加上选项已经可以完全取代SETNX
、SETEX
、PSETEX
、GETSET
的功能,所以在将来的版本中,redis 可能会不推荐使用并且最终抛弃这几个命令
1 | > SET hello world |
GET
语法规则:GET key
用于获取指定 key 的值。 返回与 key
相关联的字符串值
1 | > GET hello |
GETRANGE
语法规则:GETRANGE key start end
返回存储在 key 中的字符串的子串,由 start
和 end
偏移决定(都包括在内)。负数偏移提供相对字符串结尾的偏移。所以, -1 表示最后一个字符, -2 表示倒数第二个字符,以此类推
1 | # 获取 hello 值的 [1, 3) |
SETRANGE
语法规则:SETRANGE key offset value
从偏移量 offset
开始,用 value
参数覆盖键 key
中储存的字符串值。如果键 key
不存在,当作空白字符串处理
如果键 key
中原来所储存的字符串长度比偏移量小(比如字符串只有 5
个字符长,但要设置的 offset
是 10
), 那么原字符和偏移量之间的空白将用零字节 "\x00"
进行填充
1 | # 将 hello 值的第 2 个字符开始的子串设置为“test” |
SETEX
语法规则:SETEX key seconds value
将键 key
的值设置为 value
, 并将键 key
的生存时间设置为 seconds
秒钟
SETEX
= SET
+ EXPIRE
SETEX
是一个原子操作, 它可以在同一时间内完成设置值和设置过期时间这两个操作
1 | > setex aaa 10 "bbb" |
SETNX
语法规则:SETNX key value
在指定的 key 不存在时,为 key 设置指定的值
1 | # 设置成功 |
APPEND
语法规则:APPEND key value
为指定的 key 追加值
如果 key
已经存在并且是一个字符串, APPEND 命令将 value 追加到 key
原来的值的末尾
如果 key
不存在,APPEND
就简单地将给定 key 设为 value ,就像执行 SET key value
一样
1 | # 将 hello 值后面追加“ is ok!” |
STRLEN
语法规则:STRLEN key
获取指定 key 所储存的字符串值的长度。当 key 储存的不是字符串类型时,返回错误
1 | > STRLEN hello |
INCY
语法规则:INCR key
将 key 中储存的数字值增一
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR
操作
1 | > set count 0 |
INCRBY
语法规则:INCRBY key increment
将 key 中储存的数字加上指定的增量值
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令
1 | # 原子加指定整数 |
注:默认情况下,单个 Redis 字符串最大可为 512 MB
DECR
语法规则:DECR key
将 key 中储存的数字值减一
1 | > decr count |
DECRBY
语法规则:DECRBY key decrement
将 key 中储存的数字减去上指定的减量值
1 | > decrby count 6 |
GETSET
语法规则:GETSET key value
将键 key
的值设为 value
, 并返回键 key
在被设置之前的旧值
如果键 key
没有旧值, 也即是说, 键 key
在被设置之前并不存在, 那么命令返回 nil
1 | > getset count 100 |
INCRBYFLOAT
语法规则:INCRBYFLOAT key increment
为键 key
中储存的值加上浮点数增量 increment
,key 中的浮点数是以字符串形式存储的
1 | > incrbyfloat count 0.1 |
MGET
语法规则:MGET key [key ...]
返回一个或多个给定 key 的值
1 | > mget hello count |
MSET
语法规则:MSET key value [key value ...]
设置多个 key
的值为各自对应的 value
1 | > mset k1 v1 k2 v2 |
MSETNX
语法规则:MSETNX key value [key value ...]
当且仅当所有给定键都不存在时, 为所有给定键设置值,即使只有一个给定键已经存在,MSETNX
也会拒绝执行对所有键的设置操作
MSETNX
是一个原子性(atomic)操作, 所有给定键要么就全部都被设置, 要么就全部都不设置
1 | # 所有 key 设置成功 |
PSETEX
语法规则:PSETEX key milliseconds value
和 SETEX
命令相似, 但它以毫秒为单位设置 key
的生存时间
1 | > psetex newkey 10000 "newv" |
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 | # 计算 ohmytext 和 mynewtext 两个字符串的 lcs |
应用场景
缓存:将高频字符串、图片、视频等放入 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 | > lpush venom:list 1 2 3 |
RPUSH
语法规则:RPUSH key element [element ...]
将给定值添加到列表的尾部
1 | > rpush venom:list 4 5 6 |
LPOP
语法规则:LPOP key
从列表头部删除并返回一个元素
1 | > lpop venom:list |
RPOP
语法规则:RPOP key
从列表尾部删除并返回一个元素
1 | > rpop venom:list |
LLEN
语法规则:LLEN key
返回列表的长度
1 | > llen venom:list |
LRANGE
语法规则:LRANGE key start stop
返回列表指定区间内的元素
0 表示列表的第一个元素,1 表示第二个,-1 表示最后一个,-2 表示倒数第二个
1 | > lrange venom:list 0 -1 |
LMOVE
语法规则:LMOVE source destination LEFT|RIGHT LEFT|RIGHT
以原子的方式将元素从一个列表移动到另一个列表
1 | # 将 venom:list 的头元素 移到 venom:list 的尾部 |
LTRIM
语法规则:LTRIM key start stop
将列表缩小到指定的元素范围
1 | # 截取列表第 1 个到第 2 元素 |
BLPOP
语法规则:BLPOP key [key ...] timeout
LPOP 的阻塞版本,移出并获取列表的第一个元素,如果没有元素则阻塞列表直到等待超时或发现有可弹出元素为止
当给定多个 key 参数时,按参数 key 的先后顺序依次检查各个列表,弹出第一个非空列表的头元素
timeoust 为 0 则表示一直阻塞永不超时,单位为 s
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 | # venom:list 中的第一个元素 |
LINSERT
语法规则:LINSERT key BEFORE|AFTER pivot element
key:列表
BEFORE|AFTER:前或后
pivot:参考值
element:插入值
1 | > lrange venom:list 0 -1 |
LPUSHX
语法规则:LPUSHX key element [element ...]
当 key 存在并且存储着一个 list 类型值的时候,向值 list 的头部插入 element,当 key 不存在的时候不会进行任何操作
1 | # venom:list 存在 |
LREM
语法规则:LREM key count element
从列表 key 中删除前 count 个值等于 element 的元素
count > 0:从头到尾删除值为 v 的元素
count < 0:从尾到头删除值为 v 的元素
count = 0:移除所有值为 v 的元素
1 | # 移除 venom:list 中前 3 个元素中为 2 的元素 |
LSET
语法规则:LSET key index element
设置列表 key 中 index 位置的元素值为 element
1 | > lset venom:list 1 "2" |
应用场景
- 栈:lpush + lpop(FILO)
- 队列:lpush + rpop(FIFO)
- 有限集合:lpush + ltrim
- 消息队列:lpush + brpop
注:列表的最大长度为
2^32 - 1
,每个列表最多支持40亿
个元素
Hashes 哈希
Hash 是一个键值对集合,其中 value 的形式如:[{field1, value1}, ...{fieldN, valueN}]
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 | > hset venom:hash name venom age 18 |
HGET
语法规则:HGET key field
返回哈希表中指定字段 field
的值
1 | > hget venom:hash name |
HGETALL
语法规则:HGETALL key
返回存储在 key
中的哈希表中所有的字段和值
1 | > hgetall venom:hash |
HDEL
语法规则:HDEL key field [field ...]
删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略
1 | > hdel venom:hash name age |
HEXISTS
语法规则:HEXISTS key field
判断哈希表的指定 field
是否存在
1 | # 不存在 |
HINCRBY
语法规则:HINCRBY key field increment
为哈希表 key
中的域 field
的值加上增量 increment
增量也可以为负数,相当于对给定域进行减法操作
如果域 field
不存在,那么在执行命令前,域的值被初始化为 0
1 | > hincrby venom:hash age 18 |
HINCRBYFLOAT
语法规则:HINCRBYFLOAT key field increment
为哈希表 key
中的域 field
加上浮点数增量 increment
1 | > hincrbyfloat venom:hash height 188.8 |
HKEYS
语法规则:HKEYS key
返回存储在 key
中哈希表的所有域
1 | > hkeys venom:hash |
HLEN
语法规则:HLEN key
获取哈希表中字段(fields)的数量
1 | > hlen venom:hash |
HMGET
语法规则:HMGET key field [field ...]
返回哈希表中,一个或多个给定字段(field)的值
1 | > hmget venom:hash name age height |
HMSET
语法规则:HMSET key field value [field value ...]
同时将多个 field-value 对设置到哈希表中
1 | > hmset venom:hash gender male job programmer |
HSCAN
语法规则:HSCAN key cursor [MATCH pattern] [COUNT count]
遍历哈希表中的键值对
- cursor:游标
- pattern:匹配模式(匹配 key)
- count:返回多少元素,默认 10
1 | > hset venom:hash email "[email protected]" |
HSETNX
语法规则:HSETNX key field value
为哈希表中不存在的字段赋值
1 | # 已存在,赋值失败 |
HSTRLEN
语法规则:HSTRLEN key field
返回存储在 key
中的哈希表里,与给定域 field
相关联的值的字符串长度
1 | > hstrlen venom:hash name |
HVALS
语法规则:HVALS key
返回哈希表所有字段(field)的值
1 | > hvals venom:hash |
应用场景
- 缓存: 相比 string 更节省空间,更直观
Sets 集合
Set 类型是一个无序并唯一的键值集合,它的存储顺序不会按照插入的先后顺序进行存储
Set 类型除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集
Set 类型的底层是 Hash
SADD
语法规则:SADD key member [member ...]
将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略
1 | > sadd venom:set 1 2 3 |
SCARD
语法规则:SCARD key
返回集合中元素的数量
1 | > scard venom:set |
SDIFF
语法规则:SDIFF key [key ...]
返回第一个集合与其他集合之间的差异,或者说是,第一个集合特有的元素
1 | > sadd venom:set2 2 3 4 |
SDIFFSTORE
语法规则:SDIFFSTORE destination key [key ...]
作用和SDIFF
类似,不同的是它将结果保存到 destination
集合
如果 destination 集合存在, 则会被覆盖
1 | > sdiffstore venom:set4 venom:set venom:set2 venom:set3 |
SINTER
语法规则:SINTER key [key ...]
返回所有给定集合的成员交集
如果给定的key
中有一个空集合,那么结果集一定是空集合
1 | > sinter venom:set venom:set2 venom:set3 |
SINTERSTORE
语法规则:SINTERSTORE destination key [key ...]
作用和SINTER
类似,不同的是它将结果保存到 destination
集合
如果 destination 集合存在, 则会被覆盖
1 | > sinterstore venom:set5 venom:set venom:set2 venom:set3 |
SISMEMBER
语法规则:SISMEMBER key member
判断元素 member
是否集合 key
的成员
1 | # 存在 |
SMEMBERS
语法规则:SMEMBERS key
返回存储在 key
中的集合的所有的成员
1 | > smembers venom:set |
SINTER
也能实现同样的效果
1 | > sinter venom:set |
SMISMEMBER
语法规则:SMISMEMBER key member [member ...]
与 SISMEMBER
功能类似,判断多个元素是否集合 key
的成员
1 | > smismember venom:set 1 2 9 0 |
SMOVE
语法规则:SMOVE source destination member
从集合source
中移动成员member
到集合 destination
如果集合source
不存在,或者要移动的成员不是集合source
的成员,什么也不执行并返回 0
如果要移动的元素在集合 destination
中已经存在,那么只是从集合source
中删除该成员
如果 source
或destination
不是集合类型则返回错误
1 | > smove venom:set venom:set5 1 |
SPOP
语法规则:SPOP key [count]
从集合 key
中删除并返回 count
个随机元素
1 | > sinter venom:set |
SRANDMEMBER
语法规则:SRANDMEMBER key [count]
类似于SPOP
命令,不同的是 SRANDMEMBER
不会移除元素
如果 count
是整数且小于元素的个数,返回含有 count
个元素的数组
如果 count
是个大于集合中元素的个数时,返回整个集合的所有元素
如果 count
是负数,则取 count
的绝对值
如果 count
是负数且绝对值大于元素个数,则会出现一个元素出现多次的情况
1 | # venom:set2 的元素个数 |
SREM
语法规则:SREM key member [member ...]
在集合中删除指定的元素。如果指定的元素不是集合成员则被忽略
1 | > sinter venom:set2 |
SSCAN
语法规则:SSCAN key cursor [MATCH pattern] [COUNT count]
遍历集合中键的元素
1 | > sscan venom:set3 0 MATCH "4" |
SUNION
语法规则:SUNION key [key ...]
返回所有给定集合的并集
1 | > sunion venom:set venom:set2 venom:set3 venom:set4 venom:set5 |
SUNIONSTORE
语法规则:SUNIONSTORE destination key [key ...]
功能类似于 SUNION
,不同的是不反回结果集,而是存储在 destination
中
1 | > sunionstore venom:set6 venom:set venom:set2 venom:set3 venom:set4 venom:set5 |
注: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返回值只计算新添加成员的数量
- INCR:
ZADD
使用该参数与ZINCRBY
功能一样,一次只能操作一个 score-element 对 - score:分数使用双精度64位浮点数表示,它能包括的整数范围是
-(2^53)
到+(2^53)
注: GT, LT 和 NX 三者互斥不能同时使用
1 | # 添加单个元素 |
ZRANGE
语法规则:ZRANGE key start stop [WITHSCORES]
返回有序集中,指定区间内的成员,其中成员的按分数值递增(从小到大)来排序,具有相同分数值的成员按字典序来排列
如果 start
参数的值大于有序集合中的最大索引,或者 start > stop
,将会返回一个空列表
如果 stop
的值大于有序集合的末尾,Redis 会将其视为有序集合的最后一个元素
可以传递 WITHSCORES
选项,以便将元素的分数与元素一起返回
1 | # 获取 venom:zset 第一个到最后一个元素 |
ZCARD
语法规则:ZCARD key
返回有序集的成员个数
1 | > zcard venom:zset |
ZCOUNT
语法规则:ZCOUNT key min max
有序集 key
中, score
值在 min
和 max
之间(默认包括 score
值等于 min
或 max
)的成员的数量
1 | > zcount venom:zset 1 5 |
ZRANK
语法规则:ZRANK key member
返回有序集 key
中成员 member
的升序排名
1 | > zrank venom:zset test |
ZINCRBY
语法规则:ZINCRBY key increment member
有序集 key
的成员 member
的 score 值加上增量 increment
当 key
不存在,或 member
不是 key
的成员时, 等同于 ZADD key increment member
1 | # key 存在且 member 为 key 的成员 |
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 | # 新增一个 zset |
ZINTERSTORE
语法规则:ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
与 ZINTER
相似,不同的是 ZINTERSTORE
会将结果放到 destination 中
1 | # 取 venom:zset 和 venom:zset2 的交集放入 venom:zset3 并取最小的 scores 为结果集元素的 scores |
ZLEXCOUNT
语法规则:ZLEXCOUNT key min max
返回有序集中值在 min
和max
之间的成员个数
min
和 max
参数可以使用以下格式
-
:表示负无穷(最小值)+
:表示正无穷(最大值)[value
:表示大于等于value
的值value]
:表示小于等于value
的值(value
:表示大于value
的值value)
:表示小于value
的值
1 | # 新增 zset venom:zset4 |
ZRANGEBYLEX
语法规则:ZRANGEBYLEX key min max [LIMIT offset count]
升序返回有序集中 score 在 min
和max
之间的成员
可选的 LIMIT
参数指定返回结果的数量及区间(就像SQL中的 SELECT LIMIT offset, count
),注意当 offset
很大时,定位 offset
的操作可能需要遍历整个有序集,此过程最坏复杂度为 O(N) 时间
min
和 max
的参数格式与 ZLEXCOUNT
相同
1 | # 获取有序集合中所有成员小于等于「c」的元素 |
ZRANGEBYSCORE
语法规则:ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
返回有序集 key
中,所有 score
值介于 min
和 max
之间的成员。有序集成员按 score
升序排列
具有相同 score
值的成员按字典序排列
min
和 max
的参数格式与 ZLEXCOUNT
相同
1 | # 返回 -1 ≤ score ≤ 1 |
ZMSCORE
语法规则:ZMSCORE key member [member ...]
返回有序集中指定成员的 members
的 scores
1 | > zmscore venom:zset hello |
ZPOPMAX
语法规则:ZPOPMAX key [count]
删除并返回有序集合 key
中的最高得分 count
个成员
count
默认为 1
如果 count
大于集合的元素总数,则按 score 降序删除并返回整个集合
1 | > zcard venom:zset |
ZPOPMIN
语法规则:ZPOPMIN key [count]
规则与 ZPOPMAX
类似,不同的是删除和返回的是最小值
1 | > zpopmin venom:zset2 |
ZREM
语法规则:ZREM key member [member ...]
从有序集合key
中删除指定的成员member
1 | > zrem venom:zset4 f |
ZREMRANGEBYLEX
语法规则:ZREMRANGEBYLEX key min max
用于删除成员名称按字典由低到高排序介于min
和 max
之间的所有成员
不要在成员分数不同的有序集合中使用此命令,因为它是基于分数一致的有序集合设计的,如果使用,会导致删除的结果不正确
1 | > zrange venom:zset4 0 -1 withscores |
ZREMRANGEBYRANK
语法规则:ZREMRANGEBYRANK key start stop
移除有序集 key 中,指定排名区间 start
和 stop
内的所有成员
start
和 stop
都是从 0 开始计数,0 是分数最小的元素,-1 是分数最大的元素
1 | # 往 venom:zset4 中加入几个 member |
ZREMRANGEBYSCORE
语法规则:ZREMRANGEBYSCORE key min max
移除有序集 key 中,所有 score 值介于 min 和 max 之间的成员
1 | # 往 venom:zset4 中加入几个 member |
ZREVRANGE
语法规则:ZREVRANGE key start stop [WITHSCORES]
返回有序集key
中,指定区间内的成员,其中成员的位置按 score 降序
ZREVRANGE
是 ZRAGNE
的倒序版本
1 | > zrevrange venom:zset4 0 -1 withscores |
ZREVRANGEBYLEX
语法规则:ZREVRANGEBYLEX key max min [LIMIT offset count]
ZREVRANGEBYLEX
是 ZRANGEBYLEX
的倒序版本,二者的 max
和 min
相反
1 | # 往 venom:zset4 中加入几个 member |
ZREVRANGEBYSCORE
语法规则:ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
ZREVRANGEBYSCORE
是 ZRANGEBYSCORE
的倒序版本
1 | # 返回 -1 ≤ score ≤ 1 |
ZREVRANK
语法规则:ZREVRANK key member
ZRANK
的倒序版本
1 | > zrevrank venom:zset4 d |
ZSCAN
语法规则:ZSCAN key cursor [MATCH pattern] [COUNT count]
用法同 SCAN
1 | > zscan venom:zset4 0 |
ZSCORE
语法规则:ZSCORE key member
返回有序集 key
.中成员 member
的分数
1 | > zscore venom:zset4 c |
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 | # venom:zset0 |
应用场景
- 排行榜: 学生成绩的排名榜、游戏积分排行榜、视频播放排名、电商系统中商品的销量排名等