当前位置: 首页>后端>正文

缓存使用-整合Redis

整合redis步骤

  • 1)、引入data-redis-start
  • 2)、简单配置redis的host信息
  • 3)、使用springboot自动配置好的StringRedisTemplaes来操作redis
    redis->map 存放key,数据值value

一、整合redis

pom.xml引入redis

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>io.lettuce</groupId>
                    <artifactId>lettuce-core</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

二、application添加redis配置

spring:
  redis:
    host: 127.0.0.1
    port: 6379

三、测试

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Test
    public void testStringRedisTemplate(){
        ValueOperations<String, String> ops= stringRedisTemplate.opsForValue();
        // 保存
        ops.set("hello","value_"+ UUID.randomUUID().toString());
        // 查询
        String hello = ops.get("hello");
        System.out.println("之前保存的数据是:"+hello);
    }

  • 1)、springboot2.0以后默认使用lettuce作为操作redis的客户端,它使用netty进行网络通信。

  • 2)、lettuce的bug导致netty堆外溢出 -Xmx300m;netty如果没有指定堆外内存,默认使用-Xmx300m

  • 解决方案:不能使用-Dio.netty.maxDirectMemory只去调大堆外内存

1、升级lettuce客户端
2、切换使用jedis
redisTemplate:
lettuce,jedis操作redis底层客户端。spring再次封装redisTemplace;

缓存穿透

?缓存穿透是指查询一个一定不存在的数据,由于缓存是不命中,将去查询数据库,但是数
据库也无此记录,我们没有将这次查询的 null 写入缓存,这将导致这个不存在的数据每次
请求都要到存储层去查询,失去了缓存的意义。
? 在流量大时,可能 DB 就挂掉了,要是有人利用不存在的 key 频繁攻击我们的应用,这就是
漏洞。
? 解决:
缓存空结果、并且设置短的过期时间。

缓存击穿

? 对于一些设置了过期时间的 key,如果这些 key 可能会在某些时间点被超高并发地访问,
是一种非常“热点”的数据。
? 这个时候,需要考虑一个问题:如果这个 key 在大量请求同时进来前正好失效,那么所
有对这个 key 的数据查询都落到 db,我们称为缓存击穿。
? 解决:
加锁

缓存雪崩

? 缓存雪崩是指在我们设置缓存时采用了相同的过期时间,导致缓存在某一时刻同时失
效,请求全部转发到 DB,DB 瞬时压力过重雪崩。
? 解决:
原有的失效时间基础上增加一个随机值,比如 1-5 分钟随机,这样每一个缓存的过期时间的
重复率就会降低,就很难引发集体失效的事件。

Redisson 完成分布式锁

Redisson 是架设在 Redis 基础上的一个 Java 驻内存数据网格(In-Memory Data Grid)。充分
的利用了 Redis 键值数据库提供的一系列优势,基于 Java 实用工具包中常用接口,为使用者
提供了一系列具有分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的工
具包获得了协调分布式多机多线程并发系统的能力,大大降低了设计和研发大规模分布式
系统的难度。同时结合各富特色的分布式服务,更进一步简化了分布式环境中程序相互之间
的协作。
官方文档:https://github.com/redisson/redisson/wiki/%E7%9B%AE%E5%BD%95

缓存数据一致性

保证一致性模式
1、双写模式
2、失效模式
3、改进方法 1-分布式读写锁

  • 缓存的所有数据都有过期时间,数据过期下一次查询触发主动更新
  • 读写数据的时候,加上分布式的读写锁

4、改进方法 2-使用 cananl

四、spring-cache的不足

 *  1)读模式
 *      缓存穿透:查询一个null数据。解决:缓存空数据:spring.cache.redis.cache-null-values=true
 *      缓存击穿:大量并发进来同时查询一个正好过期的数据。解决:加锁 默认无加锁 sync = true加锁
 *      缓存雪崩:大量key同时过期。解决:加随机时间。加上过期时间:spring.cache.redis.time-to-live=3600000
 *  2)写模式:(缓存与数据库一致)
 *      1)读写加锁
 *      2)引入canal,感知mysql的更新去更新数据库
 *      3)读多写多,直接去数据库查询就行
 *  总结:常规数据,(读多写少,即时性,一致性要求不高的数据):完全可以使用Spring-Cache;写模式,只要缓存的的数据有过期时间就行
 *      特殊数据:特殊设计
 * 原理:
 *      CacheManager(RedisCacheManager)->Cache(RedisCache)->Cache负责缓存的读写

https://www.xamrdz.com/backend/3qf1942653.html

相关文章: