什么叫缓存?
广义的缓存就是在第一次加载某些可能会复用数据的时候,在加载数据的同时,将数据放到一个指定的地点做保存。再下次加载的时候,从这个指定地点去取数据。
这里加一层缓存是有一个前提的,就是从这个地方取数据,比从数据源取数据要快的多。
这里可以类比计算机物理硬件或者JMM内存模型索罗蓝:由JMM看线程不安全的原因zhuanlan.zhihu.com
java狭义一些的缓存,主要是指三大类虚拟机缓存(ehcache,JBoss Cache)
分布式缓存(redis,memcache)
数据库缓存
正常来说,速度由上到下依次减慢
为什么要用缓存?
作为一个高并发项目来说,一秒钟服务器收到的请求是非常多的,而如果这每一次的请求都直接请求数据库服务器,那么数据库的压力将会变得非常大。
拿一个双十一系统举例,传统数据库架构,能同时承受的高并发数量是有限的,而如何再不改动原数据库的情况下,降低并发压力呢,这里大概有3种方案数据库集群
消息队列(削峰)
数据缓存
这三种方式对应的设计理念是完全不同的
数据库集群是从提高数据库承受能力的角度去做提升
消息队列是用削峰的方式去降低同一时刻的并发压力这里多解释一句方便理解,他并不降低数据库服务器需要承受的并发数量,而是将这个并发分布到后续的时间里去处理,所以叫削峰
数据缓存则是从程序上降低请求访问数据库的量
分布式缓存和虚拟机缓存
两者的区别(拿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
缓存会出现的一些问题
缓存穿透:缓存中没有该数据,数据库也没有该数据,但是请求过来的时候,还是要用数据库语句进行查询,这就是缓存击穿。攻击者可能对这一个不存在的数据反复的进行查询请求,对数据库造成极大压力。
解决方式:对没有的值也加入缓存,比如key-null,设置过期时间,避免这一段时间内重复对该值进行反复请求;接口层增加鉴定,不符合要求的直接返回,不进入数据库查询队列。
缓存击穿:缓存中没有该数据,数据库有该数据,但是同时来了一堆请求查询到缓存没有数据,会在一瞬间加重数据库压力
解决方式:添加互斥锁(取数据串行化);设置热点数据永不过期;
缓存雪崩:大量缓存中的key在同一时间过期
解决方式:设置热点数据永不过期,缓存预热