Redis具有高性能的数据存取特性,广泛的应用于缓存场景,在提升业务应用响应速度的同时,也避免了将数据查询的压力发送到了数据库。Redis用作缓存的普遍性和其在应用中的钟涛作用,我们需要了解Redis为什么能够用作缓存一级其具体的工作机制。
无论是计算机系统还是具体的应用,其架构都是分层的。系统中的不同层之间访问速度是不一样的,所以将一些经常被访问的数据放到缓存中就可以加快其访问速度。
以计算机系统为例,下图展现了计算机系统中的三层存储结构以及其容量和访问性能。CPU、内存、磁盘的访问速度差别很大。如果每次CPU处理数据都要从磁盘中读取,那么磁盘就会拖累CPU的计算,影响整个计算机的运行速度。
计算机中默认有两种缓存:
因为缓存的容量是有限的,所以缓存中的数据需要按一定规则淘汰出去,写回后端系统,而新的数据又要从后端系统中读取进来,写入缓存。我们可以学习下缓存是如何处理请求的,当业务应用在访问Redis缓存中的数据时,数据不一定内存,因此其处理方式也是不同的。
Redis用作缓存时,会把Redis部署在数据库的前端,当业务应用在访问数据时。先查询Redis中是否保存了相应的数据,然后在根据数据是否在缓存中分为以下两种情况:
通常我们的应用是一个web应用,用户的请求发送到Tomcat,Tomcat负责处理业务逻辑,如果需要访问数据就需要从MySQL中读写数据。Redis在用作缓存时有三个基本操作:
Redis是一个独立的系统软件,和业务应用程序是两个软件。在Redis部署完之后,如果程序中想要执行Redis缓存就需要增加相应的缓存操作代码,读取缓存、读取数据、更新缓存等操作都需要在应用程序中完成,所以称为旁路缓存。
平时在开发程序时,我们是没有专门在代码中显式地创建LLC或page cache的实例的,也没有显式调用过它们的GET接口。这是因为,我们在构建计算机硬件系统时,已经把LLC和page cache放在了应用程序的数据访问路径上,应用程序访问数据时直接就能用上缓存。
而使用Redis用作缓存时就需要增加三方面的代码:
为了使用缓存,Web应用程序需要有一个表示缓存系统的实例对象redisCache,还需要主动调用Redis的GET接口,并且要处理缓存命中和缓存缺失时的逻辑,例如在缓存缺失时,需要更新缓存。
不过,除了从Redis缓存中查询、读取数据以外,应用程序还可能会对数据进行修改,这时,我们既可以在缓存中修改,也可以在后端数据库中进行修改,我们该怎么选择呢?
Redis缓存的两种类型:只读缓存和读写缓存。只读缓存能加速读请求,而读写缓存可以同时加速读写请求。
当Redis用作只读缓存时,应用要读取数据的话,会先调用Redis GET接口,查询数据是否存在。而所有的数据写请求,会直接发往后端的数据库,在数据库中增删改。对于删改的数据来说,如果Redis已经缓存了相应的数据,应用需要把这些缓存的数据删除,Redis中就没有这些数据了。
当应用再次读取这些数据时,会发生缓存缺失,应用会把这些数据从数据库中读出来,并写到缓存中。这样一来,这些数据后续再被读取时,就可以直接从缓存中获取了,能起到加速访问的效果。
举个例子:如果业务嘤嘤需要修改数据A,如果缓存中有数据A,应用会现在数据库中修改A,再将Redis中的A删除。等到应用需要读取数据A时就会发生缓存丢失,应用从数据库中读取A,并且写入Redis以便后续请求能够从缓存中直接读取。
对于读写缓存来说,除了读请求会发送到缓存进行处理(直接在缓存中查询数据是否存在),所有的写请求也会发送到缓存,在缓存中直接对数据进行增删改操作。此时,得益于Redis的高性能访问特性,数据的增删改操作可以在缓存中快速完成,处理结果也会快速返回给业务应用,这就可以提升业务应用的响应速度。
在使用读写缓存时,最新的数据是在Redis中,而Redis是内存数据库,一旦出现掉电或宕机,内存中的数据就会丢失。这也就是说,应用的最新数据可能会丢失,给应用业务带来风险。
所以根据业务应用对数据可靠性和缓存性能的不同要求,我们会有同步直写和异步写回两种策略。
关于是选择只读缓存,还是读写缓存,主要看我们对写请求是否有加速的需求。
举个例子,在商品大促的场景中,商品的库存信息会一直被修改。如果每次修改都需到数据库中处理,就会拖慢整个应用,此时,我们通常会选择读写缓存的模式。而在短视频App的场景中,虽然视频的属性有很多,但是,一般确定后,修改并不频繁,此时,在数据库中进行修改对缓存影响不大,所以只读缓存模式是一个合适的选择。
1、极客时间-Redis核心技术与实战
下一篇