Redis 的基础数据结构和 API
Redis 提供的基础数据结构有五种:
- 字符串
string
- 哈希表
hash
- 列表
list
- 集合
set
- 有序集合
zset
全局命令
- 查看所有键:
keys *
- 会遍历所有键,时间复杂度为 O(n)
- 如果保存了大量的键,禁止使用
- 键总数:
dbsize
- 键是否存在:
exists key
- 删除:
del key [key ...]
- 添加过期时间:
expire key seconds
- 返回剩余时间:
ttl
- 返回剩余时间:
- 键的数据结构:
type key
字符串
- Redis 最基础的数据结构,其它的数据结构都是在字符串之上进行构建
- 键都是字符串类型
- 值可以是字符串(包括 JSON、XML)、数字、二进制等等
- 但不能超过 512 MB
常用命令
- 设置值:
set key value [ex seconds] [px milliseconds] [nx|xx]
nx
:键必须不存在,才可以设置成功,用于「添加」xx
:键必须存在,才可以设置成功,用于「更新」setex
、setnx
:与ex
和nx
选项一样
- 获取值:
get key
- 批量设置值:
mset key value [key value ...]
- 批量获取值:
mget key [key ...]
批量操作与 n
次 get
对比:
- 批量操作:1 次网络时间 +
n
次命令时间 n
次get
:n
次网络时间 +n
次命令时间
对于值为整数还可以进行自增 incr
和自减 decr
操作。
另外,还有 append
可以追加值(不常用)
1 | > get key |
内部编码结构
字符串内部的数据结构有三种:
int
:8 个字节的长整形(int64)embstr
:小于等于 39 个字节的字符串raw
:大于 39 个字节的字符串
可以使用 object encoding key
查看。
经典使用场景
- 缓存
- 计数
- 共享 session
- 限速
哈希
Redis 的字符串的 key-value 已经很类似常规的哈希了。Redis 的哈希则是值本身又是一个键值对的结构。
常用命令
- 设置值:
hset key field value
- 成功返回
1
,失败返回0
- 也有
hsetnx
- 成功返回
- 获取值:
hget key field
- 删除值:
hdel key field [field ...]
- 统计
field
个数:hlen key
- 判断 field 是否存在:
hexists key field
- 获取所有的 field:
hkeys key
- 批量设置或获取 field-value
hmget key field [field ...]
hmset key field value [field value ...]
内部编码结构
ziplist
(压缩列表):元素个数小于hash-max-ziplist-entries
(默认 512),同时所有值长度都小于hash-max-ziplist-value
(默认 64 字节)。ziplist
会比hashtable
更加紧凑(连续存储),从而节省内存。hashtable
:元素多了之后,会使用hashtable
作为内部实现。但是,hashtable
装载率一般只有一半左右,所以比较耗费内存。
经典使用场景
存储用户信息,例如:用户名、年龄等等。
列表
存储多个有序的字符串。一个列表最多可以存储 2^32-1 个元素。在 Redis 中,可以对列表两端进行插入 push
和 pop
,还可以获取指定范围的元素列表。可以充当栈和队列的角色。
lpush
+lpop
= stack(栈)lpush
+rpop
= queue(队列)lpush
+ltrim
= capped collection(有限集合)lpush
+brpop
= message queue(消息队列)
常用命令
- 添加:
rpush key value [value ...]
lpush key value [value ...]
- 在某个
pivot
元素之前或者之后插入元素:linsert key before|after pivot value
- 查找指定范围的元素:
lrange key start end
- 获取索引下标的元素;
lindex key index
- 删除:
lpop key
rpop key
- 删除指定元素:
lrem key count value
count > 0
:从左往右,删除最多count
个元素count < 0
:从右向左,删除最多count
绝对值个元素count = 0
:删除所有元素
- 按照索引范围修剪列表:
ltrim key start end
- 修改指定索引下标的元素:
lset key index newValue
- 阻塞式弹出
blpop key [key ...] timeout
brpop key [key ...] timeout
lpop
和rpop
的阻塞版本- 如果列表为空,
timeout = 3
,客户端要等 3 秒才返回,如果timeout = 0
,那么客户端会一直阻塞等待下去。
内部编码结构
ziplist
(压缩列表):当列表的元素个数小于list-max-ziplist-entries
配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value
配置时(默认64字节),Redis 会选用ziplist
来作为列表的内部实现来减少内存的使用。linkedlist
(链表):当列表类型无法满足ziplist
的条件时,Redis 会使用linkedlist
作为列表的内部实现。
经典使用场景
- 消息队列
- 文章列表
集合
集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一样的是,集合中 不允许有重复元素 ,并且集合中的元素是无序的,不能通过索引下标获取元素。
Redis 除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集,合理地使用好集合类型,
常用命令
- 添加元素:
sadd key element [element ...]
,返回成功添加的元素个数 - 删除元素:
srem key element [element ...]
- 计算元素个数:
scard key
(内置变量,时间复杂度为 O(1)) - 判断元素是否在集合中:
sismember key element
,存在返回1
,否则返回0
- 随机从集合中返回指定个数的元素:
srandmember key [count]
,不写数量默认为1
- 随机弹出元素:
spop key
- 获取所有元素:
smembers key
集合之间的操作:
- 多个集合之间的交集:
sinter key [key ...]
- 多个集合之间的并集:
sunion key [key ...]
- 多个集合之间的差集:
sdiff key [key ...]
将交集、并集、差集的结果保存:
sinterstore destination key [key ...]
sunionstore destination key [key ...]
sdiffstore destination key [key ...]
内部编码结构
intset
(整数集合):当集合中的元素都是整数且元素个数小于set-max-intset-entries
配置(默认512个)时,Redis 会选用intset
来作为集合的内部实现,从而减少内存的使用。hashtable
(哈希表):当集合类型无法满足intset
的条件时,Redis 会使用hashtable
作为集合的内部实现
经典使用场景
标签(tag)
有序集合
保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序。它给每个元素设置一个分数(score)作为排序的依据。
数据结构 | 是否允许重复 | 是否有序 | 有序的实现 | 场景 |
---|---|---|---|---|
列表 | 是 | 是 | 索引下标 | 时间轴、消息队列等 |
集合 | 否 | 否 | 无 | 标签、社交等 |
有序集合 | 否 | 是 | 分值 | 排行榜系统、社交 |
常用命令
- 添加成员:
zadd key score member [score member ...]
nx
:添加xx
:更新ch
:返回此次操作后,集合元素和分数变化的个数incr
:对score
做增加,相当于zincrby
由于增加了排序字段,zadd
的复杂度为 O(log(n))
- 计算某个成员的分数:
zscore key member
- 计算成员的排名:
zrank key member
(从低到高),zrevrank
则从高到低 - 删除成员:
zrem key member [member ...]
- 增加成员的分数:
zincrby key increment member
- 返回指定排名范围的成员:
zrange key start end [withscores]
zrevrange key start end [withscores]
- 加上
withscores
会同时返回成员的分数
- 返回指定分数范围的成员
zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key max min [withscores] [limit offset count]
- 返回指定分数的范围的成员个数:
zcount key min max
min
和max
可以使用-inf
和+inf
代表无穷小和无穷大
- 删除指定分数范围的成员:
zremrangebyscore key min max
内部编码结构
ziplist
(压缩列表):当有序集合的元素个数小于zset-max-ziplist-entries
配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value
配置(默认64字节)时,Redis 会用ziplist
来作为有序集合的内部实现,ziplist
可以有效减少内存的使用。skiplist
(跳表):当ziplist
条件不满足时,有序集合会使用skiplist
作为内部实现,因为此时ziplist
的读写效率会下降。
经典使用场景
- 排行榜系统
参考资料
- Redis 命令手册
- 付磊, 张益军著.Redis开发与运维.机械工业出版社.2017
小结
就是简单复习一下 Redis 的数据结构。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 小谷的编程随笔空间!
评论