最近通过同学,突然知道服务器的缓存有很多猫腻,这里通过网上查询其他人的资料,进行记录:

缓存策略

比较简单的缓存策略:

1.失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中。

2.命中:应用程序从cache中取数据,取到后返回。

3. 更新:先把数据存到数据库中,成功后,再让缓存失效。

4. 数据库不存在:缓存中存放null值,避免继续请求数据库,设置较短的过期时间

5. 过期时间:每次缓存设置过期时间,避免意外的脏数据

说明:

1. 为什么不先删除缓存数据,后更新?

答:避免出现脏数据(主要原因);也避免后续数据库更新失败,则不需要更新缓存(次要原因)

2. 为什么更新完数据库后,设置缓存失效,而不更新缓存数据?

答:避免两个并发写操作,导致脏数据//redis为单线程操作,不存在这种情况

3. 为什么设置过期时间?

答:1、避免意外操作,导致的脏数据。2、长时间的积累,使得缓存数据过多,影响性能

4. 数据库不存在记录,为什么要缓存中存放null值?为什么要设置较短的过期时间?

答:缓存null值,是为了避免数据库穿透。

设置较短的过期时间,是为了避免新插入该记录,导致的脏数据。

可能出现的情况

缓存穿透:

指某个key,先查cache没查到,再查db也没有查到。

这种key的存在,会导致cache一直没办法命中,压力一直打在db上面。如果访问很高频,可能会压垮DB。

解决办法其实也很简单:当查询DB没查到时,往缓存中写入一个空值(缺省值),这样第2次再查,就不会打到DB上了。(springCache-redis将结果为null的数据,保存为空字符串)

缓存并发:

如果网站并发访问高,一个缓存如果失效,可能出现多个进程同时查询DB,同时设置缓存的情况,如果并发确实很大,这也可能造成DB压力过大,还有缓存频繁更新的问题。

解决:对缓存查询加锁,如果KEY不存在,就加锁,然后查DB入缓存,然后解锁;其他进程如果发现有锁就等待,然后等解锁后返回数据或者进入DB查询。(springCache-redis缓存不存在时,并发请求时,第一次请求可以进入方法,其他请求在等待,之后直接请求缓存结果,实现原理不清楚)

缓存失效:

引起这个问题的主要原因还是高并发的时候,平时我们设定一个缓存的过期时间时,可能有一些会设置1分钟啊,5分钟这些,并发很高时可能会出在某一个时间同时生成了很多的缓存,并且过期时间都一样,这个时候就可能引发一当过期时间到后,这些缓存同时失效,请求全部转发到DB,DB可能会压力过重。

解决:

其中的一个简单方案就时讲缓存失效时间分散开,比如我们可以在原有的失效时间基础上增加一个随机值,比如1-5分钟随机,这样每一个缓存的过期时间的重复率就会降低,就很难引发集体失效的事件。(springCache-redis可以通过修改RedisCacheManager的computeExpiration方法修改过期时间,但是该设置是针对CacheConfig修改的,也就是说一个Lei,最能设置一个过期时间

缓存雪崩:

所谓“缓存雪崩“,是指缓存的机器挂了,或者数据未加载到缓存中,或者缓存同一时间大面积的失效,从而导致所有请求都去查数据库,导致数据库CPU和内存负载过高,甚至宕机。

这种问题的解决策略,一般有以下2个方面:

1). 提高缓存的HA。比如缓存的主从复制。

2). 对DB的访问实行限流、降级。

3). 缓存过期时间。以redis为例,将过期设置放到1数据库,真实数据放到0数据库,key值相同,假设都为key1。

应用程序首先判断1库这条数据是否失效,当1库标记数据库数据失效或过期,在1库中设置新的过期时间。然后从数据库取数据更新0数据库中的数据。如果判断1数据库未失效,从0数据库取出数据返回。

如何解决DB和缓存一致性问题?

答:当修改了数据库后,有没有及时修改缓存。这种问题,以前有过实践,修改数据库成功,而修改缓存失败的情况,最主要就是缓存服务器挂了。而因为网络问题引起的没有及时更新,可以通过重试机制来解决。而缓存服务器挂了,请求首先自然也就无法到达,从而直接访问到数据库。那么我们在修改数据库后,无法修改缓存,这时候可以将这条数据放到数据库中,同时启动一个异步任务定时去检测缓存服务器是否连接成功,一旦连接成功则从数据库中按顺序取出修改数据,依次进行缓存最新值的修改。

缓存策略:redis缓存之springCache的更多相关文章

  1. springboot(九) Cache缓存和Redis缓存

    1. Cache缓存 1.1 缓存的概念&缓存注解 Cache 缓存接口,定义缓存操作.实现有:RedisCache.EhCacheCache.ConcurrentMapCache等 Cach ...

  2. 本地缓存,Redis缓存,数据库DB查询(结合代码分析)

    问题背景 为什么要使用缓存?本地缓存/Redis缓存/数据库查询优先级? 一.为什么要使用缓存 原因:CPU的速度远远高于磁盘IO的速度问题:很多信息存在数据库当中的,每次查询数据库就是一次IO操作所 ...

  3. Hibernate缓存策略(一级缓存和EHcache二级缓存)

    如何配置二级缓存: 第一步:导入EHcache依赖 1)Maven项目: <!--此处使用hibernate4--> <dependency> <groupId>o ...

  4. SpringBoot学习笔记(10)-----SpringBoot中使用Redis/Mongodb和缓存Ehcache缓存和redis缓存

    1. 使用Redis 在使用redis之前,首先要保证安装或有redis的服务器,接下就是引入redis依赖. pom.xml文件如下 <dependency> <groupId&g ...

  5. Spring Cache 抽象(缓存抽象) Redis 缓存

        积少成多 ----  仅以此致敬和我一样在慢慢前进的人儿 相关内容: https://blog.51cto.com/14230003/2369413?source=dra           ...

  6. Android 开源框架Universal-Image-Loader完全解析(二)--- 图片缓存策略详解

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/26810303),请尊重他人的辛勤劳动成果,谢谢! 本篇文章 ...

  7. Hibernate缓存原理与策略 Hibernate缓存原理:

    Hibernate缓存原理: 对于Hibernate这类ORM而言,缓存显的尤为重要,它是持久层性能提升的关键.简单来讲Hibernate就是对JDBC进行封装,以实现内部状态的管理,OR关系的映射等 ...

  8. 安卓开发笔记——关于图片的三级缓存策略(内存LruCache+磁盘DiskLruCache+网络Volley)

    在开发安卓应用中避免不了要使用到网络图片,获取网络图片很简单,但是需要付出一定的代价——流量.对于少数的图片而言问题不大,但如果手机应用中包含大量的图片,这势必会耗费用户的一定流量,如果我们不加以处理 ...

  9. Web缓存基础:术语、HTTP报头和缓存策略

    简介 对于您的站点的访问者来说,智能化的内容缓存是提高用户体验最有效的方式之一.缓存,或者对之前的请求的临时存储,是HTTP协议实现中最核心的内容分发策略之一.分发路径中的组件均可以缓存内容来加速后续 ...

  10. Android 开源框架Universal-Image-Loader全然解析(二)--- 图片缓存策略具体解释

    转载请注明本文出自xiaanming的博客(http://blog.csdn.net/xiaanming/article/details/26810303),请尊重他人的辛勤劳动成果,谢谢! 本篇文章 ...

随机推荐

  1. Linux dirname 和 basename

    [参考文章]:Linux shell - `dirname $0` 定位到运行脚本的相对位置 [参考文章]:Linux命令之basename使用 1. dirname $0 获取脚本文件所在的目录信息 ...

  2. AngularJS复习小结

    开发移动端App,首先得在头部 <meta name="viewport" content="width=device-width, initial-scale=1 ...

  3. Java-JPDA 概述

    JPDA:Java 平台调试架构(Java Platform Debugger Architecture) 它是 Java 虚拟机为调试和监控虚拟机专门提供的一套接口. 一.JPDA https:// ...

  4. Android省电和提高效率

    一.Android省电开发之性能优化 电量优化 Android应用开发中的网络.定位.传感器等都是比较耗电的特性,我们应该正确使用API来有效降低应用的耗电量. 1.BroadcastReceiver ...

  5. 【深入nodejs开发】一、将node项目结合nginx部署到Centos7服务器

    一.安装nginx服务器环境 1.使用ssh工具连接服务器 2.安装宝塔面板,方便服务器管理 yum install -y wget && wget -O install.sh htt ...

  6. 成功解决Developer Express和Janus WinForms Controls中控件的冲突

    最新在做一套GIS系统的框架,其中用到了Janus WinForms Controls和Developer Express这两个插件. 我用DE的xtraTabbedMdiManager组件来管理我的 ...

  7. 消息队列 RabbitMQ 入门介绍

    来源:http://ityen.com/archives/578 一.什么是RabbitMQ? RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系 ...

  8. PHP yii2.0框架利用mpdf导出pdf

    安装: composer require mpdf/mpdf 使用: use Mpdf\Mpdf;//(php7以前) //获取页面内容 $res = $this->controller-> ...

  9. hostname -i 出现0.0.0.0解决

    [root@hostnametest4 ~]# hostname -i 0.0.0.0 原因:是因为四个节点中其中一个节点没有配置hosts解析,必须每个节点写全这四个ip,只要掉一个ip就会出现0. ...

  10. python3速查参考- python基础 3 -> -> while循环实例 + Continue && break的应用 + 列表的初步学习

    while语句的应用 实例如下: """ 述求:用户登录系统,最多只能登录三次 第三次失败后,程序终止 """ user_table = { ...