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

缓存策略

比较简单的缓存策略:

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. Leetcode题目96.不同的二叉搜索树(动态规划-中等)

    题目描述: 给定一个整数 n,求以 1 ... n 为节点组成的二叉搜索树有多少种? 示例: 输入: 3 输出: 5 解释: 给定 n = 3, 一共有 5 种不同结构的二叉搜索树: 1 3 3 2 ...

  2. Leetcode题目39.组合总和(回溯+剪枝-中等)

    题目描述: 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合. candidates 中的数字可以无 ...

  3. svg简单的应用

    1.可以直接在html内写svg (1)width宽度,height高度 (2)xmlns svg的规则 <svg xmlns="http://www.w3.org/2000/svg& ...

  4. IDEA Method definition shorthands are not supported by current JavaScript version

    sentinel-dashboard前端用到了AngularJS v1.4.8,在IDEA里修改js,触发js验证时有一些js文件会出现红色波浪线. 在代码行里鼠标一上去提示信息:Method def ...

  5. selenium 学习中遇到的问题汇总

    1.使用document.getByClassName时无click事件,然后就不知道怎么办了,也不太懂前端,与开发大哥确认,div 中class实现展开和收起是通过隐藏和显示这种方式实现的,在编写时 ...

  6. C# 后台服务 web.config 中 项“ConnectionString”已添加。问题

    是自己在一网站下建了虚拟目录.原本网站为空,后来自己改了路径,有了默认配置很久后打开原本ok的虚拟目录,坑爹了.杯具了.代码:ConfigurationManager.ConnectionString ...

  7. DPDK 网络加速在 NFV 中的应用

    目录 文章目录 目录 前文列表 传统内核协议栈的数据转发性能瓶颈是什么? DPDK DPDK 基本技术 DPDK 架构 DPDK 核心组件 应用 NUMA 亲和性技术减少跨 NUMA 内存访问 应用 ...

  8. jack反序列化自定义字段绑定,报错:can only instantiate non-static inner class by using default, no-argument constructor

    package com.xxx; import com.fasterxml.jackson.annotation.JsonProperty; import lombok.Data; import lo ...

  9. Python排序之多属性排序

    1.sort函数说明: sort函数是list类的一个方法,说明如下: sort(...)L.sort(cmp=None, key=None, reverse=False) -- stable sor ...

  10. TTL 传输中过期,内部网络环路

    ping目标地址的时候,如果不是显示超时,而是很快出现TTL 传输中过期,很可能情况是内部网络出现环路 tracert一下目标地址,如果路由不断重复,说明是环路