缓存雪崩

  缓存雪崩是由于原有缓存失效(过期),新缓存未到期间。所有请求都去查询数据库,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机。从而形成一系列连锁反应,造成整个系统崩溃。

  1. 碰到这种情况,一般并发量不是特别多的时候,使用最多的解决方案是加锁排队。

 public object GetProductListNew()
{
const int cacheTime = 30;
const string cacheKey = "product_list";
const string lockKey = cacheKey; var cacheValue = CacheHelper.Get(cacheKey);
if (cacheValue != null)
{
return cacheValue;
}
else
{
lock (lockKey)
{
cacheValue = CacheHelper.Get(cacheKey);
if (cacheValue != null)
{
return cacheValue;
}
else
{
cacheValue = GetProductListFromDB(); //这里一般是 sql查询数据。
CacheHelper.Add(cacheKey, cacheValue, cacheTime);
}
}
return cacheValue;
}
}

  2. 加锁排队只是为了减轻数据库的压力,并没有提高系统吞吐量。假设在高并发下,缓存重建期间key是锁着的,这是过来1000个请求999个都在阻塞的。同样会导致用户等待超时,这是个治标不治本的方法。

  还有一个解决办法解决方案是:给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。

     public object GetProductListNew()
{
const int cacheTime = 30;
const string cacheKey = "product_list";
//缓存标记。
const string cacheSign = cacheKey + "_sign"; var sign = CacheHelper.Get(cacheSign);
//获取缓存值
var cacheValue = CacheHelper.Get(cacheKey);
if (sign != null)
{
return cacheValue; //未过期,直接返回。
}
else
{
CacheHelper.Add(cacheSign, "1", cacheTime);
ThreadPool.QueueUserWorkItem((arg) =>
{
cacheValue = GetProductListFromDB(); //这里一般是 sql查询数据。
CacheHelper.Add(cacheKey, cacheValue, cacheTime*2); //日期设缓存时间的2倍,用于脏读。
}); return cacheValue;
}
}

  缓存标记:记录缓存数据是否过期,如果过期会触发通知另外的线程在后台去更新实际key的缓存。

  缓存数据:它的过期时间比缓存标记的时间延长1倍,例:标记缓存时间30分钟,数据缓存设置为60分钟。 这样,当缓存标记key过期后,实际缓存还能把旧数据返回给调用端,直到另外的线程在后台更新完成后,才会返回新缓存。

  这样做后,就可以一定程度上提高系统吞吐量。

缓存穿透

  缓存穿透是指用户查询数据,在数据库没有,自然在缓存中也不会有。这样就导致用户查询的时候,在缓存中找不到,每次都要去数据库再查询一遍,然后返回空。这样请求就绕过缓存直接查数据库,这也是经常提的缓存命中率问题。

  解决的办法就是:如果查询数据库也为空,直接设置一个默认值存放到缓存,这样第二次到缓冲中获取就有值了,而不会继续访问数据库,这种办法最简单粗暴。

        public object GetProductListNew()
{
const int cacheTime = 30;
const string cacheKey = "product_list"; var cacheValue = CacheHelper.Get(cacheKey);
if (cacheValue != null)
return cacheValue; cacheValue = CacheHelper.Get(cacheKey);
if (cacheValue != null)
{
return cacheValue;
}
else
{
cacheValue = GetProductListFromDB(); //数据库查询不到,为空。 if (cacheValue == null)
{
cacheValue = string.Empty; //如果发现为空,设置个默认值,也缓存起来。
}
CacheHelper.Add(cacheKey, cacheValue, cacheTime); return cacheValue;
}
}

  把空结果,也给缓存起来,这样下次同样的请求就可以直接返回空了,即可以避免当查询的值为空时引起的缓存穿透。同时也可以单独设置个缓存区域存储空值,对要查询的key进行预先校验,然后再放行给后面的正常缓存处理逻辑。

缓存预热

  缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样避免,用户请求的时候,再去加载相关的数据。

  解决思路:

    1,直接写个缓存刷新页面,上线时手工操作下。

    2,数据量不大,可以在WEB系统启动的时候加载。

    3,定时刷新缓存,

缓存更新

 缓存的清理机制可以参考文章:https://www.cnblogs.com/ricklz/p/10742560.html

redis中的缓存-缓存雪崩和缓存穿透的更多相关文章

  1. Redis系列十:缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级

    一.缓存雪崩 缓存雪崩我们可以简单的理解为:由于原有缓存失效,新缓存未到期间(例如:我们设置缓存时采用了相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应该访问缓存的请求都去查询数据库了,而 ...

  2. [python]mysql数据缓存到redis中 取出时候编码问题

    描述: 一个web服务,原先的业务逻辑是把mysql查询的结果缓存在redis中一个小时,加快请求的响应. 现在有个问题就是根据请求的指定的编码返回对应编码的response. 首先是要修改响应的bo ...

  3. Redis中几个简单的概念:缓存穿透/击穿/雪崩,别再被吓唬了

    Redis中几个“看似”高大上的概念,经常有人提到,某些好事者喜欢死扣概念,实战没多少,嘴巴里冒出来的全是高大上的名词,个人一向鄙视概念党,呵呵! 其实这几个概念:缓存穿透/缓存击穿/缓存雪崩,有一个 ...

  4. Redis中的缓存雪崩与缓存穿透

    1.缓存雪崩 1.1什么是缓存雪崩? 如果我们的缓存挂掉了,这意味着我们的全部请求都跑去数据库了. 我们都知道Redis不可能把所有的数据都缓存起来(内存昂贵且有限),所以Redis需要对数据设置过期 ...

  5. Redis总结(五)缓存雪崩和缓存穿透等问题

    前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhong/category/771056.html .今 ...

  6. redis缓存雪崩、缓存穿透、数据库和redis数据一致性

    一.缓存雪崩 回顾一下我们为什么要用缓存(Redis):减轻数据库压力或尽可能少的访问数据库. 在前面学习我们都知道Redis不可能把所有的数据都缓存起来(内存昂贵且有限),所以Redis需要对数据设 ...

  7. Redis缓存雪崩、缓存穿透、热点Key解决方案和分析

    缓存穿透 缓存系统,按照KEY去查询VALUE,当KEY对应的VALUE一定不存在的时候并对KEY并发请求量很大的时候,就会对后端造成很大的压力. (查询一个必然不存在的数据.比如文章表,查询一个不存 ...

  8. Redis总结(五)缓存雪崩和缓存穿透等问题(转载)

    前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhong/category/771056.html .今 ...

  9. Redis缓存雪崩、缓存穿透、缓存击穿、缓存降级、缓存预热、缓存更新

    Redis缓存能够有效地加速应用的读写速度,就DB来说,Redis成绩已经很惊人了,且不说memcachedb和Tokyo Cabinet之流,就说原版的memcached,速度似乎也只能达到这个级别 ...

随机推荐

  1. CodeMixer工具,完美替代ChaosTool,iOS添加垃圾代码工具,代码混淆工具,代码生成器,史上最好用的垃圾代码添加工具,自己开发的小工具

    新工具 ProjectTool 已上线 这是一款快速写白包工具,秒级别写H5游戏壳包,可视化操作,极易使用,支持Swift.Objecive-C双语言 扣扣交流群:811715780 进入 Proje ...

  2. Swift 4.0 字典(Dictionary)学习

    定义字典常量(常量只有读操作) let dictionary1 = ["key1": 888, "key2": 999] let dictionary2: [S ...

  3. Mol Cell Proteomics. | Proteomics Analysis of Extracellular Matrix Remodeling During Zebrafish Heart Regeneration (解读人:徐宁)

    文献名:Proteomics Analysis of Extracellular Matrix Remodeling During Zebrafish Heart Regeneration(斑马鱼心脏 ...

  4. 洛谷1541 乌鬼棋 dp入门

    题目链接:https://www.luogu.com.cn/problem/P1541 给定一个序列和一个操作序列,操作序列中只有1234四个数字,表示可以前进的步数,初始在1处,操作最后一定会全部用 ...

  5. vue的使用经验

    导读 这一次的口号是,带你重新认识vue,拯救1,2个前端开发者. 从2018年从事前端职业以来,呆过大小公司,干这一行都有2年多.代码写的多了,就越来越体会新手程序员都是挖坑的.在工作过程中,用一种 ...

  6. Hook集合----SSDTHook(x86 Win7)

    最近在学习Ring0层Hook的一些知识点,很久就写完SSDTHook的代码了,但是一直没有整理成笔记,最近有时间也就整理整理. 介绍: SSDTHook 实质是利用Ntoskrnl.exe 中全局导 ...

  7. OLED的使用-4线SPI驱动

    一 .OLED屏 1.OLED屏(七针) 2.OLED电路图 3.0.96'OLED简介 该模块特点: 1.三色可选,模块有两种单色和黄蓝双色两种颜色可选,单色为纯白色和纯蓝色,双 色为黄蓝双色: 2 ...

  8. OSLab:开启保护模式

    日期:2019/5/22 关键词:操作系统:OS:保护模式:A20地址线激活:分页开启:二级页表的设置 PS:OSLAB实验课的整理. 本文主要内容是分析操作系统中一个简易的MBR. 建议先阅读:ht ...

  9. OpenCV-Python 图像阈值 | 十五

    目标 在本教程中,您将学习简单阈值,自适应阈值和Otsu阈值. 你将学习函数cv.threshold和cv.adaptiveThreshold. 简单阈值 在这里,问题直截了当.对于每个像素,应用相同 ...

  10. Rasa Stack:创建支持上下文的人工智能助理和聊天机器人教程

    相关概念 Rasa Stack 是一组开放源码机器学习工具,供开发人员创建支持上下文的人工智能助理和聊天机器人: • Core = 聊天机器人框架包含基于机器学习的对话管理 • NLU = 用于自然语 ...