文档章节

怎样使用主流缓存更新策略来减少性能消耗?

Java干货分享
 Java干货分享
发布于 09/25 17:02
字数 2120
阅读 6
收藏 1

怎样使用主流缓存更新策略来减少性能消耗?

 

在互联网项目开发中,缓存的应用是非常普遍了,缓存可以帮助页面提高加载速度,减少服务器或数据源的负载。

一、为什么需要缓存?

一般在项目中,最消耗性能的地方就是后端服务的数据库了。而数据库的读写频率常常都是不均匀分布的,大多情况是读多写少,并且读操作(select)还会有一些复杂的判断条件,比如like、group、join等等,这些语法是非常消耗性能的,所以会出现很多的慢查询,因此数据库很容易在读操作的环节遇到瓶颈。

那么通过在数据库前面,前置一个缓存服务,就可以有效的吸收不均匀的请求,抵挡流量波峰。

另外,如果应用与数据源不在同一个服务器,中间还会有很多的网络消耗,也会对应用的响应速度有很大影响,如果当前应用对数据实时性的要求不那么强的话,在应用侧加上缓存就能很快速地提升效率。

二、使用缓存会遇到哪些问题?

虽然缓存可以提高整体性能,但是它也可能会带来别的问题。

例如使用缓存之后,就相当于把数据存放了2份,一份是在数据库中,另一份存放在缓存中。当有新的数据要写入或者旧数据需要更新的时候,如果我们只更新了其中一份数据源,那两边的数据就不一致了。所以这里就存在一个缓存数据与数据库数据如何进行有效且快速的同步才可以保证数据最终一致性的问题。

另外,加上缓存服务其实也引入了系统架构的复杂度,因为还需要额外的关注缓存自身带来的下列问题:

1、缓存的过期时间问题

设计缓存的过期时间非常需要有技巧,且必须与业务实际情况相结合。因为如果设计的过期时间太短了,那会导致缓存效果不佳,而且还会造成频繁的从数据库中往缓存里写数据;如果缓存设计的过期时间太长了,又会导致内存的浪费。

2、缓存的命中率问题

这也是设计缓存中需要存放哪些数据的很重要一点。如果设计的不好,可能会导致缓存命中率过低,失去缓存效果。一般对于热点数据而言,要保证命中率达到70%以上效果最佳。

3、缓存的穿透/雪崩问题

穿透/雪崩问题是指如果缓存服务一旦宕机或全部丢失,那么有可能一瞬间所有的流量都直接打到了后端数据库上,可能会造成连锁反应,瞬间的请求高峰极有可能导致数据库无法承载。

三、缓存的更新策略具体有哪些?

典型的缓存模式,一般有如下几种:

  • Cache Aside;
  • Read/Write Through;
  • Write Behind。

每种模式都有不同的特点,适用于不同的项目场景,下面来依次看看:

1、Cache Aside模式

 

怎样使用主流缓存更新策略来减少性能消耗?

 

 

这是大家经常用到的一种策略模式。这种模式主要流程如下:

 

  • 应用在查询数据的时候,先从缓存Cache中读取数据,如果缓存中没有,则再从数据库中读取数据,得到数据库的数据之后,将这个数据也放到缓存Cache中;
  • 如果应用要更新某个数据,也是先去更新数据库中的数据,更新完成之后,则通过指令让缓存Cache中的数据失效。

这里为什么不让更新操作在写完数据库之后,紧接着去把缓存Cache中的数据也修改了呢?

主要是因为这样做的话,就有2个写操作的事件了,担心在并发的情况下会导致脏数据,举个例子:

假如同时有2个请求(请求A和请求B)并发的执行。请求A是要去读数据,请求B是要去更新数据。初始状态缓存中是没有数据的,当请求A读到数据之后,准备往回写的时候,此刻,请求B正好要更新数据,更新完了数据库之后,又去把缓存更新了,那请求A再往缓存中写的就是旧数据了,属于脏数据。

那么Cache Aside模式就没有脏数据问题了吗?不是的,在极端情况下也可能会产生脏数据,比如:

假如同时有2个请求(请求A和请求B)并发的执行。请求A是要去读数据,请求B是要去写数据。假如初始状态缓存中没有这个数据,那请求A发现缓存中没有数据,就会去数据库中读数据,读到了数据准备写回缓存中,就在这个时候,请求B是要去写数据的,请求B在写完数据库的数据之后,又去设置了缓存失效。这个时候,请求A由于在数据库中读到了之前的旧数据,开始往缓存中写数据了,此时写进入的就也是旧数据。那么最终就会导致,缓存中的数据与数据库的数据不一致,造成了脏数据。

不过这种概率比上面一种概率要小很多。所以整体而言Cache Aside模式还是一种比较简单实用的方式。

2、Read/Write Through模式

 

怎样使用主流缓存更新策略来减少性能消耗?

 

 

这个模式其实就是将缓存服务作为主要的存储,应用的所有读写请求都是直接与缓存服务打交道,而不管最后端的数据库了,数据库的数据由缓存服务来维护和更新。不过缓存中数据变更的时候是同步去更新数据库的,在应用的眼中只有缓存服务。

流程就相当简单了:

  • 应用要读数据和更新数据都直接访问缓存服务;
  • 缓存服务同步的将数据更新到数据库。

这个模式出现脏数据的概率就比较低,但是就强依赖缓存了,对缓存服务的稳定性有较大要求。另外,增加新缓存节点时还会有初始状态空数据问题。

3、Write Behind模式

这个模式就是Read/Write Through模式的一个变种。区别就是Read/Write Through模式的缓存写数据库的时候是同步的,而Write Behind模式的缓存操作数据库是异步的。

流程如下:

  • 应用要读数据和更新数据都直接访问缓存服务;
  • 缓存服务异步的将数据更新到数据库(通过异步任务)。

这个模式的特点就是速度很快,效率会非常高,但是数据的一致性比较差,还可能会有数据丢失的情况,实现逻辑也较为复杂。

以上就是目前三种主流的缓存更新策略,另外还有Refrsh-Ahead模式等由于使用的不是很常见就不详细介绍了。

顺便在此给大家推荐一个Java架构方面的交流学习群:698581634,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系,主要针对Java开发人员提升自己,突破瓶颈,相信你来学习,会有提升和收获。在这个群里会有你需要的内容  朋友们请抓紧时间加入进来吧。

© 著作权归作者所有

共有 人打赏支持
Java干货分享
粉丝 24
博文 28
码字总数 100963
作品 0
长沙
怎样使用主流缓存更新策略来减少性能消耗?

在互联网项目开发中,缓存的应用是非常普遍了,缓存可以帮助页面提高加载速度,减少服务器或数据源的负载。 一般在项目中,最消耗性能的地方就是后端服务的数据库了。而数据库的读写频率常常...

IVAN-jsjwk
09/25
0
0
使用Google Page Speed优化Web前端性能

安装步骤:http://jingyan.baidu.com/article/597035523c54cd8fc00740ed.html 安装好以后,打开Firebug,可以看到新增的标签页:Page Speed: 使用Page Speed 其中,Page Speed标签页包括两个...

星辰~
2012/08/10
0
4
大型站点的前期规划

从低成本、高性能和高扩张性的角度来说说站点的规划:HTML静态化、图片server分离、数据库集群和库表散列、缓存…… 一个小型的站点。比方个人站点,能够使用最简单的html静态页面就实现了,...

技术mix呢
2017/11/08
0
0
高并发网站之解决策略

系统在正式上线后必将会面对大量用户访问,面对各种层级的高并发请求,因此我们会采用高性能的服务器、高性能的数据库、高效率的编程语言、高性能的Web容器等。但是这几个方面,还无法从根本...

lindianlide
2014/09/05
0
0
大型网站设计注意事项

1、HTML静态化 其实大家都知道,效率最高、消耗最小的就是纯静态化的html页面,所以我们尽可能使我们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。但是对于大量...

dongzhumao
2010/11/04
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot 入门 - 进阶篇(4)- REST访问(RestTemplate)

经常需要发送一个GET/POST请求到其他系统(REST API),通过JDK自带的HttpURLConnection、Apache HttpClient、Netty 4、OkHTTP 2/3都可以实现。 HttpClient的使用:http://rensanning.iteye.c...

onedotdot
刚刚
0
0
Wi-Fi也有版本号了!

据Solidot消息,行业组织 Wi-Fi 联盟宣布当前的版本 Wi-Fi 802.11ac 重命名为 Wi-Fi 5,而下一个版本 802.11ax 重命名为 Wi-Fi 6,之前的版本 802.11n 改名为 Wi-Fi 4。 Wi-Fi 标准之前使用单...

linux-tao
2分钟前
0
0
项目经验不丰富、技术不突出的程序员怎么打动面试官?

前言 相信不少的程序员都有过类似的困惑:如果我没有大型的项目经历,也不能靠技术征服面试官,那我要怎么才能给面试官留下一个好印象呢? 按照本人的面试经验来说,面试主要看几点:项目经验...

Mamba1
12分钟前
0
0
MyBatis 源码分析----MyBatis 整体架构概要说明

MyBatis整体架构 MyBatis的整体架构分为三层1:基础支持层,2:核心处理层,3:接口层 1:基础支持层: 1-1反射模块: 该模块对Java 原生的反射进行了良好的封装,提供了更加简洁易用的API ,...

西瓜1994
18分钟前
1
0
如何让 J2Cache 在多种编程语言环境中使用

现在的系统是越来越复杂了,不仅仅是功能复杂,系统结构也非常复杂,而且经常在一个系统里包含几种不同语言编写的子系统。例如用 JavaScript 做前端开发、用 Java/PHP 等等做后端,C/C++/Go ...

红薯
19分钟前
29
1

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部