如何在Django中通过键前缀批量删除Redis缓存?
按前缀删除Django Redis缓存的实现方案
问题背景
我用Django结合Redis实现缓存功能,缓存键示例如下:determ_1ba243f3-2eda-4feb-bf24-1aa4c0cd2171appr_hist_2bfd55e4-22c1-4cc3-a913-8ac2cde3801bappr_act_5a18c351-e172-4369-9a4b-118c3df5b25a
缓存设置代码:
cache.set("determ_" + str(id), cache_object)
现在需要按键前缀(如determ_、appr_hist_、appr_act_)删除缓存,但当前的CacheManager.delete_cache方法仅调用cache.delete(pattern),只能删除与前缀完全匹配的键,无法匹配带后缀的缓存键,需要修改实现。
现有代码:
from django.core.cache import cache class CacheManager: @classmethod def delete_cache(self, prefixes = []): for pattern in prefixes: cache.delete(pattern) return True
调用代码:
CacheManager.delete_cache(['determ_','appr_hist_', 'det_appr','appr_act_','deter_sect_'])
解决方案
Django默认的cache.delete只能删除单个指定键,要按前缀批量删除,需要直接操作Redis的扫描(scan)命令匹配所有符合前缀的键,再批量删除。具体修改如下:
修改后的CacheManager代码
from django.core.cache import cache from django_redis import get_redis_connection class CacheManager: @classmethod def delete_cache(cls, prefixes=None): if not prefixes: return True # 获取Redis连接 redis_conn = get_redis_connection() for prefix in prefixes: # 构造匹配模式:前缀 + 任意字符 pattern = f"{prefix}*" # 扫描所有匹配的键,避免用keys命令阻塞Redis cursor = 0 while True: cursor, keys = redis_conn.scan(cursor=cursor, match=pattern, count=100) if keys: # 批量删除键 redis_conn.delete(*keys) if cursor == 0: break return True
关键说明
- 使用
django_redis.get_redis_connection()获取底层Redis客户端,直接执行Redis原生命令 - 用
scan代替keys:keys命令会遍历所有键,大缓存量下会阻塞Redis服务,scan是渐进式扫描,更安全高效 - 每个前缀构造
prefix*的匹配模式,匹配所有以该前缀开头的缓存键 - 循环扫描直到cursor返回0,确保所有匹配键都被处理
- 批量删除用
delete(*keys),一次操作多个键,提升执行效率
注意事项
- 确保Django缓存后端配置为Redis(如
django_redis.cache.RedisCache) - 若使用多Redis数据库,需在
get_redis_connection中指定对应别名 - 若缓存键包含特殊字符,需确保
scan的匹配模式正确(当前场景前缀为普通字符,无需额外转义)
内容的提问来源于stack exchange,提问作者Jackson Bakari
相关产品推荐
相关产品推荐

