Redis 批量删除键

Redis 批量删除键

1. 简介

在Redis中批量优雅的删除大量键是一个很麻烦的问题,下面例举常用的方法和优缺点。

2. keys+del命令

使用keys使用查找所有匹配的键,然后在使用del一起批量删除。

优点

  1. 操作简单。

缺点

  1. 查找性能特别差,需要遍历所有键。如果redis key特别多,还有可能造成redis短时间无法提供服务。
  2. 网络性能占用多,所有匹配键都需要发送到redis客户端,如果匹配键特别多会占用大量网络带宽(这个问题可以通过Lua脚本来解决)。
  3. 占用内存多,需要大量内存暂存已经找到的键。
py 复制代码
import redis

r = redis.Redis(host='127.0.0.1', port=6379, db=0)

# 查找
keys = r.keys("example-*")
# 删除
r.delete(*keys)

3. SCAN命令

  1. 使用SCAN命令迭代匹配特定模式的键。
  2. 对于每次SCAN迭代返回的键,使用DEL命令进行删除。
  3. 重复上述步骤,直到SCAN命令返回的游标为0,表示迭代完成。

优点

  1. 非阻塞,不会影响Redis服务器的其他操作。
  2. 可以控制每次迭代的键数量,减少内存占用。

缺点

  1. 在高并发场景下,很难保证所有匹配的键都完全删除,需要多次迭代。
py 复制代码
import redis

r = redis.Redis(host='127.0.0.1', port=6379, db=0)

cursor = 0  # 以0开始
while True:
    cursor, keys = r.scan(cursor=cursor, match='example-*', count=100)
    if cursor == 0:  # 以0结束
        break

    if keys:
        r.delete(*keys)

4. UNLINK命令

UNLINK命令是Redis提供的一个异步删除命令,与DEL命令不同,UNLINK命令会立即返回,而删除操作将在后台异步进行。

  1. 使用SCAN命令或KEYS命令获取要删除的键列表。
  2. 使用UNLINK命令代替DEL命令进行删除。

优点

  1. 异步删除,不会阻塞Redis服务器。

缺点

  1. 删除的完成时间不可预测。
  2. 在某些情况下可能需要额外的逻辑,保证在需要删除的键已经删除。
py 复制代码
import redis

r = redis.Redis(host='127.0.0.1', port=6379, db=0)

cursor = 0  # 以0开始
while True:
    cursor, keys = r.scan(cursor=cursor, match='example-*', count=100)
    if cursor == 0:  # 以0结束
        break

    if keys:
        r.unlink(*keys)

5. Lua脚本

上面所有的示例都可以转换成Lua脚本版本,下面只演示其中一个。

优点

  1. 大量降低redis客户端redis服务器的RTT时间。
  2. 大量节约了redis服务器的带宽。

缺点

  1. 提高操作的复杂。
py 复制代码
import redis

r = redis.Redis(host='127.0.0.1', port=6379, db=0)

lua_script = """
local key1 = KEYS[1]
local delete_count = 0
local delete_keys = redis.call('keys', key1)
if #delete_keys > 0 then
    delete_count = redis.call('del',unpack(delete_keys))
end

return delete_count
"""

# 注册脚本
script = r.register_script(lua_script)

# 执行
result = script(keys=['example-*'])
print(result)

6. 总结

  1. 尽量避免在生产环境使用keys :使用keys不可避免的会出现性能问题。
  2. 分批次删除 :不要一次删除防止redis服务端处理大量键进入阻塞状态。
相关推荐
難釋懷38 分钟前
Redis消息队列-基于Stream的消息队列-消费者组
数据库·redis·缓存
小杜的生信筆記4 小时前
生信技能技巧小知识,Linux多线程压缩/解压工具
linux·数据库·redis
初次攀爬者5 小时前
Redis脑裂问题处理——基于min-replicas-to-write配置
redis·后端
難釋懷6 小时前
Redis消息队列-基于Stream的消息队列
数据库·redis·缓存
java1234_小锋6 小时前
Java高频面试题:说说Redis的内存淘汰策略?
java·开发语言·redis
予枫的编程笔记7 小时前
【Kafka进阶篇】Canal+Kafka+ES实战:内容平台数据同步难题,这样解最优雅
redis·mysql·elasticsearch·kafka·canal·数据同步·异步解耦
LSL666_7 小时前
5 Redis通用命令
java·开发语言·redis·命令
rannn_1117 小时前
【Redis|基础篇】初识、Redis的安装与启动、Redis命令、Java客户端
java·redis·后端·缓存·nosql
西门吹雪分身8 小时前
SpringCloudGateway过滤器之RequestRateLimiterGatewayFilterFactory
java·redis·spring cloud
難釋懷8 小时前
基于Redis的Stream结构作为消息队列,实现异步秒杀下单
数据库·redis·缓存