Redis缓存篇(一)Redis是如何工作的
发布日期:2021-05-09 04:32:37 浏览次数:17 分类:博客文章

本文共 1716 字,大约阅读时间需要 5 分钟。

Redis提供了高性能的数据存取功能,所以广泛应用在缓存场景中,既能有效地提升业务应用的响应速度,还可以避免把高并发压力发送到数据库层。

因为Redis用作缓存的普遍性以及它在业务应用中的重要作用,所以需要系统地掌握缓存的一系列内容,包括工作原理、替换策略、异常处理和扩展机制。

今天我们了解缓存的特征和Redis缓存的工作机制。

缓存特征

主要有两个特征:

一是在一个层次化的系统中,缓存一定是一个快速子系统,数据存在缓存中时,能避免每次从慢速子系统中存取数据。

二是缓存系统的容量大小总是小于后端慢速系统的,我们不可能把所有数据都放在缓存系统中。

Redis缓存处理请求的两种情况

把Redis用作缓存时,会把Redis部署在数据库的前端,业务应用在访问数据时,会先查询Redis中是否保存了相应的数据。此时,根据数据是否存在缓存中,会有两种情况:

  • 缓存命中:Redis中有相应数据,就直接读取Redis,性能非常快。
  • 缓存失败:Redis中没有相应数据,就从后端数据库中读取数据,性能就会变慢。

因为Redis是独立的系统软件,和业务应用程序是两个软件,因此使用Redis缓存时,要在应用程序中增加三方面代码:

  • 当应用程序需要读取数据时,需要在代码中显式调用Redis的GET操作接口,进行查询;
  • 如果缓存缺失了,应用程序需要再和数据库连接,从数据库中读取数据;
  • 当缓存中的数据需要更新时,也需要在应用程序中显式地调用SET操作接口,把更新的数据写入缓存。

下面是一段示例代码:

String cacheKey = “productid_11010003”;String cacheValue = redisCache.get(cacheKey);//缓存命中if ( cacheValue != NULL)   return cacheValue;//缓存缺失else   cacheValue = getProductFromDB();   redisCache.put(cacheValue)  //缓存更新

 

缓存的类型

按照Redis缓存是否接受写请求,可以分为只读缓存和读写缓存。

只读缓存

只读缓存指读请求会先经过Redis,写操作不会经过Redis,但是会删除相应的数据。当再次读取数据时,会发生缓存缺失,然后从数据库中读取并写入缓存。

读写缓存

读写缓存指除了读请求会发到缓存处理,写请求也会发到缓存处理。

和只读缓存不一样的是,在使用读写缓存时,最新的数据是在Redis中,而Redis是内存数据库,一旦出现掉电或宕机,内存中的数据就会丢失。

所以,根据业务应用对数据可靠性和缓存性能的不同要求,会有两种策略,分别是同步直写和异步写回。

  • 同步直写,优先保证数据可靠性:写请求发给缓存,同时也会发给后端数据库进行处理,等到缓存和数据库都写完数据,才给客户端返回。
  • 异步写回,优先提供快速响应:所有写请求都先在缓存中处理,等到这些增改的数据要被缓存淘汰时,缓存再写回后端数据库。

只读缓存和读写缓存的选择

  • 如果需要对写请求进行回事,选择读写缓存。
  • 如果写请求很少,或者是只需要提升读请求的响应速度的话,选择只读缓存。

只读缓存和使用直写策略的读写缓存有什么区别?

使用只读缓存时,是先把修改写到后端数据中,再把缓存中的数据删除。下次访问时,再从后端数据库读取。

  • 优点:数据库和缓存完全一致,缓存中永远保留的是经常访问的热点数据。
  • 缺点:数据删除后访问会触发一次缓存缺失,从后端数据库加载数据到缓存中,这个过程访问延时会变大。

使用读写缓存时,是同时修改数据库和缓存中的值。

  • 优点:被修改后的数据永远在缓存中存在,下次访问直接命中缓存。
  • 缺点:在高并发场景下,可能会导致缓存和数据库的不一致

当数据库或缓存修改失败时:

  • 只读缓存:数据库和缓存中的数据保持一致
  • 读写缓存:可能导致缓存和数据库的不一致

总结一下:只读缓存牺牲一定性能,优先保证数据库和缓存的一致性,更适合对于一致性要求比较高的业务场景。对于数据库和缓存一致性要求不高,或者不存在并发修改同一个值的情况,使用读写缓存比较合适,保证更好的性能。

参考资料

上一篇:Redis缓存篇(二)淘汰机制:缓存满了怎么办?
下一篇:单调栈技巧总结

发表评论

最新留言

逛到本站,mark一下
[***.202.152.39]2025年04月17日 13时27分27秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

CentOS系列:【Linux】CentOS7操作系统安装nginx实战(多种方法,超详细) 2023-01-23
Docker部署postgresql-11以及主从配置 2023-01-23
EnvironmentNotWritableError: The current user does not have write permissions to the target environm 2023-01-23
kali安装docker(亲测有效) 2023-01-23
Linux系列:Linux目录分析:[/] + [/usr] + [/usr/local] + [/usr/local/app-name]、Linux最全环境配置 + 动态库/静态库配置 2023-01-23
mysql系列:远程连接MySQL错误“plugin caching_sha2_password could not be loaded”的解决办法 2023-01-23
Nmap端口服务 之 CentOS7 关于启动Apache(httpd)服务、telnet服务、smtp服务、ftp服务、sftp服务、snmp服务 2023-01-23
PHP系列:PHP 基础编程 2(时间函数、数组---实现登录&注册&修改) 2023-01-23
PHP系列:使用PHP实现登录注册功能的完整指南 2023-01-23
Python&aconda系列:cmd/powershell/anaconda prompt提示“系统找不到指定的路径”(亲测有效) 2023-01-23
Python&aconda系列:(W&L)Conda使用faiss-gpu报错及解决办法、安装numpy的坑、cmd执行Python脚本找不到第三方库、安装tensorflow-gpu时遇到的from 2023-01-23
python&anconda 系列:Pycharm在debug问题的N种解决方案(一般程序、web方向、人工智能方向) 2023-01-23
python&anconda系列(亲测有效):tensorflow AttributeError: ‘str’ object has no attribute ‘decode’ 2023-01-23
python&anconda系列:tf.keras.backend.get_session()和keras.backend.get_会话()返回不同的会话对象(待解答) 2023-01-23
"WARNING: Increasing RAM size to 1GB" and "Cannot set up guest memory 'xxx.ram': Invalid argument". 2023-01-23
#if 0 #elif 1 #else #endif 用法 2023-01-23
(反射+内省机制的运用)简单模拟spring IoC容器的操作 2023-01-23
(转)tomcat7.0 manager app和host manager web管理 2023-01-23
(转)在CListView列表视图中添加右键菜单的方法 2023-01-23
.Net(C#)实现异步编程 2023-01-23