缓存初窥
缓存是什么
我们先看下引用的两条解释:
缓存(cache),原始意义是指访问速度比一般随机存取存储器(RAM)快的一种高速存储器,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。
在计算中,缓存是一个高速数据存储层,其中存储了数据子集,且通常是短暂性存储,这样日后再次请求该数据时,速度要比访问数据的主存储位置快。 通过缓存,您可以高效地重用之前检索或计算的数据。
简单概括起来讲,缓存就是一块访问速度很快,但是空间有限的存储区域,里面通常存储着一些访问频率很高的数据的副本,通过访问缓存中数据从而显著的提高系统性能。
讲个实际的例子,大家就更好理解了,比如:淘宝双11要发100w张满100-20的券,而且每次发券的时候都需要先获取这张券的信息,普通的从DB读取耗时3ms,如果从缓存中读取只需0.1ms,那么我们就可以把这张券的信息存储到缓存,那么每次读取的耗时就从3ms->0.1ms,访问速度提升了30倍。这对于一个系统并发能力的提升,是非常明显的。
可以看到,缓存的最基本原理,就是利用空间换时间的思路,把常用数据放在缓存,通过:访问DB时间 - 访问缓存时间 > 0,从而提升系统性能。
缓存的特性
前面说到,既然缓存访问速度这么快,那么全部数据都丢缓存不就解决问题了吗?NO,缓存就是一个高速的缓冲区,通常是非持久化的,同样的造价也很高,所以不可能所有数据都存在缓存里面,空间是有限制的。
由于缓存受到空间的限制,那么如何利用好这个空间有限的高速缓冲区域,就是我们一直在探索的课题。
缓存命中率
首先,必须是常用的、热点的数据才放缓存,那么怎么考量一个缓存里面的数据是否合理?缓存命中率
缓存命中率 = 正确返回结果的请求次数 / 总的请求缓存次数:这个公式就是说,每次请求缓存,能否能从缓存里面拿到想要的数据,拿到说明缓存中的数据是合理的,这个命中率越高越好。
如果请求没有正常返回数据,那么就要引出另外一个名词了缓存穿透:穿过缓存,直接到DB中去取数据,这个时候缓存是不生效的,这个穿透率越低越好。如果大量的缓存穿透打到DB,那么就很容易造成DB的性能瓶颈,从而影响到其他业务的DB请求,进而引起系统的雪崩。
那么如何提高缓存命中率,降低缓存穿透呢?
- 合理的场景
- 业务场景是高并发的,并且对性能有极高的要求,那么对于一些关键节点,我们可以通过缓存来提速。
- 通常缓存适用于一些大量读操作的静态数据,如果一个数据一直变化,那么是不适合放到缓存的。
- 合理的缓存设计
- 缓存key、value的设计,通常要保持原子性,每个value是个单独的对象,防止汰换时,相互影响。
- 缓存预热
- 通常机器重启缓存就会丢失,那么重新部署之后,我们就可以加上预热程序,自动加载数据到缓存。从而防止冷机器接到大量请求,从而缓存穿透的问题出现。
缓存汰换策略
因为缓存的空间有限,如果缓存空间的满了的时候,我们应该如何抉择哪些数据应该移出缓存呢?
常见的策略有如下:
- FIFO
- 先进先出策略,最先进入缓存的数据在缓存空间不够的情况下会被优先被清除掉,以腾出新的空间接受新的数据。策略算法主要比较缓存元素的创建时间。
- LFU
- 最少使用策略,无论是否过期,根据元素的被使用次数判断,清除使用次数较少的元素释放空间。策略算法主要比较元素的hitCount(命中次数)。
- LRU
- 最近最少使用策略,无论是否过期,根据元素最后一次被使用的时间戳,清除最远使用时间戳的元素释放空间。策略算法主要比较元素最近一次被get使用时间。
我们也可以根据业务场景,做一些定制化的策略:
- 根据业务数据过期时间自动失效
- 比如某张券的有效时间是固定的,那么超过有效期,缓存就可以清理了。
- 根据业务操作清理缓存
- 比如用户删了某张订单之后,订单相关联的一些缓存信息就可以主动的清理。
这篇的内容就先写到这里了,下篇讲具体讲一下缓存的实践。