Redis如何优雅的删除特定前缀key

 更新时间:2019年06月17日 08:46:44   作者:37丫37  
这篇文章主要给大家介绍了关于Redis如何优雅的删除特定前缀key的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Redis具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

前言

还在用keys命令模糊匹配删除数据吗?这就是一颗随时爆炸的炸弹!

Redis中没有批量删除特定前缀key的指令,但我们往往需要根据前缀来删除,那么究竟该怎么做呢?可能你一通搜索后会得到下边的答案

redis-cli --raw keys "ops-coffee-*" | xargs redis-cli del

直接在linux下通过redis的keys命令匹配到所有的key,然后调用系统命令xargs来删除,看似非常完美,实则风险巨大

因为Redis的单线程服务模式,命令keys会阻塞正常的业务请求,如果你一次keys匹配的数量过多或者在del的时候遇到大key,都会直接导致业务的不可用,甚至造成redis宕机的风险

所以我们在生产环境中应当避免使用上边的方法,那有什么优雅的方法来解决呢?SCAN!

SCAN介绍及使用

Redis从2.8版本开始支持scan命令,SCAN命令的基本用法如下:

SCAN cursor [MATCH pattern] [COUNT count]

cursor: 游标,SCAN命令是一个基于游标的迭代器,SCAN命令每次被调用之后,都会向用户返回一个新的游标,用户在下次迭代时需要使用这个新游标作为SCAN命令的游标参数,以此来延续之前的迭代过程,直到服务器向用户返回值为0的游标时,一次完整的遍历过程就结束了

MATCH: 匹配规则,例如遍历以ops-coffee-开头的所有key可以写成ops-coffee-*,中间包含-coffee-的可以写成*-coffee-*

COUNT:  COUNT选项的作用就是让用户告知迭代命令,在每次迭代中应该从数据集里返回多少元素,COUNT只是对增量式迭代命令的一种提示,并不代表真正返回的数量,例如你COUNT设置为2有可能会返回3个元素,但返回的元素数据会与COUNT设置的正相关,COUNT的默认值是10

以下是一个SCAN命令的迭代过程示例:

127.0.0.1:6379> scan 0 MATCH ops-coffee-* 
1) "38"
2) 1) "ops-coffee-25"
 2) "ops-coffee-19"
 3) "ops-coffee-29"
 4) "ops-coffee-10"
 5) "ops-coffee-23"
 6) "ops-coffee-5"
 7) "ops-coffee-14"
 8) "ops-coffee-16"
 9) "ops-coffee-11"
 10) "ops-coffee-15"
 11) "ops-coffee-7"
 12) "ops-coffee-1"
127.0.0.1:6379> scan 38 MATCH ops-coffee-* COUNT 1000
1) "0"
2) 1) "ops-coffee-13"
 2) "ops-coffee-9"
 3) "ops-coffee-21"
 4) "ops-coffee-6"
 5) "ops-coffee-30"
 6) "ops-coffee-20"
 7) "ops-coffee-2"
 8) "ops-coffee-12"
 9) "ops-coffee-28"
 10) "ops-coffee-3"
 11) "ops-coffee-26"
 12) "ops-coffee-4"
 13) "ops-coffee-31"
 14) "ops-coffee-8"
 15) "ops-coffee-22"
 16) "ops-coffee-27"
 17) "ops-coffee-18"
 18) "ops-coffee-24"
 19) "ops-coffee-17"

SCAN命令返回的是一个包含两个元素的数组,第一个数组元素是用于进行下一次迭代的新游标,而第二个数组元素则是一个数组,这个数组中包含了所有被迭代的元素

上面这个例子的意思是扫描所有前缀为ops-coffee-的key

第一次迭代使用0作为游标,表示开始一次新的迭代,同时使用了MATCH匹配前缀为ops-coffee-的key,返回了游标值38以及遍历到的数据

第二次迭代使用的是第一次迭代时返回的游标,也即是命令回复第一个元素的值38,同时通过将COUNT选项的参数设置为1000,强制命令为本次迭代扫描更多元素

在第二次调用SCAN命令时,命令返回了游标0,这表示迭代已经结束,整个数据集已经被完整遍历过了

KEYS命令的时间复杂度为O(n),而SCAN命令会将遍历操作分解成m次时间复杂度为O(1)的操作来执行,从而解决使用keys命令遍历大量数据而导致服务器阻塞的情况,使用下边的指令可以达到优雅删除的目的:

redis-cli --scan --pattern "ops-coffee-*" | xargs -L 2000 redis-cli del

其中xargs -L指令表示xargs一次读取的行数,也就是每次删除的key数量,一次读取太多xargs会报错

其他几种数据结构的优雅删除

类似的SCAN命令,对于Redis不同的数据类型还有另外几个SSCAN、HSCAN和ZSCAN,使用方法类似:

> sscan ops-coffee 0 MATCH v1*
1) "7"
2) 1) "v15"
 2) "v13"
 3) "v12"
 4) "v10"
 5) "v14"
 6) "v1"

与SCAN命令不同的是这几个命令需要多加一个key的参数,例如上边的ops-coffee

对于一个大的set key,借助sscan使用下边的代码可以实现优雅的批量删除:

import redis

def del_big_set_key(key_name):
 r = redis.StrictRedis(host='localhost', port=6379)

 # count表示每次删除的元素数量,这里每次删除300元素
 for key in r.sscan_iter(name=key_name, count=300):
 r.srem(key_name, key)

del_big_set_key('ops-coffee')

对于一个大的hash key,则可借助hscan使用下边的代码实现优雅的删除:

import redis

def del_big_hash_key(key_name):
 r = redis.StrictRedis(host='localhost', port=6379)

 # hscan_iter获取出来的结果是个元祖,下边hdel删除用key[0]取到key
 for key in r.hscan_iter(name=key_name, count=300):
 r.hdel(key_name, key[0])

del_big_hash_key('ops-coffee')

对于大的有序集合的删除就比较简单了,直接根据zremrangebyrank排行范围删除

import redis

def del_big_sort_key(key_name):
 r = redis.StrictRedis(host='localhost', port=6379)

 while r.zcard(key_name) > 0:
 # 判断集合中是否有元素,如有有则删除排行0-99的元素
 r.zremrangebyrank(key_name, 0, 99)

del_big_sort_key('ops-coffee')

big list大列表的删除可以参考上边这个方法,通过llen判断数量,然后ltrim移除范围内的元素,这里不赘述

至此对于Redis的五中数据结构大key的优雅删除就全部实现了,生产环境择优使用~

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对程序员之家的支持。

相关文章

  • 基于redis乐观锁实现并发排队

    基于redis乐观锁实现并发排队

    这篇文章主要介绍了基于redis乐观锁实现并发排队的相关资料,需要的朋友可以参考下
    2022-12-12
  • Govern Service 基于 Redis 的服务治理平台安装过程详解

    Govern Service 基于 Redis 的服务治理平台安装过程详解

    Govern Service 是一个轻量级、低成本的服务注册、服务发现、 配置服务 SDK,通过使用现有基础设施中的 Redis 不用给运维部署带来额外的成本与负担,接下来通过本文给大家分享Govern Service 基于 Redis 的服务治理平台的相关知识,感兴趣的朋友一起看看吧
    2021-05-05
  • Redis遍历所有key的两个命令(KEYS 和 SCAN)

    Redis遍历所有key的两个命令(KEYS 和 SCAN)

    这篇文章主要介绍了Redis遍历所有key的两个命令(KEYS 和 SCAN),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • Redis增减库存避坑的实现

    Redis增减库存避坑的实现

    在电商平台或者仓库管理系统中,库存的管理是非常重要的一项任务,本文主要介绍了Redis增减库存避坑的实现,具有一定的参考价值,感兴趣的可以了解一下
    2024-02-02
  • Redis 的 GeoHash详解

    Redis 的 GeoHash详解

    这篇文章主要介绍了Redis 的 GeoHash详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • 详解redis数据结构之压缩列表

    详解redis数据结构之压缩列表

    这篇文章主要介绍了详解redis数据结构之压缩列表的相关资料,压缩列表在redis中的结构体名称为ziplist,其是redis为了节约内存而声明的一种数据结构,需要的朋友可以参考下
    2017-05-05
  • 动态添加Redis密码认证的方法

    动态添加Redis密码认证的方法

    本篇文章主要介绍了动态添加Redis密码认证的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-06-06
  • redis?lua脚本解决高并发下秒杀场景

    redis?lua脚本解决高并发下秒杀场景

    这篇文章主要为大家介绍了redis?lua脚本解决高并发下秒杀场景,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Redis生成全局唯一ID的实现方法

    Redis生成全局唯一ID的实现方法

    全局唯一ID生成器是一种在分布式系统下用来生成全局唯一ID的工具,本文主要介绍了Redis生成全局唯一ID的实现方法,具有一定的参考价值,感兴趣的可以了解一下
    2022-06-06
  • 设置Redis最大占用内存的实现

    设置Redis最大占用内存的实现

    本文主要介绍了设置Redis最大占用内存的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-05-05

最新评论

?


http://www.vxiaotou.com