Redis与缓存解读

2025-01-11 04:50
文章标签 redis 解读 缓存

本文主要是介绍Redis与缓存解读,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Redis与缓存解读》文章介绍了Redis作为缓存层的优势和缺点,并分析了六种缓存更新策略,包括超时剔除、先删缓存再更新数据库、旁路缓存、先更新数据库再删缓存、先更新数据库再更新缓存、读写穿透和异步...

缓存

在业务开发中,必然会存在需要频繁访问的数据即热点数据,如果通过访问数据库访问这些数据,由于数据存储在磁盘上,在频繁访问下会进行频繁的IO操作,会导致数据库压力过大,响应速度变慢。

那么我们可以在添加php一层中间缓存层,将热点数据缓存在内存中,在访问数据时我们不在直接查询数据库,而是先访问缓存,如果数据存在(命中),直接返回即可。如果数据不存在(未命中),再访问数据库。

Redis与缓存解读

Redis 将数据存储在内存中,因此可以提供接近于内存的访问速度。所以 redis 天然适合作为缓存层。

缓存并不是万能的,实际上缓存更使用于读密集场景,在写密集场景中由于需要保证缓存于数据库的一致性,在修改缓存时还需要修改数据库,反而加重了后端压力。

缓存优缺点

优点:

  • 降低后端负载
  • 提高读写效率,降低响应时间

缺点:

  • 增加数据一致性成本
  • 增加代码维护成本

缓存更新策略

为了保证缓存数据有效,我们需要更新缓存。这里主要有六种缓存更新策略android

超时剔除

在 redis 中我们可以设置数据的生存时间(TTL),在超时后,redis会自动删除缓存,在下次查询该数据时,由于缓存不存在,会重新写入缓存,完成更新。

这种方法实现简单,但一致性一般,在缓存未过期之前,对数据库的数据进行增删查改都不会影响缓存,用户查到的数据始终是旧数据。

先删缓存再更新数据库

在对数据库进行更新时,先删除缓存,然后更新数据,在下次查询该数据时,由于缓存不存在,会重新将新数据写入缓存,javascript完成更新。

这种方法也无法保证数据的一致性。假设有两个线程,线程A 与 线程B , 在线程 A 更新缓存时,线程 B 发起查询,可能出现这种情况:

Redis与缓存解读

在这种情况下,一直到下次数据更新之前,缓存始终不一致,因此不推荐使用这种方法。

旁路缓存(先更新数据库,再删缓存)

在更新数据时,先更新数据库,再删除缓存,在下次查询该数据时,由于缓存不存在,会重新将新数据写入缓存,完成更新。

这种方法同样无法完全保证数据的一致性,但他是最常用的更新策略。因为它发生问题的概况较小,假设有两个线程,线程A 与 线程B , 在线程 B 更新数据库时,线程 A 发起查询,可能出现这种情况:

Redis与缓存解读

同样这种情况会出现数据不一致问题,但这种情况出现概率非常小,出现这种情况需要至少满足四个条件:

  • 读操作所读数据缓存失效
  • 有个并发的写操作
  • 写操作比读操作更快
  • 读操作早于写操作进入数据库,晚于写操作更新缓存

这样的条件是十分苛刻的,即使发生也是小概率事件,即使出现也可以通过缓存生存时间兜底。

这种方法最大的问题是删除缓存后的并发问题即缓存击穿问题,在缓存常见问题我们会介绍。

先更新数据库,再更新缓存

在更新数据时,先更新数据库,再更新缓存。

理论上这种方式比先更新数据库再删缓存有着更高的读性能,因为它事先准备好数据。但由于要更新数据库和缓存两块数据,所以它的写性能就比较低,同时他也不能完全保证数据的一致性。

假设有两个线程,线程A 与 线程B , 在线程 A B 同时更新,可能出现这种情况:

Redis与缓存解读

读写穿透

客户端只与缓存交互,缓存负责与数据库的交互。

读操作先查询缓存,如果缓存未命中,则缓存从数据库加载数据并写入缓存。写操作是直接写缓存,然后缓存同步更新数据库。这种模式下,缓存和数据库的一致性由缓存中China编程间件维护。

Redis与缓存解读

异步缓存写入模式

客户端只与缓存交互,缓存异步地将数据更新到数据库,实现最终一致性。

Redis与缓存解读

这种模式适用于写操作频繁的场景,但可能会导致数据一致性问题。

缓存常见问题

使用缓存比较常见的问题有下面三种问题:缓存击穿,缓存雪崩,缓存穿透。

缓存穿透

在我们的业务逻辑中,如果客户端访问的数据不存在于缓存我们会访问数据库,如果数据库存在数据就写入缓存,如果不存在就返回,那么如果客户端不怀好意,频繁发起对不存在数据的请求会发生什么呢?大量请求会直接打入数据库,增大后端压力,实现对服务器的攻击。

Redis与缓存解读

解决方案有很多种,最常见的有两种方法:缓存空对象,布隆过滤器

缓存空对象:当请求的数据在数据库中不存在时,我们将这个“不存在”的结果缓存起来,设置一个较短的过期时间。 这样,相同的请求在缓存失效之前会直接命中缓存,减轻数据库的压力。

Redis与缓存解读

布隆过滤器:使用布隆过滤器存储所有可能查询的键,当请求到达时,先通过布隆过滤器判断键是否存在。如果布隆过滤器认为键不存在,则直接返回,不进行数据库查询和缓存操作。

Redis与缓存解读

缓存雪崩

缓存雪崩是指在高并发系统中,大量的缓存数据在同一时间过期或被清除,导致大量请求同时涌向数据库,从而对数据库造成巨大压力,甚至可能导致数据库宕机。类似于“雪崩”。

常见的解决方法有以下几种:

设置不同的过期时间: 对于缓存中的每个数据项,设置不同的过期时间,这样可以避免大量数据同时过期。例如,可以为每个数据项的过期时间加上一个随机值。

使用互斥锁: 当缓存数据过期时,如果多个请求同时到达,使用互斥锁确保只有一个请求去查询数据库并更新缓存,其他请求等待或重试。

热点数据永不过期: 对于访问非常频繁的热点数据,可以考虑设置为永不过期,或者设置一个非常长的过期时间。

缓存击穿

在高并发的访问下,当某个热点数据缓存处于过期失效的时间点时,极有可能出现多个线程同时查询该缓存。而查询数据库更新缓存又需要消耗一定时间,在同一时间会有大量并发请求直接访问数据库而导致数据库服务器的CPU或者内存负载过高,服务能力下降甚至宕机。

那么如何解决这个问题呢?有三种解决方案。

  • 加锁:在缓存失效后,通过加锁的方式只允许一个线程查询数据和写缓存,其他线程阻塞等待。这个方法会造成部分请求等待。
  • 二级缓存:A1为原始缓存,A2为拷贝缓存。A1失效时,可以访问A2,其中A1的缓存失效时间设置为短期(比如5min),A2的缓存失效时间设置为长期(比如1天)。如果缓存value很大,此方案的缓存空间利用率低。
  • 双key:思www.chinasem.cn路和方案2类似,不同的是双key分别缓存过期时间(key-time)和缓存数据(key-data),其中(key-time)的缓存失效时间设置为短期(比如5min),(key-data)的缓存失效时间设置为长期(比如1天)。当第一个线程发现 key-time 过期不存在时,则先更新key-time,然后去查询数据库并更新key-data 的值;当其他线程来获取数据时,虽然第一个线程还没有从数据库查询完毕并更新缓存,但发现key-time存在,会直接读取缓存的旧数据返回。和二级缓存的方案对比,该方案的缓存空间利用率高。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程China编程(www.chinasem.cn)。

这篇关于Redis与缓存解读的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153029

相关文章

Redis 命令详解与实战案例

《Redis命令详解与实战案例》本文详细介绍了Redis的基础知识、核心数据结构与命令、高级功能与命令、最佳实践与性能优化,以及实战应用场景,通过实战案例,展示了如何使用Redis构建高性能应用系统... 目录Redis 命令详解与实战案例一、Redis 基础介绍二、Redis 核心数据结构与命令1. 字符

Java序列化之serialVersionUID的用法解读

《Java序列化之serialVersionUID的用法解读》Java序列化之serialVersionUID:本文介绍了Java对象的序列化和反序列化过程,强调了serialVersionUID的作... 目录JavChina编程a序列化之serialVersionUID什么是序列化为什么要序列化serialV

SpringBoot18 redis的配置方法

《SpringBoot18redis的配置方法》本文介绍在SpringBoot项目中集成和使用Redis的方法,包括添加依赖、配置文件、自定义序列化方式、使用方式、实际使用示例、常见操作总结以及注意... 目录一、Spring Boot 中使用 Redis1. 添加依赖2. 配置文件3. Redis 配置类

Redis中群集三种模式的实现

《Redis中群集三种模式的实现》Redis群集有三种模式,分别是主从同步/复制、哨兵模式、Cluster,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面... 目录1. Redis三种模式概述2、Redis 主从复制2.1 主从复制的作用2.2 主从复制流程2

Redis的安全机制详细介绍及配置方法

《Redis的安全机制详细介绍及配置方法》本文介绍Redis安全机制的配置方法,包括绑定IP地址、设置密码、保护模式、禁用危险命令、防火墙限制、TLS加密、客户端连接限制、最大内存使用和日志审计等,通... 目录1. 绑定 IP 地址2. 设置密码3. 保护模式4. 禁用危险命令5. 通过防火墙限制访问6.

深入理解Redis线程模型的原理及使用

《深入理解Redis线程模型的原理及使用》Redis的线程模型整体还是多线程的,只是后台执行指令的核心线程是单线程的,整个线程模型可以理解为还是以单线程为主,基于这种单线程为主的线程模型,不同客户端的... 目录1 Redis是单线程www.chinasem.cn还是多线程2 Redis如何保证指令原子性2.

Docker + Redis 部署集群的实现步骤

《Docker+Redis部署集群的实现步骤》本文详细介绍了在三台服务器上部署高可用Redis集群的完整流程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋... 目录一、环境准备1. 服务器规划(3 台服务器)2. 防火墙配置(三台服务器均执行)3. 安装 docke

Redis中删除策略的几种实现方式

《Redis中删除策略的几种实现方式》本文详细介绍了Redis的过期键删除策略和内存淘汰策略,过期键删除策略包括定时删除、惰性删除和定期删除,具有一定的参考价值,感兴趣的可以了解一下... 目录前言一、设计背景:为什么需要删除策略?二、第一类:过期键的 3 种核心删除策略1. 定时删除(Timed Dele

Spring Boot整合Redis注解实现增删改查功能(Redis注解使用)

《SpringBoot整合Redis注解实现增删改查功能(Redis注解使用)》文章介绍了如何使用SpringBoot整合Redis注解实现增删改查功能,包括配置、实体类、Repository、Se... 目录配置Redis连接定义实体类创建Repository接口增删改查操作示例插入数据查询数据删除数据更

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.