建设银行新乡分行城南支行网站,怎么学php网站开发,免费空间申请free,同时做网站建设和代账java后端redis缓存缓存预热
缓存概述
缓存#xff1a;从数据库#xff08;磁盘#xff09;中取数据到前端展示#xff0c;速度很慢。为了提高速度可以使用缓存#xff0c;即把数据预先查出来#xff0c;放到一个更快读取的介质#xff0c;比如内存#xff…java后端redis缓存缓存预热
缓存概述
缓存从数据库磁盘中取数据到前端展示速度很慢。为了提高速度可以使用缓存即把数据预先查出来放到一个更快读取的介质比如内存不用在从数据库很慢的查。预加载缓存定时更新缓存为了不让第一次使用次此系统时数据加载很慢可以在选一个用户访问较少的时间定时加载缓存。分布式锁控制同一时间只用一台机器去执行定时任务同一份代码不用在多个机器加载缓存。缓存的实现 Redis(分布式缓存)Memcached分布式缓存Etcd(云原生架构的分布式存储公共的存储配置扩容能力强)ehcache单机本地缓存java内存MapCaffeinejava内存缓存性能高Google Guava
单机缓存和分布式缓存
单机本地缓存在同一个进程内的内存空间中缓存数据数据读写都是在同一个进程内完成分布式缓存一个独立部署的进程并且一般都是与应用进程部署在不同的机器故需要通过网络来完成分布式缓存的数据读写操作的数据传输。
Redis
Redis定义
NoSQL非关系型数据库 key-value键值对存储系统区别于mysql的键值对数据库
☆Redis的数据结构(5种基本高级)
基本 String字符串name:“erha”List列表 : names:[“erha”,“erha02”]和数组的区别列表的长度是不固定的数组长度固定的Set集合names: [“erha”,“erha02”] (值不能重复)Hash哈希nameAge:{“erha”:1,“haer02”:2}键不能重复Zset集合names:{erha-99,erha02-100}(值从小到大排序) 高级 bloomfilter布隆过滤器从大量的数据种快速过滤值比如邮箱黑名单geo计算地理位置hyperloglogpv/uv大数据统计pub/sub(发布订阅类似消息队列)BitMap(把数据以10001110001的方式存储存储大量可以压缩的值)
Redis在java中的实现方式Spring Data Redis LettuceJedis 和Redisson
不同的场景使用不同的实现方式
1. 如果用spring框架并且没有过多的定制化要求可以使用spring Data Redis最方便
2. 如果使用的不是Spring并且追求简单没有过高的性能要求可以用jedis jedis Pool
3. 如果不是spring并且追求高性能高定制化可以使用Lettuce支持异步连接池
4. 如果项目是分布式的需要用到一些分布式的特征比如分布式锁分布式集合可以使用redisson使用Spring Data Redis 实现 spring Data通用的数据访问框架定义了一组增删改查的接口操做mysqlredisjpa等数据库通过应入不同的数据库依赖实现对不同数据库的操作。引入Redis依赖dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactIdversion2.6.4/version
/dependency配置Redis地址 # Redis 配置redis:port: 6379host: localhostdatabase: 0Redis增删改查示例【如何使用Redis依赖中的增删改查接口使用redis提供的操作redis的类和对象】//操作redis的类
SpringBootTest
public class RedisTest {//操作redis的对象Resourceprivate RedisTemplate redisTemplate;Testvoid test(){ValueOperations valueOperations redisTemplate.opsForValue();//增valueOperations.set(erhaString,fish);valueOperations.set(erhaInt,1);valueOperations.set(erhaDouble,2.0);User user new User();user.setId(001);user.setUsername(testRedisString);valueOperations.set(erhaUser,user);//查Object erha valueOperations.get(erhaString);Assert.assertTrue(fish.equals((String) erha));erha valueOperations.get(erhaInt);Assert.assertTrue(1 (int)erha);erha valueOperations.get(erhaDouble);Assert.assertTrue(2.0 (Double) erha);erha valueOperations.get(erhaUser);System.out.println(valueOperations.get(erhaUser));} }注为了解决序列化问题自编代码实现序列化配置Configuration
public class RedisTemplateConfig {Beanpublic RedisTemplateString,Object redisTemplate(RedisConnectionFactory connectionFactory){RedisTemplateString,Object redisTemplate new RedisTemplate();redisTemplate.setConnectionFactory(connectionFactory);redisTemplate.setKeySerializer(new StringRedisSerializer());return redisTemplate;}
}在项目首页推荐出提取缓存 设计缓存key不同用户看到的数据不同。systemId:moduleId:func:options不和别人冲突 lack:user:recommed:userId用缓存实现主页推荐/*** 首页推荐接口(分页查询)* param request* return*/
GetMapping(/recommend)
public BaseResponsePageUser recommendUsers(long pageSize,long pageNum,HttpServletRequest request) {//先获取当前登录对象User loginUser userService.getLoginUser(request);ValueOperationsString, Object valueOperations redisTemplate.opsForValue();//判断有无缓存有直接读缓存String redisKey String.format(lack:user:recommed:userId:%s,loginUser.getId());PageUser userPage (PageUser)redisTemplate.opsForValue().get(redisKey);if(userPage ! null){return ResultUtils.success(userPage);}//无缓存查数据库QueryWrapperUser queryWrapper new QueryWrapper();userPage userService.page(new Page(pageNum,pageSize),queryWrapper);//写缓存try {//redis的内存不能无限增加一定要设置过期时间valueOperations.set(redisKey,userPage,30000, TimeUnit.MILLISECONDS);} catch (Exception e) {log.error(redis set key error,e);}return ResultUtils.success(userPage);
}优化缓存预热 缓存预热解决的问题 让第一个触发缓存的用户也能很快获取到推荐用户【提前把第一个用户需要的数据准备好当用户一登录立即显示即可】例如双十一这样可预期的场景使用缓存预热降低数据库的压力保护数据库。 缓存预热的优缺点 优点让用户始终访问很快缺点增加开发成本额外开发占用空间如果预热时机和时间错了有可能缓存的数据不正确。 缓存预热的意义 提高用户的访问速度保护数据库 缓存预热的注意点 缓存空间不能太大要预留给其他缓存空间缓存数据的周期每天一次 实现缓存预热 手动模拟触发定时触发定时任务实现每天刷新所有用户的推荐列表 ☆Spring Schedulespring boot默认整合 主类开启EnableScheduling给要定时执行的方法添加Scheduled注解编写方法/**
* 缓存预热任务
*
*/
Slf4j
Component
public class PreCacheJob {
Resource
private UserService userService;
Resource
private RedisTemplateString, Object redisTemplate;
//重点用户
private ListLong mainUserList Arrays.asList(2l);
//每天执行预热推荐用户
Scheduled(cron 0 31 19 * * ? )
public void doCacheRecommendUser() {
for (Long userId : mainUserList) {
QueryWrapperUser queryWrapper new QueryWrapper();
PageUser userPage userService.page(new Page(1, 20), queryWrapper);
String redisKey String.format(yupao:user:recommend:%s, userId);
ValueOperationsString, Object valueOperations
redisTemplate.opsForValue();
//写缓存
try {
valueOperations.set(redisKey, userPage, 30000, TimeUnit.MILLISECONDS);
} catch (Exception e) {
log.error(redis set key error, e);}
}
}
}Quartz独立于spring存在的定时任务框架 XXL-job分布式任务调度平台界面sdk Jedis 独立于spring操作redis redis的Java客户端 Lettuce 高阶的操作redis的java客户端 和Redisson 分布式操作redis的java客户端像在本地使用集合一样操作redis