redis缓存穿透和击穿解决方案,redis缓存穿透解决

  redis缓存穿透和击穿解决方案,redis缓存穿透解决

  00-1010 1什么是缓存崩溃2为什么要使用分布式锁3什么是Redisson 4 Spring Boot集成Redisson4.1添加maven依赖4.2配置yml4.3配置RedissonConfig5使用redis on的分布式锁解决缓存崩溃。

  00-1010 A热门数据,访问量非常大。在缓存失效的那一刻,大量请求直接到存储层,导致服务崩溃。

  00-1010在项目中,当存在共享资源的竞争时,为了防止并发问题,我们通常采用锁机制来控制。在单机环境下,可以使用synchronized或Lock实现;但是在分布式系统中,由于竞争的线程可能不在同一个节点上(在同一个jvm中),所以它需要一个所有进程都能访问的锁,比如mysql、redis和zookeeper。

  

目录

Redis on是一个基于Redis的Java内存数据网格。它不仅提供了一系列分布式Java公共对象,实现了重入锁、公平锁、多锁、红锁、读写锁等,还提供了许多分布式服务。Redisson提供了使用Redis的最简单和最方便的方法。Redisson的目的是促进用户对Redis的关注点分离,让用户更专注于业务逻辑。

 

  

1 什么是缓存击穿

 

  00-1010不再需要spring-boot-starter-data-redis依赖,但是把它们都加起来也不会出错。

  !-redis on-dependency groupIdorg.redisson/groupId artifactId redis on-spring-boot-starter/artifactId版本3.17.0/version/dependency

  

2 为什么要使用分布式锁

spring:数据源:用户名: xx密码:

 

  ingframework.context.annotation.Configuration;import org.springframework.data.redis.cache.RedisCacheConfiguration;import org.springframework.data.redis.cache.RedisCacheManager;import org.springframework.data.redis.connection.RedisConnectionFactory;import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;import org.springframework.data.redis.serializer.RedisSerializationContext;import org.springframework.data.redis.serializer.RedisSerializer;import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;import java.util.Random;@EnableCaching@Configurationpublic class RedissonConfig {    @Value("${spring.redis.host}")    private String host;    @Value("${spring.redis.port}")    private String port;    @Value("${spring.redis.password}")    private String password;    @Bean(destroyMethod = "shutdown")  // bean销毁时关闭Redisson实例,但不关闭Redis服务    public RedissonClient redisson() {        //创建配置        Config config = new Config();        /**         *  连接哨兵:config.useSentinelServers().setMasterName("myMaster").addSentinelAddress()         *  连接集群: config.useClusterServers().addNodeAddress()         */        config.useSingleServer()                .setAddress("redis://" + host + ":" + port)                .setPassword(password)                .setTimeout(5000);        //根据config创建出RedissonClient实例        return Redisson.create(config);    }    @Bean    public CacheManager RedisCacheManager(RedisConnectionFactory factory) {        RedisSerializer<String> redisSerializer = new StringRedisSerializer();        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);        // 解决查询缓存转换异常的问题        ObjectMapper om = new ObjectMapper();        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);        /**         * 新版本中om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)已经被废弃         * 建议替换为om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL)         */        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);        jackson2JsonRedisSerializer.setObjectMapper(om);        // 配置序列化解决乱码的问题        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()                // 设置缓存过期时间  为解决缓存雪崩,所以将过期时间加随机值                .entryTtl(Duration.ofSeconds(60 * 60 + new Random().nextInt(60 * 10)))                // 设置key的序列化方式                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))                // 设置value的序列化方式                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer));        // .disableCachingNullValues(); //为防止缓存击穿,所以允许缓存null值        RedisCacheManager cacheManager = RedisCacheManager.builder(factory)                .cacheDefaults(config)                // 启用RedisCache以将缓存 put/evict 操作与正在进行的 Spring 管理的事务同步                .transactionAware()                .build();        return cacheManager;    }}

 

  

5 使用Redisson的分布式锁解决缓存击穿

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;import com.company.dubbodemo.entity.User;import com.company.dubbodemo.mapper.UserMapper;import com.company.dubbodemo.service.UserService;import org.redisson.api.RLock;import org.redisson.api.RedissonClient;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;import javax.annotation.Resource;@Servicepublic class UserServiceImpl extends ServiceImpl<UserMapper, User>        implements UserService {        @Resource    private RedissonClient redissonClient;    @Resource    private UserMapper userMapper;    @Override    // 一定要设置sync = true开启异步,否则会导致多个线程同时获取到锁    @Cacheable(cacheNames = "user", key = "#id", sync = true)    public User findById(Long id) {        /**         *         * 加了@Cacheable之后方法体执行说明缓存中不存在所查询的数据         * 获取一把锁,只要锁的名字一样,就是同一把锁         */        /**         * 注意: 如果设置了lock.lock(10,TimeUnit.SECONDS) 锁过期不会自动续期         *      1、如果我们传递了锁的过期时间,就发送给redis执行脚本,进行占锁,默认超时就是我们指定的时间         *      2、如果没有指定锁的超时时间,就使用30000L(LockWatchdogTimeout 看门狗的默认时间)         *      可通过RedissonConfig-->getRedissonClient()-->config.setLockWatchdogTimeout()设置看门狗时间         *         只要占锁成功就会启动一个定时任务【就会重新给锁设置过期时间,新的时间就是看门狗的默认时间】,每隔10s都会自动续期,续期成30s         * 看门狗机制         * 1、锁的自动续期,如果业务超长,运行期间自动给锁续上新的30s。不用担心因为业务时间长,锁自动过期被删除         * 2、加锁的业务只要运行完成,就不会给当前锁续期,即使不手动解锁,锁默认在30s以后自动删除         *         */        RLock lock = redissonClient.getLock("redissonClient-lock");        // 对第一个线程执行方法体的线程加锁,加了@Cacheable,方法执行之后会将方法的返回值存入缓存,下一个线程直接读取缓存        lock.lock();        User user = new User();        try {            user = userMapper.selectById(id);        } catch (Exception e) {            e.printStackTrace();        } finally {            lock.unlock();        }        return user;    }}

到此这篇关于详解Spring Cache使用Redisson分布式锁解决缓存击穿问题的文章就介绍到这了,更多相关Spring Cache 缓存击穿内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

 

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • 关于redis数据库入门详细介绍图片,redis数据库的使用,关于Redis数据库入门详细介绍
  • redis队列操作命令,redis 循环队列
  • redis队列操作命令,redis 循环队列,redis实现简单队列
  • redis部署应用服务器上,redis如何启动服务器
  • redis部署应用服务器上,redis如何启动服务器,搭建Redis服务器步骤详细介绍
  • redis缓存穿透和击穿解决方案,redis缓存穿透,缓存雪崩解决
  • redis缓存穿透和击穿解决方案,redis缓存穿透,缓存雪崩解决,redis缓存穿透解决方法
  • Redis缓存,redis和缓存
  • Redis缓存,redis和缓存,Redis缓存详解
  • redis的配置,启动,操作和关闭方法有哪些,关闭redis的命令,Redis的配置、启动、操作和关闭方法
  • redis的主从配置方法详解图,Redis主从配置
  • redis的主从配置方法详解图,Redis主从配置,redis的主从配置方法详解
  • redis界面工具,mac安装redis可视化工具
  • redis界面工具,mac安装redis可视化工具,推荐几款 Redis 可视化工具(太厉害了)
  • redis正确使用的十个技巧是什么,redis正确使用的十个技巧有哪些
  • 留言与评论(共有 条评论)
       
    验证码: