StackExchange.Redis 模糊查询和删除[转]

初始化连接对象

_connectionString = ConfigurationManager.ConnectionStrings["RedisConnectionString"].ConnectionString;
_connMultiplexer = ConnectionMultiplexer.Connect(_connectionString);
_db = _connMultiplexer.GetDatabase(db);

通过 keys或scan查找出匹配的key,StackExchange.Redis 中调用 keys/scan/size/flush/save/集群 等命令须使用 IServer 对象

//默认一个服务器
_server = _connMultiplexer.GetServer(_connMultiplexer.GetEndPoints()[0]); 
var pattern = "BUIK_201710*";
//StackExchange.Redis 会根据redis版本决定用keys还是scan(>2.8)
var keys = _server.Keys(database: _db.Database, pattern: pattern); 
//删除一组key
return _db.KeyDelete(keys.ToArray());

如果数据量很大(比如几十万个key),以上操作会很慢,甚至超时,原因未知,因为通过命令执行keys是很快的

为了提高效率,可以通过Lua脚本进行模糊查询的批量操作

var pattern = "BUIK_201710*";
var redisResult = await _db.ScriptEvaluateAsync(LuaScript.Prepare(
                                 //Redis的keys模糊查询:
                                  " local res = redis.call('KEYS', @keypattern) " +
                                   " return res "), new { @keypattern = pattern });
if (!redisResult.IsNull)
{
  _db.KeyDelete((string[])redisResult);  //删除一组key
}

当然也可以通过脚本执行删除参考:

 

StackExchange.Redis加载Lua脚本进行模糊查询的批量删除和修改

前言

使用StackExchange.Redis没有直接相关的方法进行模糊查询的批量删除和修改操作,虽然可以通过Scan相关的方法进行模糊查询,例如:HashScan("hashkey", "*key*"),然后再使用相关的方法进行相关的批量操作,但是如果缓存数据量比较大,效率低下,那么可以使用Lua脚本进行模糊查询的批量操作:ScriptEvaluate(LuaScript.Prepare(...))。

 

通过keys进行模糊查询后的批量操作

批量删除

1 2 3 4 5 6 7 8 9 10 var redis = ConnectionMultiplexer.Connect("127.0.0.1:6379,allowAdmin = true");             redis.GetDatabase().ScriptEvaluate(LuaScript.Prepare(                 //Redis的keys模糊查询:                 " local ks = redis.call('KEYS', @keypattern) " //local ks为定义一个局部变量,其中用于存储获取到的keys                 " for i=1,#ks,5000 do " +    //#ks为ks集合的个数, 语句的意思: for(int i = 1; i <= ks.Count; i+=5000)                 "     redis.call('del', unpack(ks, i, math.min(i+4999, #ks))) " //Lua集合索引值从1为起始,unpack为解包,获取ks集合中的数据,每次5000,然后执行删除                 " end " +                 " return true "                 ),                 new { keypattern = "mykey*" });

批量修改

1 2 3 4 5 6 7 redis.GetDatabase().ScriptEvaluate(LuaScript.Prepare(                 " local ks = redis.call('KEYS', @keypattern) " +                 " for i=1,#ks do " +                 "     redis.call('set', ks[i], @value) " +                 " end " +                 " return true "),                 new { keypattern = "mykey*", value = "setval" });

对Hash集合下的key进行模糊查询后的批量操作

批量删除

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 redis.GetDatabase().ScriptEvaluate(LuaScript.Prepare(                 " local ks = redis.call('hkeys', @hashid) " +                 " local fkeys = {} " +                 " for i=1,#ks do " +                 //使用string.find进行匹配操作                 "   if string.find(ks[i], @keypattern) then " +                 "      fkeys[#fkeys + 1] = ks[i] " +                 "   end " +                 " end " +                 " for i=1,#fkeys,5000 do " +                 "   redis.call('hdel', @hashid, unpack(fkeys, i, math.min(i+4999, #fkeys))) " +                 " end " +                 " return true "                 ),                 new { hashid = "hkey", keypattern = "^mykey" });   //keypattern为可使用正则表达式

批量修改

1 2 3 4 5 6 7 8 9 10 11 12 13 14 redis.GetDatabase().ScriptEvaluate(LuaScript.Prepare(                 " local ks = redis.call('hkeys', @hashid) " +                 " local fkeys = {} " +                 " for i=1,#ks do " +                 "   if string.find(ks[i], @keypattern) then " +                 "      fkeys[#fkeys + 1] = ks[i] " +                 "   end " +                 " end " +                 " for i=1,#fkeys do " +                 "   redis.call('hset', @hashid, fkeys[i], @value) " +                 " end " +                 " return true "                 ),                 new { hashid = "hkey", keypattern = "^key", value = "hashValue" });   //keypattern为可使用正则表达式

对Set集合下的值进行模糊查询后的批量操作

批量删除

1 2 3 4 5 6 7 8 9 10 11 12 13 14 redis.GetDatabase().ScriptEvaluate(LuaScript.Prepare(                 " local ks = redis.call('smembers', @keyid) " +                 " local fkeys = {} " +                 " for i=1,#ks do " +                 "   if string.find(ks[i], @keypattern) then " +                 "      fkeys[#fkeys + 1] = ks[i] " +                 "   end " +                 " end " +                 " for i=1,#fkeys,5000 do " +                 "   redis.call('srem', @keyid, unpack(fkeys, i, math.min(i+4999, #fkeys))) " +                 " end " +                 " return true "                 ),                 new { keyid = "setkey", keypattern = "^myval" });   //keypattern为可使用正则表达式

注意

从 Redis 2.6.0 版本开始,才可通过内置的 Lua 解释器,使用 EVAL 命令对 Lua 脚本进行求值。

转自:https://lesg.cn/Article-105088.html

上一篇:因无报酬,开发者破坏 GitHub 知名开源库;AngularJS 结束生命周期;Linux 5.16 发布 | 开源日报


下一篇:安装完centos7 root目录下的文件anaconda-ks.cfg