• Redis缓存穿透-热点缓存并发重建-缓存与数据库双写不一致-缓存雪崩


    如何解决线上缓存穿透问题

    缓存击穿(缓存失效)

    解决思路:

    只需要加上过期时间随机值,能够保证上万条数据不同时过期,减少对数据库的压力,同一时刻缓存中还是有数据的

    redisUtil.set(key, JSON.toJSONString(cookies), 24 * 60 * 60 , TimeUnit.SECONDS);
    
    • 1

    new Random().nextInt(30)60; 随机产生一个[0~3060)int类型的数值

    redisUtil.set(key, JSON.toJSONString(cookies), 24 * 60 * 60 + new Random().nextInt(30)*60, TimeUnit.SECONDS);
    
    • 1

    缓存穿透(数据删除)

    上万条数据同时请求数据,缓存中没有数据,去数据库中数据库中也没有数据,穿透所有的持久层

    解决思路:

    为了防止缓存穿透,在第一条数据进行请求的时候发现缓存和数据库中都没有要求请的数据,就在缓存中放一个空串{},下次再次请求的时,读取到缓存中的值,判断值如果是空串则返回null ,否则返回对应的值。

    基于DCL机制解决热点缓存并发重建问题实战

    上万条请求同时请求某一条数据

    方法一:
    添加同步锁机制synchronized,,,,
    (双重检测锁)解决突发热点并发重建导致DB压力暴增
    让第一个请求先查Redis缓存,若不存在查DB,查到写入Redis缓存
    后续的请求再访问Redis时,直接取值

    synchronized(this){
    	//Redis缓存中取数据,
    	//缓存中不存在该条数据,请求DB,存到Redis中
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    方法二:
    使用Redis分布式锁

    在这里插入图片描述

    引入依赖

    <dependency>
        <groupId>org.redisson</groupId>
        <artifactId>redissson</artifactId>
        <version>3.6.5</version>
    </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    @Autowired
    private Redisson redisson;
    RLock hotCacheCreateLock = redisson.getLock(key);
    hotCacheCreateLock.locak();  //相当于执行了setnx(k,v)     // 加锁
    try{
    	//Redis缓存中取数据,
    	//缓存中不存在该条数据,请求DB,存到Redis中
    } finally {
    	hotCacheCreateLock.unlock();  //删除锁  del k 删除key
    }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Redis分布式锁解决缓存与数据库双写不一致问题实战

    在这里插入图片描述

    解决办法:Redis 分布式锁

    @Autowired
    private Redisson redisson;
    RLock hotCacheCreateLock = redisson.getLock(key);
    hotCacheCreateLock.locak();  //相当于执行了setnx(k,v)     // 加锁
    try{
    	//Redis缓存中取数据,
    	RLock updateCreateLock = redisson.getLock(key2);
    	updateCreateLock.locak();  //相当于执行了setnx(k,v)     // 加锁
    	try{
    		 //缓存中不存在该条数据,读取DB中数据,并存到Redis中
    	} finally {
    	   updateCreateLock.unlock();  //删除锁  del k 删除key2
    	}
    
    } finally {
    	hotCacheCreateLock.unlock();  //删除锁  del k 删除key
    }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    优化:可以用读写锁
    对读多写少进行优化——所有的读操作并行执行,读和写互斥串行执行

    读数据库中的数据

    @Autowired
    private Redisson redisson;
    RLock hotCacheCreateLock = redisson.getLock(key);
    hotCacheCreateLock.locak();  //相当于执行了setnx(k,v)     // 加锁
    try{
    	//Redis缓存中取数据,
    	//RLock updateCreateLock = redisson.getLock(key2);
    	RReadWriteLock readWriteLock = redisson.getReadWriteLock(ke2)
    	RLock rLock = readWriteLock.readLock();
    	rLock.locak();   // 加读锁  setnx(k,v)   
    	try{
    		 //缓存中不存在该条数据,读取DB中数据,并存到Redis中
    	} finally {
    	   rLock.unlock();  //删除锁
    	}
    
    } finally {
    	hotCacheCreateLock.unlock();  //删除锁  del k 删除key
    }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    更新数据库中数据

    RReadWriteLock readWriteLock = redisson.getReadWriteLock(ke2)
    RLock wLock = readWriteLock.writeLock();
    wLock.locak();   // 加写锁  setnx(k,v)   
    try{
    	//修改数据库中的数据操作
    } finally {
    	wLock.unlock();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    读数据缓存锁优化

    @Autowired
    private Redisson redisson;
    RLock hotCacheCreateLock = redisson.getLock(key);
    //hotCacheCreateLock.locak();  //相当于执行了setnx(k,v)     // 加锁
    hotCacheCreateLock.tryLock(2,TimeUnit.SECONDS);   //等待2秒后锁失效(设置合适的时间)
    try{
    	//Redis缓存中取数据,
    	//RLock updateCreateLock = redisson.getLock(key2);
    	RReadWriteLock readWriteLock = redisson.getReadWriteLock(ke2)
    	RLock rLock = readWriteLock.readLock();
    	rLock.locak();   // 加读锁  setnx(k,v)   
    	try{
    		 //缓存中不存在该条数据,读取DB中数据,并存到Redis中
    	} finally {
    	   rLock.unlock();  //删除锁
    	}
    
    } finally {
    	hotCacheCreateLock.unlock();  //删除锁  del k 删除key
    }  
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    利用多级缓存架构解决Redis线上集群缓存雪崩问题

    Redis单节点高并发最高10W+,,,瞬间来了几十W上百W的请求来查Redis中数据,Redis直接宕机了,,,缓存雪崩问题

    web应用分流,,,
    多级缓存——JVM进程级别缓存
    JVM进程级别的缓存一般来说都是有容量上的限制

  • 相关阅读:
    一个由public关键字引发的bug
    一道数学题,让芯片巨头亏了5亿美金!
    20230830比赛总结
    Python subprocess模块学习笔记
    Redis 先操作数据库和先删除缓存, 一致性分析
    导数求函数最大值和最小值习题
    5 年 Python ,总结的 10 条 Python 使用技巧
    数组清空(bzero与memset)
    [HITCON CTF 2022] crypto bypass
    城市、机场、服务区等场景下的智慧公厕建设诀窍揭秘
  • 原文地址:https://blog.csdn.net/qq_45896330/article/details/125975423