java后端redis缓存缓存预热

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

缓存概述

  1. 缓存:从数据库(磁盘)中取数据到前端展示,速度很慢。为了提高速度可以使用缓存,即把数据预先查出来,放到一个更快读取的介质,比如内存,不用在从数据库很慢的查。
  2. 预加载缓存:定时更新缓存,为了不让第一次使用次此系统时数据加载很慢,可以在选一个用户访问较少的时间,定时加载缓存。
  3. 分布式锁:控制同一时间只用一台机器去执行定时任务,同一份代码不用在多个机器加载缓存。
  4. 缓存的实现
    • Redis(分布式缓存)
    • Memcached(分布式缓存)
    • Etcd(云原生架构的分布式存储,公共的存储配置,扩容能力强)
    • ehcache(单机)
    • 本地缓存(java内存Map)
    • Caffeine(java内存缓存性能高)
    • Google Guava

单机缓存和分布式缓存

  • 单机本地缓存:在同一个进程内的内存空间中缓存数据,数据读写都是在同一个进程内完成;
  • 分布式缓存:一个独立部署的进程并且一般都是与应用进程部署在不同的机器,故需要通过网络来完成分布式缓存的数据读写操作的数据传输。

Redis

Redis定义:

NoSQL(非关系型数据库)
key-value键值对存储系统(区别于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. hyperloglog(pv/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:通用的数据访问框架,定义了一组增删改查的接口,操做mysql,redis,jpa等数据库,通过应入不同的数据库依赖实现对不同数据库的操作。
    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: 6379host: localhostdatabase: 0
      
    4. Redis增删改查示例【如何使用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 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. 实现缓存预热

        • 手动模拟触发
        • 定时触发(定时任务实现,每天刷新所有用户的推荐列表)
          1. ☆Spring Schedule(spring boot默认整合)

            1. 主类开启@EnableScheduling
            2. 给要定时执行的方法添加@Scheduled注解,编写方法
              /**
              * 缓存预热任务
              * 
              */
              @Slf4j
              @Component
              public class PreCacheJob {
              @Resource
              private UserService userService;
              @Resource
              private RedisTemplate<String, Object> redisTemplate;
              //重点用户
              private List<Long> mainUserList = Arrays.asList(2l);
              //每天执行,预热推荐用户
              @Scheduled(cron = "0 31 19 * * ? ")
              public void doCacheRecommendUser() {
              for (Long userId : mainUserList) {
              QueryWrapper<User> queryWrapper = new QueryWrapper<>();
              Page<User> userPage = userService.page(new Page<>(1, 20), queryWrapper);
              String redisKey = String.format("yupao:user:recommend:%s", userId);
              ValueOperations<String, Object> valueOperations =
              redisTemplate.opsForValue();
              //写缓存
              try {
              valueOperations.set(redisKey, userPage, 30000, TimeUnit.MILLISECONDS);
              } catch (Exception e) {
              log.error("redis set key error", e);}
              }
              }
              }
              
          2. Quartz(独立于spring存在的定时任务框架)

          3. XXL-job分布式任务调度平台(界面+sdk)

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/187621.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SELinux refpolicy详解(5)

接前一篇文章:SELinux refpolicy详解(4) 三、refpolicy内容详解 1. README 文件路径:refpolicy源码根目录/README。 文件内容如下: 1) Reference Policy make targets:General Make targets:install-src Install the policy sources into/etc/selinux/NAME/src/polic…

【opencv】计算机视觉基础知识

目录 前言 1、什么是计算机视觉 2、图片处理基础操作 2.1 图片处理&#xff1a;读入图像 2.2 图片处理&#xff1a;显示图像 2.3 图片处理&#xff1a;图像保存 3、图像处理入门基础 3.1 图像成像原理介绍 3.2 图像分类 3.2.1 二值图像 3.2.2灰度图像 3.2.3彩色图像…

算法与数据结构有区别吗?

算法和数据结构并不是同一件事。严格来说&#xff0c;它们并不是等效的。但是&#xff0c;我们通常在使用的时候会互换这两个术语。为了简便&#xff0c;后文我们会用数据结构这个术语来指代“数据结构及其所有相关的方法”。 有很多方法可以用来说明这两个术语之间的区别&…

企业软件手机app定制开发趋势|小程序网站搭建

企业软件手机app定制开发趋势|小程序网站搭建 随着移动互联网的快速发展和企业数字化转型的加速&#xff0c;企业软件手机App定制开发正成为一个新的趋势。这种趋势主要是由于企业对于手机App的需求增长以及现有的通用应用不能满足企业特定需求的情况下而产生的。 1.企业软件手…

​iOS Class Guard github用法、工作原理和安装详解及使用经验总结

iOS Class Guard是一个用于OC类、协议、属性和方法名混淆的命令行工具。它是class-dump的扩展。这个工具会生成一个symbol table&#xff0c;这个table在编译期间会包含进工程中。iOS-Class-Guard能有效的隐藏绝大多数的类、协议、方法、属性和 实例变量 名。 iOS-Class-Guard不…

在 S/4HANA、ECC 和 ERP 上轻松扩展或简化 SAP WM,并将其自动化到移动环境中

为您的 SAP WM 提供完整的本地 SAP 图形用户界面 基于原生通道架构&#xff08;NCA&#xff09;&#xff0c;iOS、Android 和手持 Scanguns 版 Liquid UI 可与 SAP WM 原生连接&#xff0c;同时保留 SAP GUI 丰富的事务处理功能。它使您无需编程即可直接从移动设备访问 MIGO、…

安全意识成熟度模型

安全意识成熟度模型是指导企业组织有效识别、管理和衡量团队和员工的安全意识风险&#xff0c;评估和衡量团队和员工的安全意识的评估模型。这套模型是多年以来通过对200多个具有安全意识的职员进行调研后建立的&#xff0c;安全意识成熟度模型使组织能够确定当前安全意识的成熟…

深度学习——激活函数汇总

深度学习——激活函数汇总 一、ReLU 一、ReLU 参考资料&#xff1a; https://zhuanlan.zhihu.com/p/428448728

C++核心编程——运算符重载

C核心编程——运算符重载 运算符重载的方法运算符重载函数作成员函数与友元函数重载双目运算符重载单目运算符重载流插入运算符和"<<"和流提取运算符">>"重载流插入运算符和"<<"流提取运算符">>" 运算符重载的…

LabVIEW开发自适应降噪ANC

LabVIEW开发自适应降噪ANC 在许多情况下&#xff0c;信号很嘈杂&#xff0c;必须消除噪声。自适应降噪&#xff08;ANC&#xff09;是可用于消除信号噪声的主要实时方法之一。可以使用LabVIEW自适应滤滤器工具包来设计ANC应用程序。本文介绍使用自适应筛选器工具包的ANC的一些…

【深度学习】概率图模型(二)有向图模型详解(条件独立性、局部马尔可夫性及其证明)

文章目录 一、有向图模型1. 贝叶斯网络的定义2. 条件独立性及其证明a. 间接因果关系 X 3 → X 2 → X 1 X_3 \rightarrow X_2 \rightarrow X_1 X3​→X2​→X1​b. 间接果因关系 X 1 → X 2 → X 3 X_1 \rightarrow X_2 \rightarrow X_3 X1​→X2​→X3​c. 共因关系 X 1 ← X…

java中如何将mysql里面的数据取出来然后通过stream流的方式进行数据处理代码实例?

在 Java 中使用 Stream 流的方式从 MySQL 数据库中取出数据并进行处理&#xff0c;你可以通过 JDBC&#xff08;Java Database Connectivity&#xff09;来实现。下面是一个简单的代码示例&#xff1a; import java.sql.*; import java.util.stream.Stream; public class MySQ…

android上架之获取平台公钥、签名 MD5 值

app上架需要用到的两个参数公钥、签名 MD5 步骤 1. 下载jadx-gui 工具&#xff0c;下载 2. 下载成后&#xff0c;解压压缩包&#xff0c;双击 jadx-gui-1.4.7.exe 运行。 3. 运行后&#xff0c;在页面左上方单击文件 > 打开文件&#xff0c;打开 APK 包 4. 打开 APK 包后…

Jvm常见问题

1. 为什么用元空间替换永久代 避免OOM异常&#xff1a;永久代中存放了很多JVM需要的类信息&#xff0c;这些数据大多数是不会被清理的&#xff0c;所以Full GC往往无法回收多少空间。而永久代的空间是有限的&#xff0c;如果经常加载新的类进来或者频繁的创建和删除类&#xf…

前端页面转pdf

首先&#xff0c;需要安装两个库 html2canvasjspdf 先引入这个公用的html转pdf的方法 /**path:src/utils/htmlToPdf.jsname:导出页面为pdf格式 **/ import html2Canvas from "html2canvas1.4.1"; import JsPDF from "jspdf2.5.1";const htmlToPdf {get…

APP功能测试思路

一、首先我们拿到一个app的apk包 或者是在testflight下载的app安装包&#xff0c;需要进行安装测试 1.软件安装前&#xff1a;空间不足是否有相应的提示 2.软件安装中&#xff1a;安装过程中是否可以取消、暂停&#xff1b;安装是否可以正常进行&#xff1b;安装空间不足是否…

将yolov8-face里的模型导出到指定opset11

https://github.com/derronqi/yolov8-face 解决办法: 1. 导出前 1 报错内容 (Tensor input, Tensor weight, Tensor bias, tuple of ints stride, tuple of ints padding, tuple of ints dilation, int groups) didnt match because some of the arguments have invalid typ…

2.Ansible的copy模块,我最常用的模块

1. 简述 先从我自身的情况来说&#xff0c;我不是运维人员&#xff0c;并且对linux操作也不是特别熟悉&#xff0c;所以工作中我使用ansible基本就是在平常的自动化部署中&#xff0c;而使用最多的模块就是copy模块。我使用copy模块也主要是来替换生产环境的配置文件。所以&am…

rabbitMQ镜像队列的使用

在rabbitMQ集群中&#xff0c;默认发送消息时&#xff0c;队列默认时在一个节点上存在的。 我们以node01 node02 node03三节点集群为例&#xff0c;在node01声明队列发送消息后&#xff0c;发现&#xff1a; 测试队列只在节点node01上出现。 我们手动停止node01后&#xff0c…

Tomcat外传

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 本篇开始&#xff0c;我…