首先讲解下Redis的基本概念:

Redis是单线程,同一时间段内操作大量的key值,会造成进程阻塞,会影响正在运行的其它业务,严重时会导致数据库雪崩。

方法一

del方法

推荐力度:极不推荐

是否会影响线上业务:严重影响

会影响线上业务,一般情况会造成其它服务写入读取卡顿,严重时会造成其它服务业务无法正常进行。

方案缺陷

删除的key字段数量较大时,会导致redis卡顿,影响其它业务,删除量比较大时,甚至会导致redis雪崩。

方案二

UNLINK

推荐力度:推荐

是否会影响线上业务:不会影响

Redis UNLINK 命令跟 DEL 命令十分相似:用于删除指定的 key 。就像 DEL 一样,如果 key 不存在,则将其忽略。但是,该命令会执行命令之外的线程中执行实际的内存回收,因此它不是阻塞,而 DEL 是阻塞的。这就是命令名称的来源:UNLINK 命令只是将键与键空间断开连接。实际的删除将稍后异步进行。

版本要求:可用版本>= 4.0.0.

注:如何你是使用的是windows版本,就不需要考虑这个方法,因为Windows版本的Redis是很老的版本。

方案三

redis-cli执行Lua脚本

推荐力度:极力推荐

是否会影响线上业务:不会影响 

使用场景:如果你是匹配某一类的key字段,并需要将其删除,该方案是标准的删除方法。

使用方法

在 redis-cli 中执行如下命令

EVAL "local keys = redis.call('keys', ARGV[1]) for i=1,#keys,5000 do redis.call('del', unpack(keys, i, math.min(i+4999, #keys))) end return #keys" 0 'gameBillRecord*' 

参数说明:

5000:表示每次使用del删除的数量

gameBillRecord:模糊匹配需要删除的字段

方案四

当我们的清理需求比较复杂时,就不能使用简单的模糊匹配删除了。

需求场景

我们需要通过mysql的一张用户表tb_user_info,通过该表中的封号字段,对封号数据进行清理,表中的封号数量为50000。

每个用户在redis中存储了多个key字段类型,例如用户10000的key字段有如下类型:

player_moudle_10000(key字段)

gameBillRecord_10000(集合)

gameBillRecord_10000-20220122(集合)

gameBillRecord_10000-20220123(集合)

gameBillRecord_10000-20220124(集合)

通过分析需求场景,我们发生,1个用户对应的字段可能达5个甚至更多,我们累计需要删除的key数量达到20W以上,此时只能通过编写逻辑脚本进行数据整理再进行删除。

脚本流程思路

#STEP-1

查询出封号的用户列表

#STEP-2

注:这里不要使用keys命令,会造成阻塞,scan不会造成阻塞。

通过scan命令模糊查询,将redis中所有的key字段全部加载到内存中进行与封号用户列表匹配,筛选出需要删除的key。

#STEP-3

配合方案三,生成Lua脚本代码,再使用命令批量执行Lua脚本即可。

 Lua模版脚本代码(clearPlayerStencil_0.lua):

-- 选择DB库
redis.call('select','0')
-- 输出日志
redis.log(redis.LOG_WARNING,"Step-0")
-- delRedisKeyString 替换为需要删除的key字段(例如:local delRedisKeyList = {player_moudle_10000,player_moudle_10001,player_moudle_10002};)
local delRedisKeyList = {delRedisKeyString};
-- 输出日志
redis.log(redis.LOG_WARNING,"Step-1");
redis.log(redis.LOG_WARNING,"delRedisKeyList"..#delRedisKeyList);
redis.log(redis.LOG_WARNING,"Step-2");
-- 循环输出(每次删除5000个)
for i=1,#delRedisKeyList,5000 do 
   redis.call('del', unpack(delRedisKeyList, i, math.min(i+4999, #delRedisKeyList)));
end

生成bat脚本(SH脚本同理)(清理封号用户数据0.bat)

@echo off
title clearForbidenPlayer
redis-cli -h 127.0.0.1 -p 6809 -a password --eval clearPlayerStencil_0.lua
pause

完成后,执行 清理封号用户数据0.bat 即可。

例如:我们总共需要删除20W条Key,每个脚本清理1W条,只需要生成20个bat脚本,然后再执行这20个脚本即可,脚本基本上是秒执行。

注:Lua的数组存储是有上限的,不能将20W条key直接存储,需要分脚本存储并删除。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐