什么都缓存只会害了你

现在对于缓存的误解:

  1. 不管是什么性能问题,通用解决方案都是缓存 + 多线程
  2. redis并不是唯一的缓存方案
  3. 缓存并不是提高性能的唯一方案,甚至不是最优方案


你没有尝试其他方案、或者对业务不是特别了解,不要动辄上缓存。




缓存的本质


在机械硬盘时代,系统一般装在C盘。

C盘的读写速度通常比其他盘快,‌这是因为硬盘分区的创建顺序和物理特性决定的。‌在早期的机械硬盘时代,‌硬盘分区的创建是从外圈向内圈进行的,‌由于角速度固定,‌外圈的线速度比内圈大,‌因此外圈的分区(‌如C盘)‌读写速度相对较快。‌此外,‌由于C盘作为系统盘,‌通常位于硬盘的最外圈,‌这使得C盘的读写速度在所有分区中是最快的。‌因此,‌将软件安装到C盘可以加快软件的运行速度,‌因为软件读取速度更快,‌响应也更迅速。‌


总结:


  1. 内圈的读写速度可能比外圈慢2-3倍
  2. 我们分区的目的之一,就是将最快的外圈分配给系统使用。提高整个系统的表现
  3. 大量的软件会把配置文件放到C盘中


这个情况就描述了:

  1. 系统有多种资源ABC,都能解决一个问题
  2. 而我们应该尽量使用性能最高的资源A,当A无法解决的时候才会使用次一级的B



了解了这个逻辑再聊第二个场景:

电脑上有三级缓存。

缓存是指可以进行高速数据交换的存储器,它先于内存与CPU交换数据,因此速率很快。L1 Cache(一级缓存)是CPU第一层高速缓存。内置的L1高速缓存的容量和结构对CPU的性能影响较大,不过高速缓冲存储器均由静态RAM组成,结构较复杂,在CPU管芯面积不能太大的情况下,L1级高速缓存的容量不可能做得太大。一般L1缓存的容量通常在32—256KB。L2 Cache(二级缓存)是CPU的第二层高速缓存,分内部和外部两种芯片。内部的芯片二级缓存运行速率与主频相同,而外部的二级缓存则只有主频的一半。L2高速缓存容量也会影响CPU的性能,原则是越大越好,普通台式机CPU的L2缓存一般为128KB到2MB或者更高,笔记本、服务器和工作站上用CPU的L2高速缓存最高可达1MB-3MB。由于高速缓存的速度越高价格也越贵,故有的计算机系统中设置了两级或多级高速缓存。紧靠CPU的一级高速缓存的速度最高,而容量最小,二级高速缓存的容量稍大,速度也稍低 [1]。


总结:

  1. 一级缓存速度最快,但是由于架构的原因做不大
  2. 二级缓存比一级缓存大,但是慢一半,但是仍然很快
  3. 三级缓存比二级缓存大,但是更慢,但是仍然很快
  4. 当查询的时候,先查询一级缓存,然后再查询二级缓存,再查询三级缓存


对于缓存,有一个基本的逻辑:

  1. 为什么要用缓存,因为有性能的瓶颈,需要更快的响应速度
  2. 有多个不同的介质:有高速但是容量有限的高速介质,有便宜并且大量的低速介质
  3. 缓存就是在多种不同速度的介质存储多个副本。
  4. 当查询的时候优先查询高速介质,查询不到再去查询低速介质,从而提高整个系统的表现


对于网络下载,硬盘可以做网络下载的缓存。

对手硬盘来说,内存可以做硬盘的缓存。


redis使用的是内存,而传统数据库使用的介质是硬盘。

内存的性能高于硬盘

那么,可以用redis做传统数据库的缓存。


缓存跳过计算过程

缓存可以直接跳过计算过程,直接查询到结果。


比如:

  1. 我需要统计学生的数量,但是全表扫描太慢,我可以直接缓存一个结果
  2. 我需要进行一个复杂计算,我可以直接查询之前是否进行过计算,然后从缓存里面拿到结果


这个就不需要解释了。


缓存的问题

妥协

缓存是一个妥协:

  1. 数据库性能差
  2. 用了缓存承担了80%的业务


一旦业务穿透了缓存(缓存雪崩 缓存穿透 缓存击穿),那么直接打挂数据库。

这种方式很优雅嘛?


如果有其他的解决方案,我个人不是很建议直接缓存。

  1. 大厂有运维人员,而小厂你不能24小时盯着系统
  2. 缓存的复杂性会导致各种各样的问题,比如数据一致性
  3. 隐患是存在的,“一旦穿透缓存,数据库就挂”



复杂度

和其他方案相比,缓存并不是一层,而是多层。

  1. 布隆过滤器
  2. 缓存
  3. 数据库


缓存的解决方案,基本上都是三层。而且要写入多个数据源。

作为一个解决方案,缓存是“很重”的一个解决方案。

  1. 有几层,就需要写几次
  2. 当数据变更的时候,缓存变更和替换难度相对来说比较大
  3. 缓存一致和缓存失效是老大难问题


为什么不可行

直接高速介质?

了解了缓存的本质以后:

  1. 我确认这个数据是高频的
  2. 这个数据数据量还很小
  3. 为什么不全量存到高速介质?而不是缓存?


公司穷

举个例子来描述缓存的局限性:

  1. 我有个老旧的系统,他内存使用率已经达到了85%,内存天天爆红
  2. 然后我使用了redis对系统进行了优化


这怎么优化?优化不了一点。

  1. 缓存的本质就是“热点数据存在高速介质,提高整个系统的表现”
  2. 你公司没有提供有效的高速介质,高速介质已经满了


总结一句话:老板,加钱买内存。内存是高速介质,然后我可以将“热点数据”存到内存中,提高整个系统的表现。加ssd也可以啊——但是我不用改代码。


无热点查询

缓存生效的是热点数据。

  1. 有10%的数据属于高频数据
  2. 有90%的数据低频


就系统而言,缓存的提升的几个核心要素就是:“缓存的命中率”和“缓存的大小、“高速介质和低速介质的速度差异”。比较核心的是“缓存的命中率”


而命中率不取决于“技术”,而取决于“业务”。

  1. 哪些业务是用户的高频查询词汇
  2. 哪些内容是高性能消耗的内容,值得去缓存


不确认业务场景,强行进行缓存,意义不大。


缓存不等于内存 + redis

缓存可以直接跳过计算过程,直接查询到结果。


那么:比如数据库进行count(*)比较慢,所以我直接缓存结果。

能不能直接存到数据库里呢?

  1. 缓存并不是非要缓存在redis
  2. 他存到数据库也是完全没问题的



是否有其他的方案?

数据库查询慢,是否可以买高速SSD?

是否可以不用select *,减少内存的消耗

是否可以变成分布式存储?

是否可以替换为其他解决方案呢?

是否有那么高的时效性?

是否可以进行最终一致?

用户量是否有那么高?

缓存的命中率是否高?


作为解决方案而言:

  1. 缓存的实现难度是比较大的
  2. 缓存有缓存一致性、缓存雪崩、缓存穿透等
  3. 会引入一些复杂的中间件


你没有尝试其他方案、或者对业务不是特别了解,不要动辄上缓存。






















0个评论
点击登录,快来和大家讨论吧~
表情
图片
暂无评论
下载 APP