redis中api理解与使用(二)

本文深入介绍了 Redis 中的列表、集合和有序集合的常用命令、内部编码以及键管理,包括如何插入和删除元素、集合间的操作、阻塞操作、数据结构的内存优化及键的过期、迁移等。
摘要由CSDN通过智能技术生成
4、列表(list)

列表类型是用来存储多个有序的字符串(可以重复),一个列表最多存储2^32 -1个元素。redis中可以对列表两端插入和弹出,还可以获取指定范围的元素列表、获取指定索引下标的元素等。

4.1 常用命令:
操作类型操作
添加rpush/lpush/linsert
查找lrang/lindex/llen
删除lpop/rpop/lrem/ltrim
修改lset
阻塞操作blpop/brpop

具体实现参见命令详情:
(1)、查找命令:
lrange/lindex下标都是从零开始,lrange命令end位置包含在查询当中;

(2)、删除命令:

命令解释
lrem key count value删除命令

lrem命令会从列表中找到等于value的元素进行删除,根据count的不同分为三种:
1)、count > 0,从左到右删除最多count个元素;
2)、count < 0,从右到左删除最多count个元素;
3)、count = 0,删除所有;

(3)、阻塞操作:
blpop和brpop是lpop和rpop的阻塞版本,除了弹出方向不同,使用方法基本相同,命令包含两个参数:

命令解释
blpop key [key …] timeout左出栈
brpop key [key …] timeout右出栈

1)、key [key …]:多个列表的键
2)、timeout:阻塞时间(单位:秒)
使用brpop注意点:
1)、如果是多个键,那么brpop会从左至右遍历键,一旦有一个键能弹出元素,客户端立即返回;
2)、如果多个客户端对同一个键执行brpop,那么最先执行brpop命令的客户端可以获取到弹出的值;

4.2 内部编码:

列表类型内部编码有两种:
(1)、ziplist(压缩列表):当列表的元素个数小于list-max-ziplist-entries配置(默认512个),同时列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节),redis会选择ziplist来作为列表的内部实现来减少内存的使用;
(2)、linkedlist(链表):当列表类型无法满足ziplist的条件时,redis会使用linkedlist作为列表的内部实现;
(3)、quicklist(快速列表):以ziplist为节点的linkedlist,结合了两者的优势;

5、集合(set)
集合也是用来保存多个字符串元素,同列表不同在于集合中不允许有重复元素,并且集合元素是无序的,无法通过索引下标获取元素。集合最多包含2^32 - 1个元素,除了一般命令,集合还提供多个集合取交集、并集、差集等操作。
5.1 常用命令:
5.1.1 集合内操作:
命令解释
sadd key element [element …]添加:结果为添加成功的元素个数
srem key element [element …]删除:结果为成功删除元素个数
scard key计算元素个数(时间复杂度O(1)):不会遍历所有元素,直接使用redis内部变量
sismember key element判断元素是否在集合中:给定元素存在返回1,反之返回0
srandmember key [count]随机从集合返回指定个数元素:count可选,默认为1
spop key从集合随机弹出一个元素
smember key获取所有元素
5.1.2 集合间操作:
命令解释
sinter key [key …]求多个集合交集
sunion key [key …]求多个集合的并集
sdiff key [key …]求多个集合的差集
sinterstore destination key [key …]将交集的结果保存
sunionstore destination key [key …]将并集的结果保存
sdiffstore destination key [key …]将差集的结果保存

集合间的运算在元素较多的情况下会比较耗时,故redis提供了以下三个命令(原命令+store)将集合间的交集、并集、差集的结果保存在destination key中

5.2 内部编码:

集合类型内部编码有两种:
(1)、intset(整数集合):当集合中的元素都是整数且元素个数小于set-max-intset-entries配置(默认512个)时,redis会选用intset作为集合的内部实现,从而减少内存的使用;
(2)、hashtable(哈希表):当集合类型无法满足intset的条件时,redis会选用hashtable来作为集合的内部实现;

6、有序集合(zset)
保留了集合不能有重复成员的特性,不同的是有序集合中的元素可以排序。
6.1 常用命令:
6.1.1 集合内:
命令解释
zadd key [nx|xx] [ch] [incr] score member [score member …]添加成员

参数说明:
1)、nx:member必须不存在才可设置成功,用于添加;
2)、xx:member必须存在才可设置成功,用于更新;
3)、ch:返回此次操作后,有序集合和分数发生变化的个数;
4)、incr:对score进行增加,相当于只有的zincrby;
有序集合相比集合提供了排序字段,但在时间复杂度上zadd为O(log(n)),集合为O(1);

命令解释
scard key计算成员个数
zscore key member计算某个成员的分数
zrank key member计算成员排名:zrank从低到高,zrevrank反之
zrevrank key member计算成员排名:zrank从低到高,zrevrank反之
zrem key member [memner …]删除成员
zincrby key increment member增加成员分数
zrange key start end [withscores]返回指定排名范围的成员
zrevrange key start end [withscores]返回指定排名范围的成员
zrangebyscore key min max [withscores] [limit offset count]返回指定分数范围的成员
zrevrangebyscore key min max [withscores] [limit offset count]返回指定分数范围的成员

其中zrangebyscore按照分数从低到高,zrevrangebyscore反之;
同时min和max还支持开区间(小括号)和闭区间(中括号),-inf和+inf分别表示无限小和无限大;

命令解释
zcount key min max返回指定分数范围成员个数
zremrangebyrank key start end删除指定排名内的升序元素
zremrangebyscore key min max删除指定分数范围的成员
6.1.2 集合间的操作:
命令解释
zinterstore destination numkeys key [key …] [weights weight [weight …]] [aggregate summin

参数说明:
1)、destination:交集计算结果保存到这个键;
2)、numkeys:需要做交集计算键的个数;
3)、key [key …]:需要做交集计算的键;
4)、weights weight [weight …]:每个键的权重,默认为1;
5)、aggregate sum|min|max:计算成员交集后,分值可以按照sum、min、max做汇总,默认值为sum;

命令解释
zunionstore destination numkeys key [key …] [weights weight [weight …]] [aggregate sum|min|max]并集

命令参数同zinterstore;

6.2 内部编码:

有序集合内部编码有两种:
(1)、ziplist(压缩列表):当有序集合的元素个数小于zset-max-ziplist-entries配置(默认128个),同时每个元素的值都小于zset-max-ziplist-value配置(默认64字节)时,redis会使用该结构作为有序结合的内部实现,ziplist可有效减少内存的使用;
(2)、skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因为此时ziplist的读写效率会下降;

7、键管理
7.1 单个键管理:

1、键重命名:

命令解释
rename key newkey键重命名

如果在rename之前,键已经存在,则对应键的值将会被覆盖;
为防止强行rename,redis提供了renamenx命令来确保newkey不存在时才覆盖;
由于重命名键期间会执行del命令删除旧的键,如果键对应的值比较大,会存在阻塞redis的可能;

2、随机返回一个键(已存在的):

命令解释
randomkey随机返回一个键(已存在的)

3、键过期:

命令解释
expire key seconds键在seconds秒后过期
expireat key timestamp键在秒级时间戳timestamp后过期

除了expire、ttl命令之外,redis还提供了expireat、pexpire、pexpireat、pttl、persist等一系列命令:
ttl和pttl都可以查询键的剩余过期时间,但pttl精度更高可以达到毫秒级别,有3种返回值:
1)、大于等于0的整数:键的剩余过期时间(ttl是秒,pttl是毫秒);
2)、-1:键没有设置过期时间;
3)、-2:键不存在;

除此之外毫秒级过期方案:

命令解释
pexpire key milliseconds键在milliseconds毫秒后过期
pexpireat key milliseconds-timestamp键在毫秒时间戳timestamp后过期

使用redis过期相关命令时,需注意一下几点:
1)、如果expire key的键不存在,返回结果为0;
2)、如果过期时间为负值,键会立即被删除,犹如使用del命令一样;
3)、persist命令可以将键的过期时间清除;
4)、对于字符串类型键,执行set命令会去掉过期时间;
5)、redis不支持二级数据结构(例如哈希、列表)内部元素的过期功能,例如不能对列表类型的一个元素做过期时间设置;
6)、setex命令作为set+expire的组合,不但是原子执行,同时减少了一次网络通讯的时间;

4、键迁移:
(1)、move

命令解释
move key db内部迁移

move 命令用于在redis内部进行数据迁移,redis内部可以有多个数据库,彼此间在数据上是相互隔离的;

(2)、dump + restore

命令解释
dump keydump键值
restore key ttl value导入

dump + restore可以实现在不同的redis实例之间进行数据迁移的功能,整个迁移的过程分为两步:
1)、在源redis上,dump命令会将键值序列化,格式采用的是RDB格式;
2)、在目标redis上,restore命令将上面序列化的值进行复原,其中ttl参数代表过期时间,如果ttl=0代表没有过期时间;
注意点:
I、整个迁移过程并非原子性,而是通过客户端分步完成的;
II、迁移过程是开启了两个客户端连接,故dump结果不是在源redis和目标redis之间进行传输;

(3)、migrate:

命令解释
migrate host port key | “” destination-db timeout [copy] [replace] [keys key [key …]]迁移

migrate命令具有原子性,其也是在redis实例间进行数据迁移,实际上migrate命令就是将dump、restore、del三个命令进行组合,从而简化操作流程。
其与dump + restore命令的差别:
1)、整个过程是原子执行的,不需要在多个redis实例间开启客户端,只需要在源redis上执行migrate命令即可;
2)、migrate命令的数据传输直接在源redis和目标redis上完成;
3)、目标redis完成restore命令后会发送OK给源redis,源redis接收后根据migrate对应的选项来决定是否在源redis上删除对应的键;
migrate命令参数简介:
1)、host:目标redis的ip地址;
2)、port:目标redis的端口;
3)、key|"":需要迁移的键(单个),支持多个(此时为空字符串,在之后添加);
4)、destination-db:目标redis的数据库索引;
5)、timeout:迁移的超时时间,单位为毫秒;
6)、[copy]:如果添加此项,迁移后并不删除源键;
7)、[replace]:若添加该选项,migrate不管目标redis是否存在该键都会正常迁移进行数据覆盖;
8)、[keys key [key …]]:迁移多个键;

7.2 遍历键:

1、全量遍历键:

命令解释
keys pattern全量遍历

key命令支持pattern匹配,其使用的是glob风格的通配符:
1)、* :代表匹配任意字符;
2)、? :代表匹配一个字符;
3)、[] :代表匹配部分字符;
4)、\x :用来转义,例如星号、问号;

考虑到redis的单线程架构,为避免阻塞可在如下情况使用:
1)、在一个不对外提供服务的redis节点上执行,这样不会阻塞客户端的请求,但是会影响主从复制;
2)、确认键值比较少的情况下使用;
3)、使用scan命令进行渐进式遍历;

2、渐进式遍历:

命令解释
scan cursor [match pattern] [count number]渐进式遍历

redis存储键值对实际使用的是hashtable的数据结构,每次执行scan类似于在字典当中扫描一部分键,直到将字典中的所有键遍历完毕。
1)、cursor:代表一个游标,第一次遍历从0开始,每次scan遍历完都会返回当前游标的值,直到游标值为0表示遍历结束;
2)、match pattern:模式匹配;
3)、count number:表示每次要遍历的键个数,默认为10;

除scan外,redis提供面向哈希类型、集合类型、有序季节类型的扫描遍历命令,解决诸如hgetall、smembers、zrange可能产生的阻塞问题,对应的命令分别为hscan、sscan、zscan,用法同scan类似;

渐进式遍历可以有效解决keys命令可能产生的阻塞问题,但scan命令同样存在不足,如果在scan的过程中如果有键的变化(增加、删除、修改),那么就有可能导致新的数据无法扫到,而原来存在的数据重复扫描的问题。

7.3 数据库管理:

1、切换数据库:

命令解释
select dbIndex切换db

不同数据库之间的数据没有任何关联,甚至可以存在相同的键;
该功能在redis的分布式实现redis cluster只允许使用0号数据库;
新版本中废弃多数据库原因:
1)、redis是单线程的,使用多个数据库其实仍然使用的同一个cpu资源;
2)、多数据库的使用方式会让调试和运维不同业务的数据库变得困难;
3)、部分redis客户端不支持多数据库的方式;

2、flushdb/flushall:

flushdb只清除当前数据库数据,而flushall则会清除所有库的数据;
存在的问题:
1)、flushdb/flushall命令会将所有数据清除,一旦误操作后果不堪设想,可以使用rename-command配置来规避;
2)、如果数据库的键值比较多,flushdb/flushall存在阻塞redis的可能性;

参考《redis开发与运维》

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值