对redis、redisson、springcache总结

<一> redis-缓存中间件

  1. 什么是redis
    redis是c语言开发的,一个高性能key-value键值对内存数据库,可以用来做数据库、缓存、消息中间件的一种非关系型数据库。

  2. redis数据存储在哪里
    内存和磁盘中,但是redis的读写都在内存中,这也是速度快的原因之一。
    对于高频繁访问的数据,存储在内存中方便访问。
    为了避免服务宕机或者重启数据丢失,也可以将数据存储在磁盘中持久化。

  3. redis的数据类型
    String、set、zset、list、hash

  4. redis为什么响应速度快
    1) 基于内存存储,redis的读写都是基于内存的key-value操作。内存远大于磁盘响应速度。
    2) 单线程操作,避免了多线程cpu来回切换和各种加锁和解锁的资源消耗。
    redis的单线程操作是指一个模块的操作单线程,其他该多线程的还是使用多线程。
    3)丰富的数据结构
    redis是基于key-velue键值对存储的缓存数据库,对于key都是string类型,但是vlue有多种数据类型
    4)高性能的多复用IO模型

  5. 为什么需要使用redis
    redis的响应速度快读10w+,写8w,对于一些业务场景(可以将计算的结果-菜单等存储到缓存中,下次直接getfromredis)

  6. redis怎么配置、步骤
    1) pom文件加上依赖


    org.springframework.boot
    spring-boot-starter-data-redis



    io.lettuce
    lettuce-core


2) 配置文件加上redis服务器的host port user psw等信息
3)使用springboot自动配置好的StringRedisTemplete工具来操作redis进行读写操作,
@Autowired
StringRedisTemplete stringRedisTemplete;
// 读
stringRedisTemplete.opsForValue.get(“keyName”)
// 写
stringRedisTemplate.opsForValue().set(“keyName”, value, 1, TimeUnit.DAYS); // 设置过期时间 防止缓存数据与数据库不一致

  1. redis怎么进行get,set,读写数据
    使用StringRedisTemplete .get(“keyname”) /.set(“keyname”,“value”,“time”,“时间单位”)

  2. redis有哪些参数
    key-String
    value-list,string、set、zset、hash
    过期时间-过期删除,重新sql获取set到缓存中,与数据库数据保持一致
    过期时间的单位

  3. redis缓存容易出现的问题
    1)缓存穿透
    reason: 大量并发请求一个不存在的数据,到缓存中null,之后大量请求到了数据库中,数据库压力过大崩了。这种是缓存穿透。
    way: 即使数据库中为null的数据,也存储一个标识到缓存中,并且设置一个过期时间。

2)缓存雪崩
r:大量不同业务模块的请求到缓存,但是对应的数据同时过期了,导致所有的请求到db-压力大。
w:设置不同的过期时间,可以在配置文件中统一配置,因为不同业务key存储的时间不同,过期点也不会相同。

3)缓存击穿
r:大量恶意请求到一个热点词,刚好这个key过期了。db压力过大
w:加锁-记得双重验证,每次只允许一个请求进入db-get->db,其他没有进去锁的去访问缓存即可。

  1. 本地锁(不是redis分布式锁,加关键字Synchronized等)
    本地锁只能锁住同一个进程里面的线程,如果是分布式下,即使每个服务仅仅放一个线程进来,相互是隔离的,不能只锁住一个。这个时候需要分布式锁-redisson(使用redis分布式锁-没有看门狗机制)

  2. redis怎么保证与数据库数据一致(更新数据库)
    1)双写模式
    先更新数据库,再去更新缓存对应的key,这种缓存中可能会短暂出现脏数据,稳定后缓存过期-重新读取db即可保证最新数据。
    2)失效模式
    先写数据库,后删除缓存。这种也可能短暂出现缓存有脏数据,稳定后即可

        无论是更新缓存还是删除缓存都会有脏数据,解决如下
    

    1)失效模式-使用双删模式
    先删除缓存->更新db-隔几秒再去删除缓存
    2)使用MQ消息队列,消费者监听queue消息去删除缓存
    生产者(更新db)->MQ->queue有数据->customer监听到->删除缓存->告知queue是否删除成功,失败queue再次发送。(不需要写代码,mq本身会重复出队。解耦修改数据库和查询数据库解耦,不会造成缓存有脏数据)

11.缓存锁使用的原则
正常数据,缓存加上过期时间,就可以实现数据一致性。
对于实时性要求高的,最好是到数据库中读取。
对于频繁修改的数据,不建议加读写锁,性能会慢。

<二> redisson-分布式锁

  1. redisson是什么
    redisson是基于redis的分布式框架,提供了分布式锁等服务

  2. 为什么需要分布式锁
    本地锁只能锁住当前进程-一个服务的线程,所以需要分布式锁。

  3. redission配置步骤
    1)pom文件加上依赖(前提是有redis依赖)

    org.redisson
    redisson
    3.12.0

    2)配置redis配置信息

  4. redisson提供的分布式锁与redis自己的分布式锁区别
    1)redisson提供的分布式锁
    -分布式下也只能有一个线程占用锁,执行业务代码,直至解锁,下一个thread才能进来执行。
    使用RedissonClient加锁—不会出现死锁----锁会自动过期
    @Autowried
    RedissonClient client;
    // 1. 获取锁mylock 只要锁的名字相同 就是同一把锁
    RLock myLock = redisson.getLock(“myLock”);
    // 2. 加锁
    myLock.lock(); // 阻塞锁
    // 业务代码
    try {
    System.out.println(“加锁成功,执行业务…” + Thread.currentThread().getId());
    Thread.sleep(3000);
    } catch (Exception e) {
    } finally {
    // 3. 解锁
    // 即使业务代码执行失败或者断电,没有解锁成功,也不会出现死锁,
    // RedissonClient不会出现死锁
    System.out.println(“释放锁” + Thread.currentThread().getId());
    myLock.unlock();
    }

2)redis提供的分布式锁
使用StringRedisTemplate加锁
Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent(
“lockValue”,
uuid,
5,
TimeUnit.SECONDS);

3) redis-StringRedisTemplate分布式锁与redisson-RedissonClient 分布式锁区别。
区别在于
1.–redisson分布式锁有看门狗机制,一个线程占用锁之后,如果锁没有释放之前,redisson会自动给锁续期(10s检查一次锁是否释放,续期time-30s),不会过期,直至线程结束锁释放。
2- -redis 的stringRedisTemplate分布式锁不会自动续期。
redisson加锁的业务代码只要完成,就不会自动给锁续期,即使不unlock,锁默认在30s后自动删除。即使服务宕机-业务结束,也不会出现死锁,锁会自动过期。

  1. 读写锁相关
    // 6.1 读写锁(可以获read-write)
    RReadWriteLock readWriteLock = redissonClient.getReadWriteLock(“catalogJson-lock”);
    // 6.2 写锁
    RLock wLock = readWriteLock.writeLock();
    // 6.3 读锁
    RLock rLock = lock.readLock();
    注意
    1)一个读锁可以被多个thread线程占用不互斥。
    2)写锁与其他锁都互斥,一次只能有一个线程占用锁,其他写或者读必须等待。

  2. 分布式锁的几个参数
    创建锁的过期时间,时间单位,redisson分布式锁默认是10s查看一次锁是否还在,如果在自动延长30s(前提是没有手动设置过期时间)

  3. redisson分布式锁的特点
    1)一次只能有一个进程的一个线程进来
    2)有看门狗机制,redisson–自动续期30s,业务未执行完,其他锁进来造成数据紊乱
    3)自动过期-避免死锁(什么是死锁,加锁->执行业务->执行完解锁,没有解锁业务代码出异常或者服务挂了,锁就一直存在redis缓存数据库中-死锁)

  4. redisson看门狗机制(给线程看门,线程进去执行业务,redisson看门)
    redisson-redissonClient提供的分布锁,一旦某个线程进入到占了锁,在业务代码没有执行完成,释放锁之前,redisson没10s会自动检测锁是否还在,并续期30s。直至业务完成,解锁,不再自动续期。这种情况只针对没有手动配置过期时间的前提,如果配置了则失效。

  5. redission的可重入锁机制
    Redisson 可重入锁是一种分布式锁,它基于 Redis 实现。可重入指的是同一个线程在持有锁的情况下,可以多次获取该锁而不会造成死锁。

<三>SpringCache-分布式缓存使用

  1. springcache是什么
    spring提供的一个缓存框架,使用一些注解解决缓存的问题,不需要关心底层代码逻辑如何实现

  2. 使用redis作为缓存工具,cache使用步骤
    1)pom文件加上依赖
    引入依赖 spring-boot-starter-cache
    spring-boot-starter-data-redis
    2)手动在配置文件加上缓存类型(其他配置后面使用场景再说)
    spring.cache.type=redis
    3)开启缓存@EnableCaching // 开启缓存,加在对应Configuration类上面

3.springcache 主要的注解
1)@EnableCaching-开启缓存
2)@Cacheable 加上方法上面,触发方法更新缓存(如果缓存不是null则不存储db数据到缓存中)
3)@CacheEvict,更新数据库触发删除缓存对应的数据-失效模式
4)@CachePut,更新数据库,在不影响更新数据库的情况下,更新缓存数据-双写模式。

  1. springcache有哪些不足之处?该缓存框架默认不加锁
    1)读模式(@Cacheable-读db->set->redis)
    只要涉及读db数据到redis缓存,且不加锁的情况,大并发就会暴露redis存储缺陷。
    a. 缓存穿透-开启db空值也存到redis中
    配置文件加
    spring.cache.redis.cache-null-values=true

    b. 缓存雪崩-配置设置缓存的过期时间
    spring.cache.redis.time-to-live=600000

    c. 缓存击穿-加锁
    springCache默认是不加分布式锁的,可以对应方法上
    @Cacheable注解上面加上sync = “true”,线程加锁-一次只允许一个线程占用锁访问db-避免热点击穿db。
    @Cacheable(value = “category”, key = “#root.method.name”, sync = true)

    2)写模式
    数据写模式对应的是更新数据,势必涉及更新db与更新缓存,两者存在数据一致性问题。
    解决方法:对于读多写少的数据,直接使用springcache缓存即可,key设置过期时间,查询触发再次更新db数据到缓存redis中。

总结
redis-缓存中间件-暂时的非关系key-value键值对数据库,StringRedisTemplate操作。
redisson-基于redis操作的数据库,提供分布式锁,解决分布式下操作redis缺陷。-使用redissonClient操作分布式锁(单体不需要redisson,本地锁就可以解决)
springcache-spring提供的分布式缓存框架,可以使用多种缓存中间件存储数据,本文type是redis,直接使用一些注解实现redis读-存储,写-写/删数据。不需要再单独使用redis执行一些列繁琐的代码实现。

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

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

相关文章

leetcode-413. 等差数列划分(java)

等差数列划分 leetcode-413. 等差数列划分题目描述双指针 上期经典算法 leetcode-413. 等差数列划分 难度 - 中等 原题链接 - 等差数列划分 题目描述 如果一个数列 至少有三个元素 &#xff0c;并且任意两个相邻元素之差相同&#xff0c;则称该数列为等差数列。 例如&#xff0…

16 脑洞大开:GUI测试还能这么玩

页面对象自动生成技术 页面对象自动生成技术&#xff0c;属于典型的“自动化你的自动化”的应用场景。它的基本思路是&#xff0c;你不用再手工维护 Page Class 了&#xff0c;只需要提供 Web 的 URL&#xff0c;它就会自动帮你生成这个页面上所有控件的定位信息&#xff0c;并…

JMeter接口测试数据分离驱动应用

步骤&#xff1a; 创建csv文件&#xff0c;编写接口测试用例 新建线程组——创建循环控制器&#xff08;循环次数填用例总数&#xff09; 创建CSV数据文件设置&#xff0c;设置参数。&#xff08;注意&#xff1a;是否允许带引号&#xff1f;&#xff1a;一定要设置为true&a…

深度学习实战48-【未来的专家团队】基于AutoCompany模型的自动化企业概念设计与设想

大家好,我是微学AI,今天给大家介绍一下深度学习实战48-【未来的专家团队】基于AutoCompany模型的自动化企业概念设计与设想,文本将介绍AutoCompany模型的概念设计,涵盖了AI智能公司的各个角色,并结合了GPT-4接口来实现各个角色的功能,设置中央控制器,公司运作过程会生成…

【MFC常用问题记录】

MFC 记录 MFC的edit control控件显示1.控件添加变量M_edit后&#xff1a;2.控件ID为IDC_EDIT1: 线程函数使用 MFC的edit control控件显示 1.控件添加变量M_edit后&#xff1a; CString str; int x 10; str.Format(_T("%d"),x); M_edit.SetWindowText(str)2.控件ID…

JMM内存模型之happens-before阐述

文章目录 一、happens-before的定义二、happens-before的规则1. 程序顺序规则&#xff1a;2. 监视器锁规则&#xff1a;3. volatile变量规则&#xff1a;4. 传递性&#xff1a;5. start()规则&#xff1a;6. join()规则&#xff1a; 一、happens-before的定义 如果一个操作hap…

【编程二三事】ES究竟是个啥?

在最近的项目中&#xff0c;总是或多或少接触到了搜索的能力。而在这些项目之中&#xff0c;或多或少都离不开一个中间件 - ElasticSearch。 今天忙里偷闲&#xff0c;就来好好了解下这个中间件是用来干什么的。 ES是什么? ​ ES全称ElasticSearch&#xff0c;是个基于Lucen…

性能优化的重要性

性能优化的重要性 性能优化的重要性摘要引言注意事项代码示例及注释性能优化的重要性 性能优化的重要性在 Java 中的体现响应速度资源利用效率扩展性与可维护性并发性能合理的锁策略线程安全的数据结构并发工具类的应用避免竞态条件和死锁 总结代码示例 博主 默语带您 Go to Ne…

一张图看懂 USDT三种类型地址 Omni、ERC20、TRC20的区别

USDT是当前实用最广泛&#xff0c;市值最高的稳定币&#xff0c;它是中心化的公司Tether发行的。在今年的4月17日之前&#xff0c;市场上存在着2种不同类型的USDT。4月17日又多了一种波场TRC20协议发行的USDT&#xff0c;它们各自有什么区别呢?哪个转账最快到账&#xff1f;哪…

谷歌推出首款量子弹性 FIDO2 安全密钥

谷歌在本周二宣布推出首个量子弹性 FIDO2 安全密钥&#xff0c;作为其 OpenSK 安全密钥计划的一部分。 Elie Bursztein和Fabian Kaczmarczyck表示&#xff1a;这一开源硬件优化的实现采用了一种新颖的ECC/Dilithium混合签名模式&#xff0c;它结合了ECC抵御标准攻击的安全性和…

[LeetCode]矩阵对角线元素的和

解题 思路 1: 循环,找到主对角线的下标和副对角线的下标,如果矩阵长或宽为奇数的时候,需要减去中间公共的那一个值,中间公共的那个数的下标为mat[mat.size()/2][mat.size()/2]副对角线的下标为 mat [i][mat.size()-i-1] class Solution { public:int diagonalSum(vector<ve…

JVM中判定对象是否回收的的方法

引用计数法 引用计数法是一种垃圾回收&#xff08;Garbage Collection&#xff09;算法&#xff0c;用于自动管理内存中的对象。在引用计数法中&#xff0c;每个对象都有一个关联的引用计数器&#xff0c;用于记录对该对象的引用数量。 当一个新的引用指向对象时&#xff0c;…

Hive底层数据存储格式

前言 在大数据领域,Hive是一种常用的数据仓库工具,用于管理和处理大规模数据集。Hive底层支持多种数据存储格式,这些格式对于数据存储、查询性能和压缩效率等方面有不同的优缺点。本文将介绍Hive底层的三种主要数据存储格式:文本文件格式、Parquet格式和ORC格式。 一、三…

SpringBoot复习:(42)WebServerCustomizer的customize方法是在哪里被调用的?

ServletWebServletAutoConfiguration类定义如下&#xff1a; 可以看到其中通过Import注解导入了其内部类BeanPostProcessorRegister。 BeanPostProcessor中定义的registerBeanDefinition方法会被Spring容器调用。 registerBeanDefinitions方法调用了RegistrySyntheticBeanIf…

解决vue3前端获取文件的绝对路径问题

解决vue3前端获取文件的绝对路径问题 公司的项目是基于vue3的&#xff0c;由于需求需要前端获取用户选的文件的绝对路径。但是浏览器处于安全策略无法获取真实的文件路径&#xff0c;只能拿到相对路径或者是D:\fakepath\xxxx. 看了网上很多方法都很坑&#xff0c;明明没拿到路…

vue基础-vue监听当前屏幕大小做不同的操作

文章目录 前言一、代码如下&#xff1a;总结 前言 在vue项目开发过程中&#xff0c;有个需求&#xff0c;就是当屏幕大于1024时&#xff0c;我们默认为PC模式。小于1024时&#xff0c;我们默认为H5模式。但是有的界面我们想在PC和H5上面展示不同的数据&#xff0c;请求不同的接…

Intellij IDEA SBT依赖分析插件

可分析模块和传递依赖 安装完插件后&#xff0c;由于IDEA BUG&#xff0c;会出现两个分析按钮&#xff0c;一个是gradle的&#xff0c;一般是后者是新安装的sbt。 选择需要分析的模块 只需要在project/plugins.sbt中添加代码&#xff0c;启动官方分析插件addDependencyTreeP…

1281. 整数的各位积和之差

诸神缄默不语-个人CSDN博文目录 力扣刷题笔记 文章目录 1. 简单粗暴的遍历2. 其实也是遍历&#xff0c;但是用Python内置函数只用写一行 1. 简单粗暴的遍历 Python版&#xff1a; class Solution:def subtractProductAndSum(self, n: int) -> int:he0ji1while n>1:last…

redis 数据结构(一)

Redis 为什么那么快 redis是一种内存数据库&#xff0c;所有的操作都是在内存中进行的&#xff0c;还有一种重要原因是&#xff1a;它的数据结构的设计对数据进行增删查改操作很高效。 redis的数据结构是什么 redis数据结构是对redis键值对值的数据类型的底层的实现&#xff0c…

WordToPDF2.java

用Java将Word转PDF 本例子测试了spire.doc.free-3.9.0.jar的包 <dependency><groupId> e-iceblue </groupId><artifactId>spire.doc.free</artifactId><version>3.9.0</version></dependency> package word;import com.spire.…