欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 家装 > 心链7 ----Redis的引入和实现以及缓存和定时任务应用

心链7 ----Redis的引入和实现以及缓存和定时任务应用

2025/3/12 9:32:14 来源:https://blog.csdn.net/PQ781826/article/details/139411703  浏览:    关键词:心链7 ----Redis的引入和实现以及缓存和定时任务应用

心链 — 伙伴匹配系统

Redis

数据查询慢怎么办?
用缓存:提前把数据取出来保存好(通常保存到读写更快的介质,比如内存),就可以更快地读写。
缓存

  • Redis(分布式缓存)
  • memcached(分布式)
  • Etcd(云原生架构的一个分布式存储,存储配置,扩容能力)
  • ehcache(单机)
  • 本地缓存(Java 内存 Map)
  • Caffeine(Java 内存缓存,高性能)
  • Google Guava

实现方式

  • Spring-Data-Redis
  • Spring Data:
    • 通用的数据访问框架,定义了一组 增删改查 的接口mysql、redis、jpa
  • Jedis:
    • (独立于 Spring 操作 Redis 的 Java 客户端,要配合 Jedis Pool 使用)
  • Lettuce
    • 高阶 的操作 Redis 的 Java 客户端
    • 异步、连接池
  • Redisson
    • 分布式操作 Redis 的 Java 客户端,让你像在使用本地的集合一样操作 Redis(分布式 Redis 数据网格)

对比

  1. 如果你用的是 Spring,并且没有过多的定制化要求,可以用 Spring Data Redis,最方便
  2. 如果你用的不是 SPring,并且追求简单,并且没有过高的性能要求,可以用 Jedis + Jedis Pool
  3. 如果你的项目不是 Spring,并且追求高性能、高定制化,可以用 Lettuce,支持异步、连接池
  4. 如果你的项目是分布式的,需要用到一些分布式的特性(比如分布式锁、分布式集合),推荐用 redisson

:::

Redis
NoSQL 数据库
key - value 存储系统(区别于 MySQL,他存储的是键值对)
Redis 数据结构
String 字符串类型: name: “yupi”
List 列表:names: [“yupi”, “dogyupi”, “yupi”]
Set 集合:names: [“yupi”, “dogyupi”](值不能重复)
Hash 哈希:nameAge: { “yupi”: 1, “dogyupi”: 2 }
Zset 集合:names: { yupi - 9, dogyupi - 12 }(适合做排行榜)

bloomfilter(布隆过滤器,主要从大量的数据中快速过滤值,比如邮件黑名单拦截)

geo(计算地理位置)
hyperloglog(pv / uv)
pub / sub(发布订阅,类似消息队列)
BitMap (1001010101010101010101010101)

Redis整合测试

引入和测试

Spring Data Redis(推荐)

Spring Data:通用的数据访问框架,定义了一组 增删改查 的接口
mysql、redis、jpa spring-data-redis
Just a moment…

       <!-- redis --><!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.6.4</version></dependency>

配置 Redis 地址

spring:# redis 配置redis:port: 6379host: localhostdatabase: 0

Jedis

独立于 Spring 操作 Redis 的 Java 客户端 要配合 Jedis Pool 使用

Lettuce

高阶 的操作 Redis 的 Java 客户端 异步、连接池

Redisson

分布式操作 Redis 的 Java 客户端,让你像在使用本地的集合一样操作 Redis(分布式 Redis 数据网格)

JetCache

对比

  • 如果你用的是 Spring,并且没有过多的定制化要求,可以用 Spring Data Redis,最方便
  • 如果你用的不是 SPring,并且追求简单,并且没有过高的性能要求,可以用 Jedis + Jedis Pool
  • 如果你的项目不是 Spring,并且追求高性能、高定制化,可以用 Lettuce,支持异步、连接池
  • 如果你的项目是分布式的,需要用到一些分布式的特性(比如分布式锁、分布式集合),推荐用 redisson

自定义序列化

package com.ivy.heartchain.config;import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;@Configuration
public class RedisTemplateConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(connectionFactory);redisTemplate.setKeySerializer(RedisSerializer.string());return redisTemplate;}
}

引入一个库时,先写测试类

数据缓存

设计缓存 key
不同用户看到的数据不同
systemId:moduleId:func:options(不要和别人冲突)
yupao:user:recommed:userId
redis 内存不能无限增加,一定要设置过期时间!!!

修改主页推荐接口

   /*** 推荐页面* @param request* @return*/@GetMapping("/recommend")public BaseResponse<Page<User>> recommendUsers(long pageSize,long pageNum, HttpServletRequest request){User loginUser = userService.getLoginUser(request);String redisKey = String.format("partner:user:recommend:%s", loginUser.getId());ValueOperations<String,Object> valueOperations = redisTemplate.opsForValue();//如果有缓存,直接读缓存Page<User> userPage= (Page<User>)valueOperations.get(redisKey);if (userPage!=null){return ResultUtils.success(userPage);}//无缓存,查数据库QueryWrapper<User> queryWrapper = new QueryWrapper<>();userPage = userService.page(new Page<>(pageNum, pageSize), queryWrapper);//写缓存try {valueOperations.set(redisKey,userPage,30000, TimeUnit.MILLISECONDS);}catch (Exception e){log.error("redis set key error",e);}return ResultUtils.success(userPage);}

定时任务/数据预热、

:::info
问题:第一个用户访问还是很慢(加入第一个老板),也能一定程度上保护数据库
缓存预热的优点:

  1. 解决上面的问题,可以让用户始终访问很快

缺点:

  1. 增加开发成本(你要额外的开发、设计)
  2. 预热的时机和时间如果错了,有可能你缓存的数据不对或者太老
  3. 需要占用额外空间
怎么缓存预热?
  1. 定时
  2. 模拟触发(手动触发)
实现

用定时任务,每天刷新所有用户的推荐列表
注意点:

  1. 缓存预热的意义(新增少、总用户多)
  2. 缓存的空间不能太大,要预留给其他缓存空间
  3. 缓存数据的周期(此处每天一次)

定时任务实现

  1. Spring Scheduler(spring boot 默认整合了)
  2. Quartz(独立于 Spring 存在的定时任务框架)
  3. XXL-Job 之类的分布式任务调度平台(界面 + sdk)

第一种方式:

  1. 主类开启 @EnableScheduling
  2. 给要定时执行的方法添加 @Scheduling 注解,指定 cron 表达式或者执行频率

不要去背 cron 表达式!!!!!

  • https://cron.qqe2.com/
  • https://www.matools.com/crontab/

新建文件夹新建文件。之前就写个的,就不具体写出来了。
:::

package com.yupi.usercenter.job;import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yupi.usercenter.common.ResultUtils;
import com.yupi.usercenter.model.domain.User;
import com.yupi.usercenter.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;/*** @Description:        数据预热*/@Component
@Slf4j
public class PreCacheJob {@Resourceprivate UserService userService;@Resourceprivate RedisTemplate<String, Object> redisTemplate;// 重点用户private List<Long> mainUserList = Arrays.asList(1L);// 每天执行,预热推荐用户@Scheduled(cron = "0 12 1 * * *")   //自己设置时间测试public void doCacheRecommendUser() {//查数据库QueryWrapper<User> queryWrapper = new QueryWrapper<>();Page<User> userPage = userService.page(new Page<>(1,20),queryWrapper);String redisKey = String.format("sanshui:user:recommend:%s",mainUserList);ValueOperations valueOperations = redisTemplate.opsForValue();//写缓存,30s过期try {valueOperations.set(redisKey,userPage,30000, TimeUnit.MILLISECONDS);} catch (Exception e){log.error("redis set key error",e);}}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词