缓存作用
当我们遇到某个页面打开很慢的时候,引入缓存之后页面内打开速度会变快。缓存之所以快是因为基于内存建立的,内存的读写速度比硬盘快很多倍,用内存代替硬盘会大大提高访问数据的速度。
另外,缓存还有两个重要的运行方式:预读取和延迟写。
预读取
预读取就是预先读取要载入的数据,原理是在系统中将硬盘的一部分加载到内存,再对外提供服务。
在一些一启动就有非常多的请求进来的系统,如果让请求直接到数据库,那会让数据库的压力非常大,可能无法响应。这时候就要通过预读取来解决。
延迟写
因为数据库的写入速度是比读取速度慢的,在写入的时候需要一系列的保证数据准确性的机制,如果想提升写入的速度,一是做分库分表,二是通过缓存来进行缓冲,然后在批量写入到磁盘。
但是分库分表对跨彪啊操作和多条件组合查询的副作用很大,所以优先考虑用缓存来解决。延迟写是预先将需要写入磁盘或者数据库的数据暂时写到内存,然后返回成功,后续再定时将内存中的数据批量写入到磁盘。
如果发生突发情况,在写入内存后返回成功,但中途关机或者断电,并没有写入到磁盘,这时候数据就丢失了。
所以,延迟写一般应用在对数据完整性没那么苛刻的场景
缓存应用
热点数据:被高频访问的数据。
静态数据:变化非常小,对数据的读操作多于写操作。
缓存类别
- 浏览器缓存
- CDN缓存
- 网关(代理)缓存
- 进程内缓存
- 进程外缓存
- 数据库缓存
缓存缺点
- 缓存雪崩
当大量的请求并发进入,但由于某些原因没有预期的缓存效果,导致所有请求全部到了数据库,造成数据库压力过大。解决方法可以利用“加锁排队”和“缓存时间增加随机值”。 - 缓存穿透
和缓存雪崩类似,但持续时间更长。因为每次“cache miss”后还是无法从数据源加载数据到缓存,导致持续产生“cache miss”。解决方法可以利用“布隆过滤器”和“缓存空对象”。 - 缓存并发
解决方法可以“先DB在缓存”,并且缓存操作delete而不是set。 - 缓存无底洞
虽然分布式缓存可以无限横向扩展,但是集群下的节点不是越多越好。缓存也是符合“边际效用递减”规律的。 - 缓存淘汰
内存总是有限的,如果数据量很大,那么根据具体的场景指定合理的淘汰策略是必不可少的,如LRU(Least Recently Used)、LFU(Least frequently used)与FIFO等。
LRU与LFU的区别