redis的模糊操作问题分析解决(基于redisTemplate)

需求背景

		redis存在多个前缀相同的key,有时需要对其进行批量查询,删除,插入。当key大了,会坑惨CPU,因为redis通过tcp对外提供服务,是要i一个多路复用的单线程,每次请求的命令都是生成一个连接,所以后面的命令会阻塞直到前面的服务处理完毕才会继续。所以呢,存在一个隐患,这个隐患也只有量起来后才会出现,当我们循环获取key的时候,一开一合,耗时啊。

解决方案

版本2.8以上,过低貌似不可以的。

是时候引入pipeline了,pipeline管道就是解决执行大量命令时、会产生大量阻塞而导致延迟的技术。

其实原理很简单,pipeline就是把所有的命令一次发过去,避免频繁的发送、接收带来的网络开销,redis在打包接收到一堆命令后,依次执行,然后把结果再打包返回给客户端。

根据项目中的缓存数据结构的实际情况,数据结构为string类型的,使用RedisTemplate的multiGet方法;数据结构为hash,使用Pipeline(管道),组合命令,批量操作redis。

所谓的无感操作。

场景1

批量插入/查询指定前缀的key的value
利用multiGet批量获取

完整版例子

/**
 * 批量获取key的value
 *
 * @param keys
 * @return
 */
public List<Object> getMul(Collection<String> keys) {
    List<String> list= (List<String>) keys;
    //方法1
	redisTemplate.executePipelined(new SessionCallback<Object>() {
		@Override
		public <K, V> Object execute(RedisOperations<K, V> redisOperations) throws DataAccessException {
			for (String s : list) {
				//查询
				redisTemplate.opsForValue().get(s);
				//插入
				redisTemplate.opsForValue().set(s, "testValue");
			}
			return null;
		}
	});

	//方法2
	redisTemplate.executePipelined(new RedisCallback<Object>() {
		@Override
		public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
			StringRedisConnection stringRedisConnection = (StringRedisConnection) redisConnection;
			for (String s : list) {
				//查询
				stringRedisConnection.get(s);
				//插入
				stringRedisConnection.set(s, "testValue");
			}
			return null;
		}
	});
	return redisTemplate.opsForValue().multiGet(keys);
}

场景2

批量删除指定前缀的key的值,
1、可用用keys方法模糊匹配后再调取delete方法干掉,但是key过大时候,匹配过慢,影响性能。
2、可以考虑分为两步去处理这个缓存
既然需要批量删除,那么肯定插入,批量插入如上所讲方式,单次插,就不用说了。但是呢,在插的时候,我们可多做一个步骤,把这些具有相同前缀的key,干入一个list集合了,代码如图所示
在这里插入图片描述
到此,应该明确了吧,下面要删除指定前缀的key,那么先从这个list取出所有的key,然后再调用delete方法,redisTemplate自带的delete方法支持批量删除,可无需引入管道重写那玩意。
代码如下:
在这里插入图片描述

这样避免模糊匹配所有,当然这种写法需要考虑一些细节,比如一致性!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
RedisTemplate是Spring Data Redis提供的模板类,用于简化Redis操作。而RedisUtils是一个Redis工具类,封装了一些常用的Redis操作,可以方便地进行数据存取。 基于RedisTemplateRedisUtils,需要在RedisTemplate的基础上封装一些常用的操作。首先需要引入Spring Data Redis的依赖,并注入RedisTemplate对象。 ```java @Autowired private RedisTemplate<String, Object> redisTemplate; ``` 然后可以封装一些常用的操作,例如设置缓存、获取缓存和删除缓存。其中,使用RedisTemplate的opsForValue()方法获取ValueOperations对象,然后可以调用set、get、delete等方法进行操作。 ```java public class RedisUtils { @Autowired private RedisTemplate<String, Object> redisTemplate; /** * 设置缓存 * @param key 键 * @param value 值 * @param expireTime 过期时间(秒) */ public void set(String key, Object value, long expireTime) { ValueOperations<String, Object> ops = redisTemplate.opsForValue(); ops.set(key, value, expireTime, TimeUnit.SECONDS); } /** * 获取缓存 * @param key 键 * @return 值 */ public Object get(String key) { ValueOperations<String, Object> ops = redisTemplate.opsForValue(); return ops.get(key); } /** * 删除缓存 * @param key 键 */ public void delete(String key) { redisTemplate.delete(key); } // 其他封装操作... } ``` 除了缓存操作RedisUtils还可以封装一些其他操作,例如列表、集合、哈希表和有序集合等操作。这些操作可以使用RedisTemplate的opsForList、opsForSet、opsForHash和opsForZSet方法获取相应的操作对象,然后进行操作。 综上可知,基于RedisTemplateRedisUtils需要先引入Spring Data Redis的依赖,注入RedisTemplate对象,然后封装常用的缓存和其他操作。这些操作可以通过RedisTemplate的相关方法进行封装。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值