java后端&redis缓存&缓存预热

缓存概述

  1. 缓存:从数据库磁盘)中取数据到前端展示,速度很慢。为了提高速度可以使用缓存,即把数据预先查出来,放到一个更快读取的介质,比如内存,不用在从数据库很慢的查。
  2. 加载缓存定时更新缓存,为了不让第一次使用次此系统数据加载很慢可以在选一个用户访问较少的时间定时加载缓存
  3. 分布式锁:控制同一时间只用一台机器执行定时任务,同一份代码不用在多个机器加载缓存
  4. 缓存实现

单机缓存和分布式缓存

Redis

Redis定义

NoSQL(非关系数据库
keyvalue键值存储系统区别mysql键值数据库

☆Redis数据结构(5种基本高级)

  1. 基本
    1. String字符串name:“erha
    2. List列表 : names:[“erha”,“erha02”](和数组区别列表长度是不固定的,数组长度固定的)
    3. Set集合names: [“erha”,“erha02”] (值不能重复)
    4. Hash哈希nameAge:{“erha”:1,“haer02”:2}(键不能重复
    5. Zset集合names:{erha-99,erha02-100}(值从小到大排序)
  2. 高级
    1. bloomfilter布隆过滤器,从大量的数据种快速过滤值,比如邮箱黑名单
    2. geo(计算地理位置
    3. hyperloglogpv/uv大数据统计
    4. pub/sub(发布订阅,类似消息队列)
    5. BitMap(把数据以10001110001的方式存储存储大量可以压缩的值)

Redis在java中的实现方式(Spring Data Redis , Lettuce,Jedis 和Redisson

不同的场景使用不同的实现方式,
1. 如果用spring框架,并且没有过多的定制化要求,可以使用spring Data Redis,最方便
2. 如果使用的不是Spring,并且追求简单没有过高的性能要求,可以用jedis + jedis Pool
3. 如果不是spring,并且追求高性能定制化可以使用Lettuce支持异步连接池
4. 如果项目是分布式的,需要用到一些分布式的特征比如分布式锁,分布式集合),可以使用redisson
  1. 使用Spring Data Redis 实现

    1. spring Data:通用的数据访问框架,定义一组增删改查接口,操做mysqlredisjpa等数据库,通过应入不同的数据库依赖实现对不同数据库的操作
    2. 引入Redis依赖
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-data-redis</artifactId>
          <version>2.6.4</version>
      </dependency>
      
    3. 配置Redis地址
        # Redis 配置
        redis:
          port: 6379
          host: localhost
          database: 0
      
    4. Redis增删改查示例如何使用Redis依赖中的增删改查接口使用redis提供的,操作redis的类和对象
      //操作redis的类
      @SpringBootTest
      public class RedisTest {
      
          //操作redis的对象
          @Resource
          private RedisTemplate redisTemplate;
      
          @Test
          void 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 {
      
          @Bean
          public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory connectionFactory){
              RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
              redisTemplate.setConnectionFactory(connectionFactory);
              redisTemplate.setKeySerializer(new StringRedisSerializer());
              return redisTemplate;
          }
      }
      
    5. 项目首页推荐提取缓存
      1. 设计缓存key,不同用户看到的数据不同。systemId:moduleId:func:options(不和别人冲突
        lack:user:recommed:userId
      2. 用缓存实现主页推荐
        /**
         * 首页推荐接口(分页查询)
         * @param request
         * @return
         */
        @GetMapping("/recommend")
        public BaseResponse<Page<User>> recommendUsers(long pageSize,long pageNum,HttpServletRequest request) {
            //先获取当前登录对象
            User loginUser = userService.getLoginUser(request);
            ValueOperations<String, Object> valueOperations = redisTemplate.opsForValue();
            //判断有无缓存,有直接读缓存
            String redisKey = String.format("lack:user:recommed:userId:%s",loginUser.getId());
            Page<User> userPage =(Page<User>)redisTemplate.opsForValue().get(redisKey);
            if(userPage != null){
                return ResultUtils.success(userPage);
            }
            //无缓存查数据库
            QueryWrapper<User> 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);
        }
        
    6. 优化=>缓存预热
      1. 缓存预热解决的问题:

      2. 缓存预热的优缺点

      3. 缓存预热的意义:

      4. 缓存预热的注意点:

        • 缓存空间不能太大,要预留给其他缓存空间
        • 缓存数据的周期(每天一次
      5. 实现缓存预热

  2. Jedis
    独立于spring操作redis
    redis的Java客户端

  3. Lettuce
    高阶操作redis的java客户端

  4. 和Redisson
    分布式操作redis的java客户端,像在本地使用集合一样操作redis

原文地址:https://blog.csdn.net/weixin_52154534/article/details/134629984

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_21304.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注