目录
1. 字符串
Redis中键都是字符串类型。字符串类型的值实际可以是简单字符串、复杂字符串(XML、JSON等)、整数、浮点数、二进制(图片、视频、音频,但不能超过512MB)。
1.1 命令
1.1.1 设置值
命令:set key value [ex seconds] [px milliseconds] [nx|xx]
注意事项:返回结果为OK即代表设置成功,返回0则代表设置失败;
选项:ex seconds:为key设置秒级过期时间。
px milliseconds:为key设置毫秒级过期时间。
nx:key必须不存在的前提下,set才能执行成功。
xx:key必须存在的前提下,set才能执行成功。
除了set选项,还提供了setex、setnx命令:
setex key seconds value(作用跟ex选项一致)
setnx key value(作用跟nx选项一致)
1.1.2 获取值
命令:get key
注意事项:如果key存在则返回对应的value,否则返回nil
1.1.3 批量设置值
命令:mset key value [key value......]
1.1.4 批量获取值
命令:mget key [key......]
注意事项:如果key不存在则返回nil。mget比get优点在于只发送一次网络请求,例如发送10次get则经过网络10次,而mget只需经过网络1次,当然1次mget也不能获取太多数据,数据太多也能造成Redis阻塞/网络拥堵。
1.1.5 自增
命令:incr key
注意事项:如果value不是整数则返回错误,如果value是整数则返回自增后的结果,如果key不存在则按照0开始自增并返回结果1。
自增:incr key
自增指定数字:incrby key increment
自减:decr key
自减指定数字:decrby key decrement
自增浮点数:incrbyfloat key increment
1.1.6 追加值
命令:append key value
注意事项:向字符串尾部追加值,
1.1.7 字符串长度
命令:strlen key
1.1.8 设置并返回原值
命令:getset key value
1.1.9 设置指定位置的字符
命令:setrange key offeset value
注意事项:索引从0开始。
1.1.10 获取部分字符串
命令:getrange key start end
注意事项:start和end分别代表开始、结束的偏移量,偏移量从0开始计算,包头包尾。
1.1.11 命令与时间复杂度
命令 | 时间复杂度 |
set | O(1) |
get | O(1) |
del | O(k)k为键的个数 |
mset | O(k)k为键的个数 |
mget | O(k)k为键的个数 |
incr | O(1) |
decr | O(1) |
incrby | O(1) |
decrby | O(1) |
incrbyfloat | O(1) |
append | O(1) |
strlen | O(1) |
setrange | O(1) |
getrange | O(n)n为字符串长度,由于获取字符串非常快,所以如果字符串不是很长的话可以等同为O(1) |
1.2 底层实现
int:8个字节的长整型
embstr:小于等于39个字节的字符串
raw:大于39个字节的字符串
Redis会根据value类型和长度,去决定使用哪种底层实现。
1.3 String命令总结
指令 | 解释 | 指令时间复杂度 |
set key value [ex seconds] [px milliseconds] [nx|xx] | ex seconds为键设置秒级过期时间 px milliseconds为键设置毫秒级过期时间 nx键必须不存在才可以设置成功,用于新增 xx键必须存在才可以设置成功,用于更新 | O(1) |
setex key seconds value | 跟ex seconds同样含义 |
|
setnx key value | 跟set nx同样含义 |
|
get key | 获取值,不存在则返回nil | O(1) |
mset key value [key value...] | 批量设置值 | O(k),k是键的个数 |
mget key [key...] | 批量获取值,结果是按照传入键的顺序返回,如果键不存在则返回nil | O(k),k是键的个数 |
incr key | 计数,当值不是整数返回错误, 当值是整数返回自增后的结果,当键不存在按照值为0自增返回结果为1 | O(1) |
decr key | 自减 | O(1) |
incrby key increment | 自增指定数字 | O(1) |
decrby key decrement | 自减指定数字 | O(1) |
incrbyfloat key increment | 自增浮点数 | O(1) |
append key value | 追加值 | O(1) |
strlen key | 字符串长度 | O(1) |
getset key value | 设置并返回原值 |
|
setrange key offeset value | 设置指定位置的字符 | O(1) |
getrange key start end | 获取部分字符串 | O(n),n是字符串长度,由于获取字符串非常快,所以如果字符串不是很长,可以约等于O(1) |
字符串内部,会根据值不同而采取不同的内部结构,目前其内部结构有3种:int代表8个字节的长整型、embstr小于等于39个字节的字符串、raw大于39个字节的字符串。
2. 哈希
哈希类型是指value自身又是一个键值对结构。
2.1 命令
2.1.1 设置值
命令:hset key field value
注意事项:设置成功返回1,否则返回0;还有hsetnx命令。
2.1.2 获取值
命令:hget key field
注意事项:如果key或者field不存在则返回nil,否则返回对应value
2.1.3 删除field
命令:hdel key field [field ......]
注意事项:返回结果为成功删除field的个数。
2.1.4 计算field个数
命令:hlen key
2.1.5 批量设置/获取field
命令:hmset key field value [field value......]
hmget key filed [field......]
2.1.6 判断field是否存在
命令:hexists key field
注意事项:存在则返回1,否则返回0.
2.1.7 获取所有field
命令:hkeys key
注意事项:返回key对应的、所有的field。
2.1.8 获取所有value
命令:hvals key
2.1.9 获取所有的field-value
命令:hgetall key
注意事项:在使用hgetall时,如果哈希元素个数比较多会存在阻塞Redis的可能。如果只需获取部分field则可以使用hmget。如果一定要获取全部field-value则可以使用hscan命令。
2.1.10 自增
命令:hincrby key field/hincrbyfloat key field
2.1.1 1 计算value的字符串长度
命令:hstrlen key field
注意事项:需要Redis3.2以上
2.1.12 时间复杂度
命令 | 时间复杂度 |
hset | O(1) |
hget | O(1) |
hdel | O(k)k为field个数 |
hlen | O(1) |
hgetall | O(k)k为field个数 |
hmget | O(k)k为field个数 |
hmset | O(k)k为field个数 |
hexists | O(1) |
hkeys | O(k)k为field个数 |
hvals | O(k)k为field个数 |
hsetnx | O(1) |
hincrby | O(1) |
hincrbyfloat | O(1) |
hstrlen | O(1) |
2.2 底层实现
ziplist压缩列表:当哈希类型元素数量小于hash-max-ziplist-entries参数(默认512个)、同时value都小于hash-max-ziplist-value参数(默认64字节)时,Redis使用ziplist作为哈希的内部实现。Ziplist使用更加紧凑的结构实现多个元素的连续存储,在节省内存方面比hashtable更加优秀。
hashtable哈希表:无法满足ziplist使用条件时,Redis则使用hashtable作为哈希的内部实现,因为此时的ziplist读写效率会下降而hashtable的读写时间复杂度反而为O(1)。
2.3 Hash命令总结
Redis是key-value形式,只不过value自身又是field-value形式。
指令 | 解释 | 指令时间复杂度 |
hset key field value | 设置值,设置成功返回1,否则返回0 | O(1) |
hget key field | 获取值,如果key或field不存在则返回nil | O(1) |
hdel key field [field...] | 删除field,返回结果是成功删除field的个数 | O(k),k是field个数 |
hlen key | 计算field个数 | O(1) |
hmget key field [field...] | 批量获取field | O(k),k是field个数 |
hmset key field value [filed value...] | 批量设置field | O(k),k是field个数 |
hexists key field | 判断field是否存在,存在返回1,不存在返回0 | O(1) |
hkeys key | 获取所有field | O(n),n是field总数 |
hvals key | 获取所有value | O(n),n是field总数 |
hgetall key | 获取所有的field-value | O(n),n是field总数 |
hscan |
|
|
hincrby key field | 对field自增 | O(1) |
hincrbyfloat key field | 对field自增 | O(1) |
hstrlen key field | 计算value的字符串长度 | O(1) |
Hash类型的内部结构有2种:
ziplist:当哈希类型元素field个数小于hash-max-ziplist-entries配置(默认512个)、或者,所有值value都小于hash-max-ziplist-value配置(默认64字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,基于小对象压缩技术,因此在节省内存方面比hashtable更加优秀。
hashtable:当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)。
3. 列表
用来存储多个有序的字符串,每个字符串称为元素element,一个列表最多可以存储2^32-1个元素。在Redis中可以对列表两端插入push和弹出pop、还可以获取指定范围的元素列表、获取指定索引下标的元素等等。可以充当栈和队列的角色。
列表类型有2个特点:①列表中的元素是有序的,可以通过索引下标来获取某个元素/某个范围内的元素列表,索引从0开始。②列表中的元素可以重复。
3.1 命令
3.1.1 从右边插入元素
命令:rpush key value [value......]
3.1.2 从左边插入元素
命令:lpush key value [value......]
3.1.3 向某个元素前/后插入元素
命令:linsert key before/after pivot value
注意事项:linsert命令会从列表中找到等于pivot的元素,然后在其前before或后after插入一个新元素value
3.1.4 获取指定范围内的元素列表
命令:lrange key start end
注意事项:索引下标从左到右分别是0到(N-1),但从右到左分别是-1到-N,另外lrange的end选项包含了自身即包头包尾
3.1.5 获取列表指定索引下标的元素
命令:lindex key index
注意事项:例如当前列表最后一个元素为a:lindex listkey -1.这里可以参考lrange中从右到左的索引下标排序。
3.1.6 获取列表长度
命令:llen key
3.1.7 从列表左侧弹出元素
命令:lpop key
3.1.8 从列表右侧弹出
命令:rpop key
3.1.9 删除指定元素
命令:lrem key count value
注意事项:lrem命令从列表中找到等于value的元素进行删除,根据count选项的不同而分为3种情况:
①count>0,从左到右,删除最多count个元素
②count<0,从右到左,删除最多count绝对值个元素
③count=0,删除所有
3.1.10 按照索引范围修剪列表
命令:ltrim key start end
注意事项:包头包尾
3.1.11 修改指定索引下标的元素
命令:lset key index newValue
3.1.12 阻塞式弹出
命令:blpop key [key...] timeout/brpop key [key...] timeout
注意事项:
①在列表为空的前提下,如果timeout>0则客户端等待timeout秒后才能拿到结果,
如果timeout=0则客户端一直处于等待状态,直到有新数据插入后客户端才拿到数据。
②在列表不为空的前提下,timeout=0则立即返回给客户端
3.1.13 时间复杂度
操作类型 | 命令 | 时间复杂度 |
添加 | rpush | O(k)k是元素个数 |
lpush | O(k)k是元素个数 | |
linsert | O(n)n是pivot距离到表头/表尾的距离 | |
查找 | lrange | O(s+n)s是start偏移量,n是start到end的范围 |
lindex | O(n)n是索引的偏移量 | |
llen | O(1) | |
删除 | lpop | O(1) |
rpop | O(1) | |
lrem | O(n)n是列表长度 | |
ltrim | O(n)n是要裁剪的元素总数 | |
修改 | lset | O(n)n是索引的偏移量 |
blpop | O(1) | |
brpop | O(1) |
3.2 底层实现
ziplist压缩列表:当列表元素个数小于list-max-ziplist-entries参数(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value参数(默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使用。
linkedlist链表:当列表类型无法满足ziplist条件时,Redis会使用linkedlist作为列表的内部实现。
quicklist:Redis3.2提供,以ziplist为节点的linkedlist。
3.3 List命令总结
指令 | 解释 | 指令时间复杂度 |
rpush key value [value...] | 从右边插入元素 | O(k),k是元素个数 |
lpush key value [value...] | 从左边插入元素 | O(k),k是元素个数 |
linsert key before|after pivot value | 向某个元素前或者后插入元素,linsert命令会从列表中找到等于pivot的元素,在其前before或者后after插入一个新元素value | O(n),n是pivot距离列表头或尾的距离 |
lrange key start end | 查找,lrange会获取列表指定索引范围所有的元素。索引下标取值范围有如下特点: ①索引从左到右分别是0到N-1,从右到左分别是-1到-N ②lrange中的end选项包含自身,start选项也包含自身 | O(s+n),s是start偏移量,n是start到end 的范围 |
lindex key index | 获取列表指定索引下标的元素 | O(n),n是索引的偏移量 |
llen key | 获取列表长度 | O(1) |
lpop key | 从列表左侧弹出元素 | O(1) |
rpop key | 从列表右侧弹出元素 | O(1) |
lrem key count value | 删除指定元素value,根据count取值不同分为3种情况: ①count为正数,从左到右,删除最多count个元素 ②count为负数,从右到左,删除最多count绝对值个元素 ③count=0,删除所有元素 | O(n),n是列表长度 |
ltrim key start end | 按照索引范围修剪列表 | O(n),n是要裁剪的元素总数 |
lset key index newValue | 修改指定索引下标的元素 | O(n),n是索引的偏移量 |
blpop key [key...] timeout | lpop的阻塞形式,timeout表示阻塞时间(单位:秒),当timeout=0时则永远阻塞下去直到有元素弹出。 当[key...]如果某个key有值则立即返回给客户端; | O(1) |
brpop key [key...] timeout | rpop的阻塞形式,timeout表示阻塞时间(单位:秒),当timeout=0时则永远阻塞下去直到有元素弹出。 当[key...]如果某个key有值则立即返回给客户端;) | O(1) |
内部编码:
其实,在Redis原理章节中,有个“小对象压缩技术”,说白了就是尽量减少对内存的占用,避免因为内存崩溃。
ziplist:当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),Redis会选用ziplist来作为列表的内部实现来减少内存的使用。
linkedlist:当列表类型无法满足ziplist的条件时,Redis会使用linkedlist作为列表的内部实现。
4. 集合
集合set不允许有重复元素,并且集合中元素是无序的,因此不能通过索引下标来获取元素。一个集合最多可以存储2^32-1个元素。
4.1 命令
4.1.1 添加元素
命令:sadd key element [element...]
注意事项:返回结果为添加成功的元素个数
4.1.2 删除元素
命令:srem key element [element...]
注意事项:返回结果为成功删除元素个数
4.1.3 计算元素个数
命令:scard key
注意事项:scard命令并不会遍历集合set所有元素,而是直接用Redis内部变量,因此该命令的时间复杂度为O(1)。
4.1.4 判断元素是否在集合中
命令:sismember key element
注意事项:存在则返回1,否则返回0.
4.1.5 随机从集合返回指定个数元素
命令:srandmember key [count]
注意事项:count是可选参数,不写默认为1.
4.1.6 从集合随机弹出元素
命令:spop key
注意事项:spop从Redis3.2版本开始也支持count参数,srandmember和spop都是随机从集合选出元素,两者不同的是spop命令执行后,元素会从集合中删除而srandmember则不会。
4.1.7 获取所有元素
命令:smembers key
注意事项:smembers、lrange、hgetall都属于比较重的命令,如果元素过多则存在阻塞Redis的可能性,可以用sscan来完成。
4.1.8 求多个集合的交集
命令:sinter key [key...]
4.1.9 求多个集合的并集
命令:suinon key [key...]
4.1.10 求多个集合的差集
命令:sdiff key [key...]
4.1.11 将交集、并集、差集的结果保存
命令:
sinterstore destination key [key...]
suionstore destination key [key...]
sdiffstore destination key [key...]
4.1.12 时间复杂度
命令 | 时间复杂度 |
sadd | O(k)k是元素个数 |
srem | O(k)k是元素个数 |
scard | O(1) |
sismember | O(1) |
sradmember key [count] | O(count) |
spop | O(1) |
smembers | O(n)n是元素总数 |
sinter/sinterstore | O(m*k)k是多个集合中元素最少的个数,m是键个数 |
suinon/suinonstore | O(k)k是多个集合元素个数和 |
sdiff/sdiffstore | O(k)k是多个集合元素个数和 |
4.2 底层实现
intset整数集合:当集合中元素都是整数、元素个数小于set-max-intset-entries配置(默认512个)时,Redis会选择intset来作为集合的内部实现从而减少内存使用。
hashtable哈希表:当无法满足intset条件时则选择hashtable作为集合内部实现。
4.3 Set集合总结
集合(set)类型也是用来保存多个的字符串元素,但和列表类型不一样的是,集合中不允许有重复元素,并且集合中的元素是无序的,不能通过索引下标获取元素。一个集合最多可以存储232-1个元素。Redis除了支持集合内的增删改查,同时还支持多个集合取交集、并集、差集。
指令 | 解释 | 指令时间复杂度 |
sadd key element [element...] | 添加元素,返回结果为添加成功的元素个数 | O(k),k是元素个数 |
srem key element [element...] | 删除元素,返回结果为成功删除元素个数 | O(k),k是元素个数 |
scard key | 计算元素个数,该指令不会遍历集合所有元素,而是直接用内部变量 | O(1) |
sismember key element | 判断元素是否在集合中,如果给定元素element在集合内则返回1,否则返回0 | O(1) |
srandmember key [count] | 随机从集合返回指定个数元素,count不写则默认为1 | O(count) |
spop key | 从集合中随机弹出元素,然后从集合中删除被弹出的元素 | O(1) |
smembers key | 获取所有元素,如果元素过多,该指令会导致Redis阻塞,建议使用sscan | O(n),n是元素总数 |
sinter key [key....] | 求多个集合的交集 | O(m*k),k是多个集合中元素最少的个数,m是键个数 |
suinon key [key...] | 求多个集合的并集 | O(k),k是多个集合元素个数总和 |
sdiff key [key...] | 求多个集合的差集 | O(k),k是多个集合元素个数总和 |
sinterstore destination key [key...] | 保存交集结果,destination是目标集合 | O(m*k),k是多个集合中元素最少的个数,m是键个数 |
suionstore destination key [key...] | 保存并集结果,destination是目标集合 | O(k),k是多个集合元素个数总和 |
sdiffstore destination key [key...] | 保存差集结果,destination是目标集合 | O(k),k是多个集合元素个数总和 |
集合类型的内部编码有两种:
intset:当集合中的元素都是整数且元素个数小于set-maxintset-entries配置(默认512个)时,Redis会选用intset来作为集合的内部实现,从而减少内存的使用。
hashtable:当集合类型无法满足intset的条件时,Redis会使用hashtable作为集合的内部实现。
5. 有序集合
保留了集合不能重复成员的特性,同时还可以排序。有序集合给每个元素设置一个分数score作为排序的依据。
数据结构 | 是否允许重复元素 | 是否有序 | 有序实现方式 |
列表 | 是 | 是 | 索引下标 |
集合 | 否 | 否 | 无 |
有序集合 | 否 | 是 | 分值 |
5.1 命令
5.1.1 添加成员
命令:zadd key score member [score member...]
注意事项:返回结果代表成功添加成员的个数.有序集合比集合提供了排序字段,因此zadd的时间复杂度O(log(n)),sadd时间复杂度为O(1)。
参数选项:Redis3.2为zadd添加了nx、xx、ch、incr四个选项:
nx:member必须不存在才可以设置成功
xx:member必须存在才可以设置成功
ch:返回此次操作后有序集合元素和分数发生变化的个数
incr:对score做增加,相当于zincrby
5.1.2 计算成员个数
命令:zcard key
注意事项:跟集合类型的scard命令一样,zcard时间复杂度为O(1)
5.1.3 计算某个成员的分数
命令:zscore key member
注意事项:如果成员不存在则返回nil
5.1.4 计算成员的排名
命令:zrank key member/zrevrank key member
注意事项:zrank是分数从低到高返回排名,zrevrank反之。
5.1.5 删除成员
命令:zrem key member [member...]
注意事项:返回结果为成功删除的个数。
5.1.6 增加成员的分数
命令:zincrby key increment member
5.1.7 返回指定排名范围的成员
命令:zrange key start end [withscores]/zrevrange key start end [withscores]
注意事项:zrange是从低到高返回,zrevrange反之。
5.1.8 返回指定分数范围的成员
命令:
zrangebyscore key min max [withscores] [limit offset count]
zrevrangebyscore key max min [withscores] [limit offset count]
注意事项:zrangebyscore按照分数从低到高返回,zrevrangebyscore反之。
参数选项:
- withscores选项会同时返回每个成员的分数。
- [limit offset count]选项可以限制输出的起始位置和个数。
- 同时min和max还支持开区间(小括号)和闭区间(中括号),-inf和+inf分别代表无限小和无限大。
5.1.9 返回指定分数范围成员个数
命令:zcount key min max
5.1.10 删除指定排名内的升序元素
命令:zremrangebyrank key start end
5.1.11 删除指定分数范围的成员
命令:zremrangebyscore key min max
5.1.12 交集
命令:
zinterstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
参数选项:
- destination:交集计算结果保存到这个键。
- numkeys:需要做交集计算键的个数。
- key[key...]:需要做交集计算的键。
- weights weight[weight...]:每个键的权重,在做交集计算时,每个键中的每个member会将自己分数乘以这个权重,每个键的权重默认是1。
- aggregate sum|min|max:计算成员交集后,分值可以按照sum(和)、min(最小值)、max(最大值)做汇总,默认值是sum。
5.1.13 并集
命令:
zunionstore destination numkeys key [key ...] [weights weight [weight ...]] [aggregate sum|min|max]
注意事项:该命令的所有参数和zinterstore是一致的。
5.1.14 时间复杂度
命令 | 时间复杂度 |
Zadd | O(K*log(n))。K是添加成员的个数,n是当前有序集合成员个数。 |
Zcard | O(1) |
zscore | O(1) |
Zrank/zrevrank | O(log(n)) |
Zrem | O(k*log(n))。K是删除成员的个数,n是当前有序集合成员个数 |
Zincrby | O(log(n)) |
Zrange/zrevrange | O(log(n)+k)。K是要获取的成员个数,n是当前有序集合成员个数 |
Zrangebyscore/zrevrangebyscore | O(log(n)+k)。K是要获取的成员个数,n是当前有序集合成员个数 |
zcount | O(log(n)) |
Zremrangebyrank/zremrangebyscore | O(log(n)+k)。K是要获取的成员个数,n是当前有序集合成员个数 |
Zinterstore | O(n*k)+O(m*log(m))。n是成员数最小的有序集合成员个数,k是有序集合的个数,m是结果集中成员个数 |
zunionstore | O(n)+O(m*log(m))。n是所有有序集合成员个数和,m是结果集中成员个数。 |
5.2 底层实现
Ziplist压缩列表:当有序集合的元素个数小于zset-max-ziplistentries
配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配
置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist
可以有效减少内存的使用。
Skiplist跳跃表:当ziplist条件不满足时,有序集合会使用skiplist作
为内部实现,因为此时ziplist的读写效率会下降。
5.3 有序集合命令总结
它保留了集合不能有重复成员的特性,但不同的是,有序集合中的元素可以排序。
指令 | 解释 | 指令时间复杂度 |
zadd key score member [score member...] | 添加成员,返回结果代表成功添加成员的个数。 nx:member必须不存在才能设置成功。 xx:member必须存在才能设置成功。 ch:返回此次操作后有序集合元素和分数发生变化的个数。 incr:对score做增加。 | O(k * log(n)),k是添加成员的个数,n是当前有序集合成员个数 |
zcard key | 计算成员个数 | O(1) |
zscore key member | 计算某个成员的分数,如果成员不存在则返回nil | O(1) |
zrank key member zrevrank key member | 计算成员的排名,zrank是分数从低到高返回排名,zrevrank是分数从高到低返回排名 | O(log(n)),n是当前有序集合成员个数 |
zrem key member[member...] | 删除成员,返回结果为成功删除的个数 | O(k * log(n)),k是删除成员的个数,n是当前有序集合成员个数 |
zincrby key increment member | 增加成员的分数 | O(log(n)),n是当前有序集合成员个数 |
zrange key start end [withscores] Zrevrange key start end [withscores] | 返回指定排名范围的成员, zrange是从低到高返回,zrevrange反之。加上withscores选项则同时返回分数 | O(log(n) + k),k是要获取的成员个数,n是当前有序集合成员个数 |
zrangebyscore key min max [withscores][limit offset count] zrevrangebyscore key max min [withscores][limit offset count] | 返回指定分数范围的成员。zrangebyscore按照分数从低到高返回,zrevrangebyscore反之。 Withscores同时返回每个成员的分数,而limit offset count则限制输出的起始位置和个数。 同时min和max还支持开区间(小括号)和闭区间(中括号),-inf和+inf分别代表无限小和无限大。 | O(log(n) + k),k是要获取的成员个数,n是当前有序集合成员个数 |
zcount key min max | 返回指定分数范围成员个数 | O(log(n)),n是当前有序集合成员个数 |
zremrangebyrank key start end | 删除指定排名内的升序元素,返回结果为成功删除的个数 | O(log(n) + k),k是要删除的成员个数,n是当前有序集合成员个数 |
zremrangebyscore key min max | 删除指定分数范围的成员,返回结果为成功删除的个数 | O(log(n) + k),k是要删除的成员个数,n是当前有序集合成员个数 |
zinterstore destination numkeys key [key...][weights weight [weight...]][aggregate sum|min|max] | 交集 Destination交集计算结果保存到这个键 Numkeys需要做交集计算键的个数 Key[key...]需要做交集计算的键 Weights weight[weight]每个键的权重,默认值为1 Aggregate sum|min|max计算成员交集后,分值可以按照sum和、min最小值、max最大值做汇总,默认值是sum | O(n*k)+O(m*log(m)),n是成员数最小的有序集合成员个数,k是有序集合的个数,m是结果集合中成员个数 |
zunionstore destination numkeys key [key...][weights weight[weight...]][aggregate sum|min|max] | 并集运算,该命令的所有参数和zinterstore是一致的 | O(n)+O(m*log(m)),n是所有有序集合成员个数和,m是结果集合中成员个数 |
有序集合类型的内部编码有两种:
ziplist:当有序集合的元素个数小于zset-max-ziplistentries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,Redis会用ziplist来作为有序集合的内部实现,ziplist可以有效减少内存的使用。
skiplist:当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因为此时ziplist的读写效率会下降。
6. 键通用操作命令
6.1 键重命名
命令:rename key newkey
注意事项:
①如果在rename之前,键newkey已经存在则将被覆盖。为了防止被强行rename,Redis提供了renamenx命令,确保只有newkey不存在时才能被覆盖,返回结果是0则代表没有完成重命名操作;
②由于重命名键期间会执行del命令删除旧的键,如果键对应的值比较大,会存在阻塞Redis的可能性;
③如果rename和renamenx中的key和newkey如果是相同的,在Redis3.2和之前版本返回结果略有不同:Redis3.2中会返回OK,Redis3.2之前的版本会提示错误。
6.2 随机返回一个键
命令:randomkey
6.3 键过期
命令:
expireat key seconds键在seconds秒后过期;
expireat key timestamp键在秒级时间戳timestamp后过期;
ttl和pttl命令都可以查询键的剩余过期时间,但pttl精度更高,可以达到毫秒级别,pttl有3种返回值:正整数代表键剩余的过期毫秒;-1则代表没有设置过期时间;-2键不存在;
pexpire key milliseconds键在milliseconds毫秒后过期;
pexpireat key milliseconds-timestamp键在毫秒级时间戳timestamp后过期;
注意事项:
①如果expire key的键不存在,返回结果为0:
②如果过期时间为负值,键会立即被删除,犹如使用del命令一样:
③persist命令可以将键的过期时间清除:
④对于字符串类型键,执行set命令会去掉过期时间;
⑤Redis不支持二级数据结构(例如哈希、列表)内部元素的过期功能;
⑥setex命令作为set+expire的组合,不但是原子执行,同时减少了一次网络通讯的时间;
6.4 迁移键
命令:move key db
注意事项:move命令用于在Redis内部进行数据迁移,Redis内部可以有多个数据库,彼此在数据上是相互隔离的,move key db就是把指定的键从源数据库移动到目标数据库中。
命令:dump + restore
dump key
restore key ttl value
迁移过程:dump+restore实现在不同Redis实例之间进行数据迁移的功能,整个迁移过程分为2步:
1.在源Redis上,dump命令将键和值都序列化,格式采用的是RDB格式;
2.在目标Redis上,restore命令将上面序列化的值进行复原,其中ttl参数代表过期时间,如果ttl=0代表没有过期时间;
注意事项:一方面整个迁移过程并非原子性的而是通过客户端分步完成的,另一方面迁移过程是开启了两个客户端连接
命令:migrate host port key|”” destination-db timeout [copy] [replace] [keys key [key...]]
参数说明:
host:目标Redis的IP地址
port:目标Redis的端口
key|””:3.0.6之前migrate只支持迁移一个键,因此这里是要迁移的键;3.0.6之后支持迁移多个键,如果当前需要迁移多个键,此处为空字符串
destination-db:目标Redis的数据库索引,例如要迁移到0号数据库,这里就写0
Timeout:迁移的超时时间,单位为毫秒
[copy]:如果添加此选项,迁移后并不删除源键
[replace]:如果添加此选项,migrate不管目标Redis是否存在该键都会正常迁移并进行数据覆盖
[keys key[key...]]:要迁移的多个键,例如要迁移key1、key2、key3,此处填写:keys key1 key2 key3
迁移过程:migrate命令也用于在Redis实例之间进行数据迁移,实际上migrate命令就是把dump+restore+del命令进行组合从而简化了操作流程。Migrate命令具有原子性,从3.0.6版本以后支持迁移多个键功能从而提高迁移效率。
注意事项:
第一整个过程是原子执行的,不需要在多个Redis实例上开启客户端的,只需要在源Redis上执行migrate命令即可。
第二migrate命令的数据传输直接在源Redis与目标Redis完成。
第三目标Redis完成restore后会发送OK给源Redis,源Redis接收后会根据migrate对应的选项来决定是否在源Redis上删除对应的键
6.5 遍历键
命令:keys pattern,又叫全量遍历键
注意事项:pattern可以使用glob风格的通配符,例如:*代表匹配任意字符、.代表匹配一个字符、[]代表匹配部分字符、\x用来做转义,由于Redis是单线程架构,如果Redis包含了大量的键,使用pattern可能会造成Redis阻塞
命令:scan,又叫渐进式遍历
scan cursor [match pattern] [count number]
参数说明:
Cursor必须参数,cursor是一个游标,第一次遍历从0开始,每次scan遍历完都会返回当前游标的值,直到游标值为0表示遍历结束
Match pattern是可选参数,它的作用是做模式匹配
Count number是可选参数,作用是表明每次要遍历的键个数,默认值是10,该参数可以适当增大
注意事项:从2.8后才提供scan命令用来弥补keys缺点,keys命令执行时会遍历所有键,而scan采用渐进式遍历,每次scan命令的时间复杂度是O(1)。Scan并非完美无瑕,如果在scan过程中键发生增加、修改、删除,那么新增的键可能没有遍历到,遍历出重复的键等情况
6.6 数据库管理
切换数据库:select dbIndex,Redis只用数字作为多个数据库的实现且默认配置有16个数据库;
清除数据库:flushdb/flushall,flushdb只清除当前数据库而flushall会清除所有数据库,如果当前数据库键值数量比较多时,flushdb/flushall存在阻塞Redis的可能性。