前言
当应用系统有大量用户进行访问时,导致系统的TPS极速上升,查询数据直接打到了数据库
达到了系统的性能瓶颈,接口的响应会变慢,用户体验变得非常差
那么从技术架构的角度思考可以使用缓存技术对系统进行优化
-
缓存是成本最低并且 简单有效的一种技术架构方案 -
缓存可以 减轻系统的负载同时 提高数据的传播效率
缓存及其应用场景
缓存介绍
在计算机中,缓存是一个高速数据存储层,其中存储了数据子集且通常是短暂性存储
这样日后再次请求此数据时要比访问数据的主存储位置快
通过缓存可以高效地重用之前检索或计算的数据
缓存分为以下三种
硬件缓存
它是指一块芯片集成到硬盘、CPU上
作用是充当硬盘、CPU与外界接口之间的暂存器
外部接口通常是指硬盘或CPU和内存之间
客户端缓存
为了提高用户体验和减轻服务端压力,会将用户之前访问的一些数据缓存在客户端本地
一般来说指的是浏览器缓存或APP缓存
服务端缓存
服务端缓存目的和客户端缓存是一样的,只是站在服务端的角度考虑
如果客户端每次请求服务端都要直接连接到数据库,当客户请求数多的时候数据库压力会非常大
这个时候可以把一些经常被请求的数据存放在内存中
当有请求来访问的时候直接返回,不用经过数据库,这样就能减轻数据库的压力
硬件缓存属于硬件层面上的优化而客户端和服务端缓存则属于技术优化手段
缓存的本质是以空间换时间的手段来提升接.口的响应速度
作为一个后端开发关注更多的是服务器端缓存
应用场景
缓存常见的应用场景
高并发查询、高并发写入、热点数据、大对象初始化
使用缓存的好处
![](https://i-blog.csdnimg.cn/blog_migrate/e6c0fa4f264f785de48392f55e8674ee.png)
-
提升应用程序性能
因为内存速度远远高于磁盘,所以大大的提升了应用程序的访问速度
-
降低数据库成本
一个缓存实例就可以提供数十万的QPS,可以取代大量数据库实例从而降低总成本
-
减少后端负载
降低数据库负载,防止其在负载情况下性能下降甚至是雪崩
-
可预测的性能
现在应用程序最中常见的就是当有大量请求直接查询数据库时,有些请求的响应速度会变慢,导致接口的性能不可预测
通过利用高吞吐量的内存缓存可以缓解此问题
-
消除数据库热点
当有很少数据被频繁的访问,例如微博上某个明星突然官宣,很多用户都会去看一下
这会在数据库中产生热点,为了让访问速度更快,需要用特殊手段去维护这些热点数据
当使用了缓存以后就不需要考虑热点数据的问题
-
提高读取吞吐量
相比较于数据库除了更低的延迟外,内存系统还提供了更高的吞吐量
比如说redis单个实例可以处理十几万的读请求
缓存的常用类型:
-
内存缓存 (进程内缓存) -
分布式缓存 -
组合缓存 (多级缓存)
缓存的特点和常见问题
缓存的特点
-
设置存活时间(过期策略)
缓存通常需要设置有效期,过期后应当失效
常见的过期策略有:定时、定期、惰性失效
-
空间占用有限(淘汰策略)
缓存占用有空间上限,超过上限需淘汰部分缓存数据
常见的淘汰策略有:FIFO、LRU、LFU
-
支持并发更新
缓存需要支持并发的读取和写入
缓存的常见问题
使用缓存的应用程序正常的处理流程分为以下三个步骤
-
查询缓存是否存在该数据有则直接响应客户端 -
没有则查询数据库 -
将查询到的数据设置到缓存然后再响应客户端
缓存穿透
请求数据库中不存在的数据导致每次查询都无法命中缓存,从而违背了降低数据库压力的本意
缓存击穿
缓存失效的同时大量相同请求穿过缓存访问数据库
缓存雪崩
大量缓存同时失效,导致大量请求穿过缓存访问到数据库
常见的内存缓存实现方式
对于java应用而言,常见的基于内存缓存实现方式主要有以下四种
Java容器
基于JDK自带的Map容器类:HashMap、ConcurrentHashMap
Guava Cache
Google提供的java增强工具包Guava的一个模块,社区活跃。Spring5之前默认的内存缓存框架
Ehcache
重量级的内存缓存,支持二级缓存,Hibernate中默认的缓存框架
Caffeine
基于Guava API开发的高性能内存缓存,Spring5默认的内存缓存框架
总结
看到这里相信大家对于缓存应该有了一个基本的认知,总结起来缓存的作用就是为了降低数据库的压力,从而提高应用程序的性能
缓存的特点是过期策略、淘汰策略,是怎么实现的呢?
那么在使用缓存的过程中可能会遇到缓存穿透、缓存击穿、缓存雪崩的问题,我们又是如何应对这种情况呢?
内存缓存实现是如何去实现的呢?
关于本文章落下的这些疑点会在后期文章中详情介绍,包含以下知识点
-
手写一个简单的内存缓存工具 -
常见的内存缓存框架介绍并使用 -
从源码级别去分析 Caffeine的实现原理 -
缓存穿透、缓存击穿、缓存雪崩的应对手段 -
内存框架设计与实现