如何使用系统中的多级缓存设计

缓存的本质

缓存的本质是解决数据两端的处理速度差异问题,从而尽量避免处理速度快的等着处理速度慢的。

例如,我们都知道CPU的处理速度比内存的存储速度快,这种速度差异巨大,为了避免CPU在从内存读取数据时等待空转,因此才有CPU内部的三级缓存L1, L2, L3,从而避免内存成为CPU的性能瓶颈。

另外,本文所阐述的缓存只针对后台服务,针对web前端的浏览器级别,CDN,或者手机端本地缓存不做过多叙述。

通常服务中的几层缓存

在Web服务中,数据大多数永久的存储在mysql等关系型数据库中,客户端通过web或者移动端,通过网络请求Web后台服务器,后台服务器请求数据库,并通过一定程序逻辑将数据通过网络返回给客户终端。这一系列操作,数据的流向大致是如下图这样:

image-20220314175232702

那么,在这个过程中,那个过程最缓慢呢?即哪个过程最可能是系统瓶颈呢?

答案就是:数据库接受到数据请求后查询数据,并返回数据的过程。

因此,我们需要针对这一系统瓶颈提出解决方案,那便是缓存。

Redis/memcache

最常见的,也是使用最普遍的缓存中间件就是Redis、memcache。以Redis为例,通过key-value的存储结构,其value可以存储字符串,列表,集合等内容。例如,下图是我们使用redis管理工具Another Redis DeskTop Manager查看数据库的情况:

image-20220314180501402

image-20220314180509279

Redis通常是部署在一个单独的内存较大的服务器上,通过在内存中存储数据从而加速数据的查找与读取。

而且,目前Redis与Memcache已支持做分布式部署,或者部署为缓存集群,功能强大。

Caffine/Guava Cache

Caffine/Guava Cache是本地内存缓存中间件,换句话说,他们与应用程序是紧密结合的。其通过将本地程序的部分数据放在内存中,从而减少外部数据请求。

我们画一幅图来理解上述的两层缓存:

image-20220314181331621

一个数据请求流程,大致是先访问Caffine存储,若为命中,则访问Redis缓存,仍然未命中,则访问数据库。