![5c5b6110acdce53191a4d1e5ec2017f2.png](https://i-blog.csdnimg.cn/blog_migrate/05ef7ece224f8a4a12052a798ad4c6ca.jpeg)
什么叫缓存?
广义的缓存就是在第一次加载某些可能会复用数据的时候,在加载数据的同时,将数据放到一个指定的地点做保存。再下次加载的时候,从这个指定地点去取数据。
这里加一层缓存是有一个前提的,就是从这个地方取数据,比从数据源取数据要快的多。
这里可以类比计算机物理硬件或者JMM内存模型
索罗蓝:由JMM看线程不安全的原因zhuanlan.zhihu.com![46534edd1dda022e9143c55249f3b34d.png](https://i-blog.csdnimg.cn/blog_migrate/0da934e9970e471a1624aea47a797ab8.jpeg)
java狭义一些的缓存,主要是指三大类
- 虚拟机缓存(ehcache,JBoss Cache)
- 分布式缓存(redis,memcache)
- 数据库缓存
正常来说,速度由上到下依次减慢
为什么要用缓存?
作为一个高并发项目来说,一秒钟服务器收到的请求是非常多的,而如果这每一次的请求都直接请求数据库服务器,那么数据库的压力将会变得非常大。
拿一个双十一系统举例,传统数据库架构,能同时承受的高并发数量是有限的,而如何再不改动原数据库的情况下,降低并发压力呢,这里大概有3种方案
- 数据库集群
- 消息队列(削峰)
- 数据缓存
这三种方式对应的设计理念是完全不同的
数据库集群是从提高数据库承受能力的角度去做提升
消息队列是用削峰的方式去降低同一时刻的并发压力
这里多解释一句方便理解,他并不降低数据库服务器需要承受的并发数量,而是将这个并发分布到后续的时间里去处理,所以叫削峰
![0072cc24693d4ad22d1a304a7a109212.png](https://i-blog.csdnimg.cn/blog_migrate/a462622b0daaf31c9a0699eeb1f8cbdf.jpeg)
数据缓存则是从程序上降低请求访问数据库的量
分布式缓存和虚拟机缓存
两者的区别(拿ehcache和redis举例)
1.应用场景的不同,虚拟机用在单体应用,分布式缓存不仅可以用在单体应用,也可以用于分布式缓存,自带分布式锁保证数据一致性。
2.数据储存位置不同,ehcache储存在虚拟机堆内存中,redis储存在内存中(数据库储存在硬盘中)从硬件特性上也可以很好看出他们的速度差别。
当然他们都有一些储存策略,通过设置储存策略把内存数据写入硬盘持久化。
3.造成的影响不同,ehcache储存在堆内存会在一定程度上影响系统性能,而redis是可以搭建redis服务器的,让缓存系统独立出来。
缓存的淘汰策略
当缓存的数据的大小超过设置的指定大小,或者缓存对象的数量超过了设置的指定数量,那么缓存就会对一些数据进行删除,删除的策略主要分三种
LRU(Least Recently Used)最近最久未使用的
LFU(Least Frequently Used)最近最少使用算法
FIFO(First in First out)先进先出
缓存的淘汰策略blog.csdn.net缓存的更新策略
Cache Aside (最常用,很好解决缓存一致性问题的方式)
Read/Write Through
Write Behind
缓存服务的更新策略有哪些?www.jianshu.com![2e836284f2772c731f9750fb4d975cbf.png](https://i-blog.csdnimg.cn/blog_migrate/8031301823b33b8359fcc6efd946ddcf.jpeg)
缓存会出现的一些问题
缓存穿透:缓存中没有该数据,数据库也没有该数据,但是请求过来的时候,还是要用数据库语句进行查询,这就是缓存击穿。攻击者可能对这一个不存在的数据反复的进行查询请求,对数据库造成极大压力。
解决方式:对没有的值也加入缓存,比如key-null,设置过期时间,避免这一段时间内重复对该值进行反复请求;接口层增加鉴定,不符合要求的直接返回,不进入数据库查询队列。
缓存击穿:缓存中没有该数据,数据库有该数据,但是同时来了一堆请求查询到缓存没有数据,会在一瞬间加重数据库压力
解决方式:添加互斥锁(取数据串行化);设置热点数据永不过期;
缓存雪崩:大量缓存中的key在同一时间过期
解决方式:设置热点数据永不过期,缓存预热