前言

在使用缓存的时候,我们时不时会遇到这样一个需求,根据缓存键的规则去批量删除这些数据,比较常见的就是按前缀去删除。

举个简单的例子,Redis中现在有几百个商品的数据,这些数据的key值是有一定规律的,都是以product:id的形式存在的。

现在由于不得以为的原因要删除这几百个商品的数据,这个时候我们肯定就要把缓存键以product:开头的给全部删除掉。

其实这个需求在Redis中是可以很容易去实现的。

来看看几种常见的做法。

常见的几种做法

  1. 用Keys命令找到key之后执行删除操作
  2. 用Scan命令找到key之后执行删除操作(2.8.0版本之后)
  3. 添加缓存数据的时候,可以同时将key存放到一个SET中,然后依据这个SET来执行删除操作

对于Keys命令,网上有不少血的教训,对于生产环境还是要谨慎谨慎再谨慎!能不用就别用。

Scan命令的话是大部分人推荐的做法,是增量式迭代的一个命令。

存到SET中就相对繁琐一点,而且额外占用了一部分内存。而且在进行删除的时候还要从这里读取出相应的key,同时也要移除这部分key的数据。

下面来看看如何在.NET Core中来处理,主要还是针对SCAN的做法。

示例操作Redis用的是StackExchange.Redis

使用IServer.Keys

可能有人会有疑惑,不是说Keys命令尽量不要用吗?怎么你还用?

这个还真的要解释一下!

可能从方法上,我们找遍所有IServer和IDataBase接口都找不到纯粹的SCAN命令(SetScan,HashScan等除外)。

但是如果看过里面的实现,你就会知道是为什么了!

传送门:Keys

可以看看下图高亮的两行代码:

大致意思就是,如果你用的Redis的版本支持SCAN命令,走的就是SCAN,反之只能是KEYS了。

下面定义一个查找RedisKey的方法。

private static RedisKey[] SearchRedisKeys(IServer server, string pattern)
{
var keys = server.Keys(pattern: pattern).ToArray();
Console.WriteLine("Search Count-{0}",keys.Length);
return keys;
}

知道那些Key要删除,剩下的就比较简单了!

private static void KeysOrScanSolution(IServer server,IDatabase db, string pattern)
{
db.KeyDelete(SearchRedisKeys(server, pattern));
}

使用IDatabase.Execute

IServer.Keys可以说是隐式的调用了SCAN命令,那么我们自然也可以显式的去调用这个命令来完成这些。

private static RedisKey[] SearchRedisKeys(IDatabase db,string pattern)
{
var keys = new HashSet<RedisKey>(); int nextCursor = 0;
do
{
RedisResult redisResult = db.Execute("SCAN", nextCursor.ToString(), "MATCH", pattern, "COUNT", "1000");
var innerResult = (RedisResult[])redisResult; nextCursor = int.Parse((string)innerResult[0]); List<RedisKey> resultLines = ((RedisKey[])innerResult[1]).ToList(); keys.UnionWith(resultLines);
}
while (nextCursor != 0); return keys.ToArray();
}

删除的代码。

private static void ExecuteSolution(IDatabase db, string pattern)
{
db.KeyDelete(SearchRedisKeys(db, pattern));
}

当然还有一种做法是调用lua脚本去完成,这里就不细说了。

总结

虽然上面几种做法能比较简单的处理这个问题,但是在拿出这些Keys的时候,客户端的内存占用可能会比较大,尤其是有大量符合条件的缓存项的时候。

涉及缓存的诸多操作(包含根据前缀去删除缓存项),我也在EasyCaching中实现了相应的操作,后面也会不断的抽时间来完善这一项目,有兴趣的朋友可以关注一下。

文中的示例代码 RedisBatchRemoveSolution

谈谈使用Redis缓存时批量删除的几种实现的更多相关文章

  1. redis优雅的批量删除key

    redis优雅的批量删除key 近期在处理redis的故障中,发现需要删除大量的历史数据(也是bigkeys),好在符合正则表达式.要不然就很痛苦,这也体现了在设计key的时候遵循规范带来的维护好处之 ...

  2. mybatis 根据id批量删除的两种方法

    原文:https://blog.csdn.net/qq_40010745/article/details/81032218 mybatis 根据id批量删除的两种方法   第一种,直接传递给mappe ...

  3. 在Spring中使用Redis Lua脚本批量删除缓存

    背景 之前分享了一篇利用lua脚本批量删除redis的key的文章.现在项目中我打算使用spring的缓存,而Spring缓存以前我是用ehcache来做实现的.没发现什么问题..这次我换成redis ...

  4. memcache 缓存的批量删除方案(转)

    memcache 默认只支持使用delete(key)和 flush_all,这两种方法都太极端了,不能满足用户的特定需求,如:批量删除‘aaaaaaaa_’开头的所有缓存,这个时候该怎么办? 1 g ...

  5. Redis中的批量删除数据库中的Key

    本文参考:http://blog.csdn.net/spring21st/article/details/15771861 http://stackoverflow.com/questions/575 ...

  6. redis命令行批量删除匹配到的key

    执行命令如下 redis-cli -h 12.132.30.21 -p 6379 -a 2016 -n 4 keys "ecard*" | xargs redis-cli -h 1 ...

  7. redis 命令远程批量删除keys

    1.首先在电脑上装上 redis 客户端; https://www.cnblogs.com/feijl/p/6879929.html 2.安装成功后,进入 redis-cli 客户端目录; 连接 re ...

  8. redis通过命令批量删除key

    需求:想删除 notify_ 开头的所有key redis-cli KEYS "notify_*" | xargs redis-cli DEL 通过 notify_* 来匹配

  9. Redis批量删除缓存数据

    背景: 在使用redis中,经常会遇到批量删除缓存的情况,但是对于在客户端中,如果一个一个的删除key,则需要较长时间及相对麻烦,可以使用以下命令,批量删除缓存. 本地批量删除KEY: ./redis ...

随机推荐

  1. VC调用Delphi对象接口

    说在前头 很久没有碰Delphi的东西了,今天有个朋友让我帮他将一个Delphi中已经实现的功能在VC中进行使用,虽然后来又用VC的方式实现了该功能,但是在实现过程中想到了这样的调用方式,特写下本文以 ...

  2. jquery对象和DOM对象的区别和转换

    jquery对象和DOM对象的区别和转换 在使用jquery时,我们直接通过jq的选择器获取元素,然后对元素进行操作,用jq选择器获取到的对象是一个jq对象,jq对象能够使用jq提供的方法,但是不能用 ...

  3. 一个很好的MySQL在线学习平台

    一个很好的MySQL在线学习平台 https://www.techonthenet.com/sql/

  4. 用最简单的例子实现jQuery图片即时上传

    [http://www.cnblogs.com/Zjmainstay/archive/2012/08/09/jQuery_upload_image.html] 最近看了一些jQuery即时上传的插件, ...

  5. [bzoj3998][TJOI2015]弦论-后缀自动机

    Brief Description 给定一个字符串, 您需要求出他的严格k小子串或非严格k小子串. Algorithm Design 考察使用后缀自动机. 首先原串建SAM, 然后如果考察每个状态代表 ...

  6. 枚举enum学习小记

    参考文献: [1]C++程序设计语言(特别版), 裘宗燕译, 机械工业出版社 [2]C++ Primer (3rd Ed.), S.B. Lippman and J. Lajoie, 人民邮电出版社 ...

  7. Java经典编程题50道之二

    判断101-200之间有多少个素数,并输出所有素数. public class Example02 {    public static void main(String[] args) {      ...

  8. ubuntu16.04 python3 安装selenium及环境配置

    环境 ubuntu16.04 python3 安装selenium sudo pip3 install seleium 默认安装完是支持firefox,但是更新得太慢对于较新的firefox已经不支持 ...

  9. ASP.NET Core 使用 URL Rewrite 中间件实现 HTTP 重定向到 HTTPS

    在传统 ASP.NET 程序中,我们可以通过配置 IIS 的“URL 重写”功能实现将 HTTP 请求重定向为 HTTPS .但是该方法在 ASP.NET Core 应用中不再工作.在 ASP.NET ...

  10. 几种优化ajax的执行速度的方法

    1.尽量使用局部的变量,而不使用全局变量: 2.优化for循环 3.尽量少用eval,每次使用eval都需要消耗大量的时间: 4.将DOM节点放在文档上. 5.尽量减少点好(.)操作符号的使用