首页 » SEO优化 » phpreids删除key技巧_redis删除key

phpreids删除key技巧_redis删除key

访客 2024-12-17 0

扫一扫用手机浏览

文章目录 [+]

redis-cli --raw keys \"大众ops-coffee-\公众 | xargs redis-cli del

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

phpreids删除key技巧_redis删除key

由于Redis的单线程做事模式,命令keys会壅塞正常的业务要求,如果你一次keys匹配的数量过多或者在del的时候碰着大key,都会直接导致业务的不可用,乃至造成redis宕机的风险

phpreids删除key技巧_redis删除key
(图片来自网络侵删)

以是我们在生产环境中应该避免利用上边的方法,那有什么优雅的方法来办理呢?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的优雅删除就全部实现了,生产环境择优利用。

标签:

相关文章

主从复制php技巧_Mysql高可用主从复制

许可将来自一个MySQL数据库做事器(主理事器)的数据复制到一个或多个MySQL数据库做事器(从做事器)。根据从数据库做事器配置,...

SEO优化 2024-12-18 阅读0 评论0