缓存(一): 概要
前言
本文章主要是讲述了缓存的一些相关知识,可能有很多人都很熟悉这个是什么。我查看了一些资料,将那些讲述的汇集在一起慢慢整理成自己的知识体系。这个是第一篇文章。希望有所帮助吧。接下来我会按照几个问题去讲述。
- 缓存什么?
- 哪些场景下适合做缓存?
- 怎么评估加了缓存使得了性能提高了提升?
缓存是什么
缓存最早出现在 1967 年的一篇电子工程期刊论文中。 wiki 百科中的原理部分有这么段讲解:
当CPU处理数据时,它会先到Cache中去寻找,如果数据因之前的操作已经读取而被暂存其中,就不需要再从随机存取存储器(Main memory)中读取数据——由于CPU的运行速度一般比主内存的读取速度快,主存储器周期(访问主存储器所需要的时间)为数个时钟周期。因此若要访问主内存的话,就必须等待数个CPU周期从而造成浪费。
引入缓存的目的就是为了让数据访问的速度适应 CPU 的处理速度。 那么按照这个定义,拓展一下,可以这么认为为了高速设备和低速设备之间的处理速度偏差, 或者减少复杂耗时带来的性能问题。比如访问 html 时候,浏览器会缓存页面 cookie 等信息。与缓存相类似的有个缓冲区,虽然名字差不多,但缓冲区是会被消费掉的,可以理解成弥补高速设备和低速设备通信时的速度差,这个可以引申成消息队列。这里就不展开了。
哪些场景下适合做缓存呢?
为了解决这个问题,我们首先了解引入缓存的目的是什么?是为了弥补高速设备和低速设备之间的速度,从而提高系统性能。而我们在日常开发中,我们经常使用的四个动作,增删改查。增删改来说一般瓶颈都不会太大,那么查的速度来看,影响是比较大的。因此,我们可以将读写比为 N:1 的数据作为缓存。N 可以是认为 > 1 的数据,所以它首先是使用频率比较高的数据, 使用不高引不引用关系都不是很大。那么在使用频率高的情况下,哪些数据适合呢?比如一些静态数据, html, css 等这些文件; 或者如国家的城市行政区,公司的组织架构等准静态数据。还有一些比如: 计算斐波拉契数据时需要记录的中间数据,或者变量副本,配置中心的本地副本等一些中间状态数据。在分布式系统中,引入缓存必然会有数据不一致的情况,所以强一致性的数据不太适合做缓存。如果非要做,则必须使用分布式锁,或者分布式事务来保证数据的原子性, 否则会引发数据不一致问题,导致比较严重的业务故障。而非强一致性的数据,就只需要保证最终一致性即可。
怎么评估加了缓存使得了性能提高了提升?
加入了缓存,我们又怎么去评估缓存使性能得到了提升呢?一般来讲命中率达到了 80% 即可,当然了有些特殊场景需要 95% 以上才能算提高。这个需要根据自己的业务衡量。当然了, 评估缓存性能通常还是会使用平均内存访问时间(Average Memory Access Time, AMAT) 这一指标。
AMAT = (1 − MR) * T$ + MR * (T$ + MP) = T$ + MR * MP
其中三项解释为:
- T$ : 缓存访问时间
- MP (缓存失效损失,Miss Penatly),缓存失效后,系统访问缓存的时间与访问原始请求的时间之和。
- MR (Miss Rate), 缓存失效率
由这个计算公式可以看出,优化缓存可以从三个方面入手:
- 减少命中缓存的时间
- 降低缓存失效率
- 减轻失效的代价
当我们选择缓存时,容量和使用的峰值也是需要考虑的因素。不同的缓存的访问速度也不尽相同,比如 内存级的一般 <μs (微秒)
, 而分布式缓存,如 Redis 这种一般 <ms(毫秒)
级别,原始数据库的 >ms(毫秒)
级别,不同的场景需要不同的需要选择合适的缓存。
总结
总结一下全文, 该文章从三个问题如果大概的讲述了缓存的基本概念和性能评估的方法。适合做缓存的数据一般为读写比较大的,访问评率高的,且一致性要求没有那么高的数据。