redis删除key
redis的key删除的时候,是一个阻塞操作;
为什么会阻塞呢,是在删除key的时候,首先要寻找的key,然后进行删除,然而当key已经过期了,或者被他人删除之后,在删除的时候,就找不到这个key,那么它就一直寻找,新版的redis 有最大重试次数(以前的版本直接死循环),那么就会导致一直阻塞.这对于一线上项目来说,阻塞的这段时间可能是致命的;
如何避免??
1 删除普通key,删除key的时候,可以提前判断是否存在,在的时候再进行删除,这样就可以很大概率减少此类事件发生,例如这样:
-
if (redisTemplate.hasKey(RedisConstant.CASCADE_CHECK_COUNT cascadeDownTask.getId())) {
-
redisTemplate.delete(RedisConstant.CASCADE_CHECK_COUNT cascadeDownTask.getId());
-
}
不要直接删除
2 其实还有一种情况,删除的这个key为大 key,什么是大key,不是key有多大,而是key对应的value 很大,例如 redis有五种数据类型,有四个是集合,那么当key对应的集合 非常大的时候,此key 就叫做大key,那么删除的时候,也会导致阻塞问题;
我们可以利用类如 分段处理的方式去处理,例如: 目前redis中对应的数据类型是hash,然后hash中有大量 hk ,我们可以分段去删除,然后每次删除休眠一下,这样可以有效减少redis的压力
-
@SpringBootTest
-
@Slf4j
-
class AreaDemoControllerTest {
-
-
-
// @Autowired
-
// IAreaDemoService areaDemoService;
-
//
-
// @Autowired
-
// AreaDemoMapper areaDemoMapper;
-
-
// @Test
-
// public void aaa(){
-
// List<AreaDemo> list = areaDemoService.list();
-
//
-
// List<AreaDemo> areaDemos1 = list.subList(0, 10);
-
// areaDemos1.forEach(demo -> demo.setId(null));
-
// areaDemoMapper.updateBatch(areaDemos1);
-
// }
-
-
-
@Autowired
-
RedisTemplate redisTemplate;
-
-
-
/**
-
* @Description 模拟批量删除大key
-
* @Author FL
-
* @Date 11:08 2022/5/12
-
* @Param []
-
**/
-
@Test
-
public void tetsts() {
-
String key = "mapKey";
-
-
redisTemplate.opsForHash().put(key, "NAME", "小明");
-
redisTemplate.opsForHash().put(key, "age", "32");
-
redisTemplate.opsForHash().put(key, "add", "西湖");
-
redisTemplate.opsForHash().put(key, "tianqi", "晴朗");
-
redisTemplate.opsForHash().put(key, "heart", "nice");
-
redisTemplate.opsForHash().put(key, "shoot", "nike");
-
redisTemplate.opsForHash().put(key, "sex", "男");
-
-
Cursor scan = redisTemplate.opsForHash().scan(key, ScanOptions.NONE);
-
int i = 0;
-
while (scan.hasNext()) {
-
Object next = scan.next();
-
System.out.println( i);
-
}
-
// redisTemplate.opsForHash().delete(key);
-
removeBigKey(key, 2, 100);// 每次删除两个 休眠100ms
-
}
-
-
public void removeBigKey(String key, int scanCount, long intervalMills) throws CacheException {
-
final ScanOptions scanOptions = ScanOptions.scanOptions().count(scanCount).build();
-
// 避免内存泄漏
-
// 执行循环删除
-
List<String> fieldKeyList = new ArrayList<>();
-
try {
-
Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash().scan(key, scanOptions);
-
if (ObjectUtil.isNotNull(cursor)) {
-
while (cursor.hasNext()) {
-
String fieldKey = String.valueOf(cursor.next().getKey());
-
fieldKeyList.add(fieldKey);
-
if (fieldKeyList.size() >= scanCount) {
-
// 批量删除
-
Object[] fields = fieldKeyList.toArray();
-
redisTemplate.opsForHash().delete(key, fields);
-
log.info("[Big key] remove key: {}, fields size: {}", key, fields.length);
-
// 清空列表,重置操作
-
fieldKeyList.clear();
-
// 沉睡等待,避免对 redis 压力太大
-
// DateUtil.sleepInterval(intervalMills, TimeUnit.MILLISECONDS);
-
Thread.sleep(intervalMills);
-
}
-
}
-
}
-
// 最后 fieldKeyList 中可能还有剩余,不过一般数量不大,直接删除速度不会很慢
-
// 执行 key 本身的删除
-
// redisTemplate.opsForHash().delete(key,fieldKeyList);
-
redisTemplate.opsForHash().delete(key, fieldKeyList.toArray());
-
} catch (Exception e) {
-
// log.error();
-
}
-
}
-
-
-
}
代码均在 test中
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgakkbg
系列文章
更多
同类精品
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01