`
y806839048
  • 浏览: 1120681 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

redis的进程锁避免缓存击穿

阅读更多

 

redis的进程锁避免缓存击穿

 

首先由于系统的特性知道哪些键是热键,针对这些热键,哪个线程发现自己现在拿的是空,马上锁住,获取向下操作的资格,其他阻塞(这样就不会对db压力大(不然都去访问db)),然后马上这UI个线程请求db获取数据填充缓存

 

缓存击穿

对于一些设置了过期时间的key,如果这些key可能会在某些时间点被超高并发地访问,是一种非常“热点”的数据。这个时候,需要考虑一个问题:缓存被“击穿”的问题,这个和缓存雪崩的区别在于这里针对某一key缓存,前者则是很多key。

 

缓存在某个时间点过期的时候,恰好在这个时间点对这个Key有大量的并发请求过来,这些请求发现缓存过期一般都会从后端DB加载数据并回设到缓存,这个时候大并发的请求可能会瞬间把后端DB压垮。

 

解决方案

1.使用互斥锁(mutex key)

业界比较常用的做法,是使用mutex。简单地来说,就是在缓存失效的时候(判断拿出来的值为空),不是立即去load db,而是先使用缓存工具的某些带成功操作返回值的操作(比如Redis的SETNX或者Memcache的ADD)去set一个mutex key,当操作返回成功时,再进行load db的操作并回设缓存;否则,就重试整个get缓存的方法。

SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果。在redis2.6.1之前版本未实现setnx的过期时间,所以这里给出两种版本代码参考:

[java] view plain copy 在CODE上查看代码片派生到我的代码片

//2.6.1前单机版本锁  

String get(String key) {    

   String value = redis.get(key);    

   if (value  == null) {    

    if (redis.setnx(key_mutex, "1")) {    

        // 3 min timeout to avoid mutex holder crash    

        redis.expire(key_mutex, 3 * 60)    

        value = db.get(key);    

        redis.set(key, value);    

        redis.delete(key_mutex);    

    } else {    

        //其他线程休息50毫秒后重试    

        Thread.sleep(50);    

        get(key);    

    }    

  }    

}  

最新版本代码:

[java] view plain copy 在CODE上查看代码片派生到我的代码片

public String get(key) {  

      String value = redis.get(key);  

      if (value == null) { //代表缓存值过期  

          //设置3min的超时,防止del操作失败的时候,下次缓存过期一直不能load db  

          if (redis.setnx(key_mutex, 1, 3 * 60) == 1) {  //代表设置成功  

               value = db.get(key);  

                      redis.set(key, value, expire_secs);  

                      redis.del(key_mutex);  

              } else {  //这个时候代表同时候的其他线程已经load db并回设到缓存了,这时候重试获取缓存值即可  

                      sleep(50);  

                      get(key);  //重试  

              }  

          } else {  

              return value;        

          }  

分享到:
评论

相关推荐

    Redis使用-缓存穿透,雪崩,击穿以及解决方案分析.docx

    4. 使用分布式锁机制,例如使用 ZooKeeper 或 Etcd 等分布式锁,来避免缓存击穿问题。 缓存穿透、雪崩、击穿都是缓存使用中可能出现的问题,但是通过合理的解决方案,可以避免这些问题的出现,并确保系统的稳定运行...

    如何设计缓存系统:缓存穿透,缓存击穿,缓存雪崩解决方案分析.docx

    缓存系统设计解决方案分析 缓存系统是当前web应用程序中最常用的性能...缓存系统设计需要考虑的要素很多,但是如果我们采用合适的解决方案,可以避免缓存穿透、缓存雪崩和缓存击穿等问题,提高系统的性能和可靠性。

    缓存穿透,缓存击穿,缓存雪崩解决方案分析.docx

    缓存穿透、缓存击穿、缓存雪崩解决方案分析 本文主要介绍了缓存系统中三个常见的问题:缓存穿透、缓存击穿和缓存雪崩,并对每个问题提供了多种解决方案。 缓存穿透 缓存穿透是指查询一个一定不存在的数据,由于...

    常见的缓存穿透,缓存击穿,缓存雪崩解决方案分析.docx

    在Redis 2.6.1之前的版本,`SETNX`命令没有设置过期时间的能力,因此在旧版本中需要手动添加过期时间,以避免持有锁的进程崩溃导致无法释放锁。 ```java // 2.6.1前单机版本锁实现 public String get(String ...

    高性能分布式缓存 Redis1

    - **缓存失效策略**:缓存穿透、缓存雪崩和缓存击穿是高并发场景下的潜在风险,需合理设计缓存失效机制。 - **键的设计**:通常将表名作为key前缀,用冒号分隔,然后是列名和主键值,如`user:6`。 **Redis的特定...

    缓存和分布式锁.pdf

    缓存击穿通常发生在高并发访问热点数据时,如果这些数据恰好过期了,也会造成瞬间流量集中到数据库。为此,可以采取热点数据不过期或者使用分布式锁保护数据更新。 二、缓存整合Redis 在Spring Boot项目中整合...

    60道关于Redis的常见面试题.pdf

    在使用 Redis 过程中,你如何处理缓存击穿的问题?能详细说明一下解决方案吗? - **缓存击穿**:缓存和数据库中的数据同时失效,导致大量请求直接打到数据库,引起数据库压力过大。 - **解决方案**: - 使用互斥...

    Redis非关系型数据库笔记-数据持久化-主从同步-缓存-笔记-五大数据类型-三大特殊数据类型

    - **缓存击穿**: 大量并发请求同时访问同一缓存数据,导致后端数据库压力过大。 - **解决方案**: 使用互斥锁(Mutex)或者双重检查锁定(Double-Checked Locking)来控制并发访问。 - **缓存雪崩**: 缓存中大量数据同时...

    高效Java后台程序缓存用户信息的研究.zip

    3. **缓存击穿**:某一热点key刚好过期,此时大量请求同时到达,导致数据库压力剧增。 解决方案:设置热点key永不过期,或者使用预加载策略。 六、缓存更新策略 1. **写后读(Write Through)**:更新数据库后...

    springboot-01-cache.rar_browndl4_goldk4u_mill18b_springboot

    6. **缓存穿透、缓存击穿与缓存雪崩**:这三个是缓存系统常见的问题,需要合理设计缓存策略来避免。缓存穿透是指请求的数据在数据库中不存在,造成对数据库的无效查询;缓存击穿是大量请求同一时刻到达,导致缓存...

    Java 面试资料 进阶版

    - **区别**: 缓存击穿针对单一热点key,而缓存雪崩涉及大量key同时过期,影响更大。 - **解决方案**: - **热点数据永不过期**: 减少因过期导致的请求激增。 - **随机过期时间**: 为每个key设置不同的过期时间,...

    java学科12月份面试问题收集.docx

    11. **Redis缓存击穿解决方案**: - 分布式锁:保证同一时刻只有一个线程更新缓存。 - 设置超时标记:在缓存对象中包含一个超时时间戳,临近超时时异步刷新缓存。 - 热点数据不过期:在高峰期保持缓存,低峰期再...

    2020春招 字节 广州 面经1

    - **缓存击穿**:特定key在缓存中过期,大量请求直接到达数据库。 - **缓存雪崩**:大量缓存同时过期,导致请求瞬间涌入数据库。 - **缓存穿透**:恶意请求不存在的key,导致数据库压力增大。 15. **TCP连接**:...

    20届同学大厂社招面经(字节阿里虾皮滴滴offer).docx

    - **实现数据一致性**:使用缓存穿透、缓存击穿和缓存雪崩的解决方案,如使用布隆过滤器预防穿透,设置合理的缓存超时时间防止击穿,分散热点数据减轻雪崩效应。 **知识点四:消息队列故障处理** - **消息队列作用*...

    2022面试题6java背诵版本.doc

    9. **Redis雪崩和击穿**: - 雪崩:大量缓存同时过期,导致数据库瞬间压力过大。 - 击穿:某个热点key过期,所有请求直接穿透到数据库。 10. **面向对象的理解**: 面向对象编程(OOP)是一种编程范式,以对象为...

Global site tag (gtag.js) - Google Analytics