当前位置: 首页 > news >正文

缓存-Redis-缓存更新策略-主动更新策略-Cache Aside Pattern(全面 易理解)

**Cache-Aside Pattern(旁路缓存模式)**是一种广泛应用于缓存管理的设计模式,尤其在使用 Redis 作为缓存层时尤为常见。该模式通过在应用程序与缓存之间引入一个旁路,确保数据的一致性和高效性。本文将在之前讨论的 Redis 主动更新策略的基础上,进一步介绍 Cache-Aside Pattern,详细阐述其工作原理、实现方式、优缺点以及适用场景。

1. Cache-Aside Pattern 概述

Cache-Aside Pattern,也称为 Lazy Loading旁路缓存模式,是一种数据访问模式,其中应用程序根据需要动态地从缓存或数据库中加载数据。其核心思想是只有当应用程序需要数据时,才从数据库中加载并将其放入缓存;而当数据被修改时,应用程序首先更新数据库,然后使缓存失效或更新缓存。这种模式适用于数据访问呈现出局部性和高读取但低写入的特点。

2. Cache-Aside Pattern 的工作原理

Cache-Aside Pattern 的基本工作流程如下:

2.1 读取数据

  1. 请求数据:应用程序请求特定的数据。
  2. 检查缓存:首先检查 Redis 缓存中是否存在该数据。
    • 缓存命中:如果数据存在于缓存中,直接返回缓存数据。
    • 缓存未命中:如果数据不在缓存中,从数据库中读取数据。
  3. 缓存填充:将从数据库读取的数据写入 Redis 缓存,以便下次请求时可以直接从缓存中获取。
  4. 返回数据:将数据返回给应用程序。

2.2 写入数据

  1. 更新数据库:应用程序首先更新数据库中的数据。
  2. 失效缓存:删除或更新缓存中的相关数据,以确保缓存中的数据不会与数据库中的数据不一致。

3. Cache-Aside Pattern 的实现方式

以下以 Python 和 Redis 的 redis-py 库为例,展示如何实现 Cache-Aside Pattern。

3.1 读取数据示例

import redis
import json# 初始化 Redis 客户端
redis_client = redis.StrictRedis(host='localhost', port=6379, db=0)def get_user(user_id):cache_key = f"user:{user_id}"# 尝试从缓存中获取数据cached_user = redis_client.get(cache_key)if cached_user:print("从缓存中获取数据")return json.loads(cached_user)else:# 缓存未命中,从数据库中读取数据user = database_read_user(user_id)  # 假设存在此函数if user:# 将数据写入缓存,设置过期时间为 5 分钟redis_client.setex(cache_key, 300, json.dumps(user))print("从数据库中获取数据,并写入缓存")return user

3.2 写入数据示例

def update_user(user_id, new_data):cache_key = f"user:{user_id}"# 更新数据库中的数据success = database_update_user(user_id, new_data)  # 假设存在此函数if success:# 删除缓存中的数据,确保下次读取时获取最新数据redis_client.delete(cache_key)print("更新数据库并删除缓存")return success

3.3 缓存预热与失效策略

在 Cache-Aside Pattern 中,缓存预热和缓存失效策略至关重要。

  • 缓存预热:在系统启动或特定时间点,提前将热点数据加载到缓存中,以减少初次访问的延迟。
  • 缓存失效:在数据更新后及时使缓存失效或更新,确保缓存数据的实时性和一致性。

4. Cache-Aside Pattern 的优势与局限

4.1 优势

  1. 灵活性高:应用程序可以根据具体需求灵活地控制缓存的加载和失效。
  2. 资源利用高效:只有实际需要的数据才会被加载到缓存中,避免了不必要的缓存占用。
  3. 适用范围广:适用于多种数据访问模式,尤其是读取频繁但更新不频繁的场景。
  4. 简单易实现:实现逻辑相对简单,不需要复杂的缓存更新机制。

4.2 局限

  1. 冷启动问题:缓存未命中时,首次读取会有较高的延迟,需要从数据库中加载数据。
  2. 缓存穿透:大量请求未命中缓存的数据,直接请求数据库,可能导致数据库压力骤增。需要配合其他策略(如布隆过滤器)防止缓存穿透。
  3. 一致性问题:在高并发场景下,可能存在缓存与数据库不一致的短暂窗口期,需要设计合理的缓存失效策略。
  4. 缓存击穿:当某个热点数据的缓存失效时,可能会有大量请求同时访问数据库,导致数据库压力骤增。可以通过设置互斥锁或使用互斥机制(如 Redis 分布式锁)来防止缓存击穿。

5. Cache-Aside Pattern 与其他策略的比较

与之前提到的 Redis 主动更新策略相比,Cache-Aside Pattern 更侧重于按需加载和灵活控制缓存,而主动更新策略(如 Write-Through、Write-Behind 等)更注重在数据变更时主动更新缓存。

特性Cache-Aside Pattern主动更新策略
更新触发点读取或写入操作触发缓存加载或失效数据变更时主动更新缓存
数据加载方式按需加载(懒加载),只有在需要时才加载到缓存中数据更新时主动将最新数据推送到缓存中
一致性保障方式通过缓存失效或更新确保与数据库一致通过同步或异步更新缓存确保一致性
适用场景读取频繁但更新不频繁,数据热点不固定数据变化频繁且对实时性要求较高的场景
实现复杂度较低,主要依赖于缓存的读写逻辑较高,需要设计缓存的同步更新机制,如消息队列、发布/订阅等
缓存命中率较高的数据热点可以提高缓存命中率通过主动更新保持缓存的最新性,减少缓存未命中的几率

6. Cache-Aside Pattern 的应用场景

Cache-Aside Pattern 适用于多种业务场景,尤其是那些读取操作频繁且数据更新相对较少的应用,如:

  1. 用户信息查询:用户资料读取频率高,但更新频率相对较低。
  2. 产品详情展示:电商平台中,产品信息经常被查询,但价格或库存等信息更新频率相对较低。
  3. 日志和统计数据:需要频繁读取统计信息,但更新操作较少。
  4. 内容管理系统:如博客、新闻网站,内容读取频率高于内容更新频率。

7. 案例分析

案例:社交媒体平台的用户资料缓存

场景描述

在一个社交媒体平台中,用户资料(如用户名、头像、简介等)被频繁读取但不经常更新。为了提升读取性能和减轻数据库压力,用户资料被缓存在 Redis 中。

实现步骤

  1. 读取用户资料

    def get_user_profile(user_id):cache_key = f"user_profile:{user_id}"cached_profile = redis_client.get(cache_key)if cached_profile:print("从缓存中获取用户资料")return json.loads(cached_profile)else:user_profile = database_read_user_profile(user_id)  # 假设存在此函数if user_profile:redis_client.setex(cache_key, 3600, json.dumps(user_profile))  # 缓存1小时print("从数据库中获取用户资料,并写入缓存")return user_profile
    
  2. 更新用户资料

    def update_user_profile(user_id, new_profile_data):cache_key = f"user_profile:{user_id}"success = database_update_user_profile(user_id, new_profile_data)  # 假设存在此函数if success:# 删除缓存中的用户资料,确保下次读取时获取最新数据redis_client.delete(cache_key)print("更新数据库并删除用户资料缓存")return success
    

优势分析

  • 提升读取性能:大部分用户资料请求可以直接从 Redis 缓存中获取,减少数据库查询延迟。
  • 减轻数据库压力:通过缓存机制,显著减少数据库的读取负载,提高整体系统的可扩展性。
  • 数据一致性:通过在更新用户资料时删除缓存,确保下次读取时获取最新数据,保持缓存与数据库的一致性。

优化建议

  • 缓存预热:在系统启动时,预先加载部分热点用户资料到缓存中,减少初始请求的缓存未命中率。
  • 防止缓存穿透:对于不存在的用户资料请求,缓存空结果或设置短暂的负缓存,避免恶意请求直接打到数据库。
  • 使用互斥锁:在高并发情况下,防止大量请求同时导致缓存穿透,可以在读取缓存未命中时使用分布式锁,确保只有一个请求从数据库加载数据,其他请求等待或直接返回。

8. Cache-Aside Pattern 与其他缓存模式的结合

在实际应用中,Cache-Aside Pattern 并非孤立使用,常常与其他缓存模式和策略结合,以应对复杂的业务需求和系统挑战。例如:

  1. 结合预刷新(Refresh-Ahead):在 Cache-Aside Pattern 的基础上,结合预刷新机制,提前刷新热点数据,进一步提高缓存命中率和数据实时性。
  2. 结合发布/订阅机制:在数据更新后,通过发布/订阅机制通知其他服务删除或更新缓存,确保多实例或分布式系统中的缓存一致性。
  3. 结合互斥锁:使用分布式锁防止缓存击穿,确保在高并发情况下,只有一个请求能够从数据库加载数据并填充缓存。

9. 总结

**Cache-Aside Pattern(旁路缓存模式)**作为一种灵活且高效的缓存管理策略,广泛应用于各种高性能和高并发的应用场景中。它通过按需加载和动态更新缓存,兼顾了系统的性能和数据的一致性。然而,Cache-Aside Pattern 也存在一些挑战,如缓存穿透和缓存击穿,需要结合其他策略(如布隆过滤器、互斥锁等)进行优化。

关键要点

  1. 按需加载:只有在需要时才从数据库加载数据,并将其写入缓存,提升资源利用效率。
  2. 缓存失效策略:在数据更新后及时删除或更新缓存,确保缓存与数据库的一致性。
  3. 防止缓存穿透和击穿:结合布隆过滤器、互斥锁等机制,提升系统的稳定性和可靠性。
  4. 与其他策略结合使用:根据具体业务需求,灵活地组合使用 Cache-Aside Pattern 与其他缓存策略,以实现最佳的性能和一致性。

通过合理应用 Cache-Aside Pattern,开发者能够在保证系统性能和数据一致性的前提下,有效地管理和维护 Redis 缓存,满足现代高并发和高性能应用的需求。

相关文章:

缓存-Redis-缓存更新策略-主动更新策略-Cache Aside Pattern(全面 易理解)

**Cache-Aside Pattern(旁路缓存模式)**是一种广泛应用于缓存管理的设计模式,尤其在使用 Redis 作为缓存层时尤为常见。该模式通过在应用程序与缓存之间引入一个旁路,确保数据的一致性和高效性。本文将在之前讨论的 Redis 主动更新…...

杭州市有哪些大学能够出具论文检索报告?

杭州市具有查收查引服务的学校有浙江大学、杭州电子科技大学、浙江工业大学、杭州师范大学等高校。 1、浙江大学图书馆 浙江大学图书馆提供文献查收查引服务,包括查询学术论文被SCIE、SSCI、A&HCI、EI、CPCI-S、CPCI-SSH、CSSCI、CSCD等国内外权威数据库收录和…...

SpringBootWeb 登录认证(day12)

登录功能 基本信息 请求参数 参数格式:application/json 请求数据样例: 响应数据 参数格式:application/json 响应数据样例: Slf4j RestController public class LoginController {Autowiredpriva…...

使用AOP在切面逻辑中无法获取到requesetBody

使用场景:在接口处理之前,我们需要拿到请求参数,对参数进行校验。注意,这里需要拿到的是原始的请求信息! 一般的获取方式 ServletInputStream inputStream request.getInputStream(); StringBuilder stringBuilder …...

生成模型:变分自编码器-VAE

1.基本概念 1.1 概率 这里有: x为真实图像,开源为数据集, 编码器将其编码为分布参数 x ^ \hat{x} x^为生成图像, 通过解码器获得 p ( x ) ^ \hat{p(x)} p(x)^​: 观测数据的分布, 即数据集所构成的经验分布 p r e a l ( x ) p_{real}(x) preal​(x): …...

Hive sql执行文件合并配置参数

HIVE自动合并输出的小文件的主要优化手段为:HIVE将会启动一个独立的map-reduce任务进行输出文件的merge。 set hive.merge.mapfiles true: 在只有map的作业结束时合并小文件, set hive.merge.mapredfiles true: 在Map-Reduce的任…...

鸿蒙 ArkUI实现地图找房效果

常用的地图找房功能,是在地图上添加区域、商圈、房源等一些自定义 marker,然后配上自己应用的一些筛选逻辑构成,在这里使用鸿蒙 ArkUI 简单实现下怎么添加区域/商圈、房源等 Marker. 1、开启地图服务 在华为开发者官网,注册应用&…...

一套极简易的直流无刷电机(Deng FOC)开发套件介绍

目录 概述 1. 硬件组成介绍 1.1 主要硬件 1.2 电机驱动板介绍 1.3 2208电机模块 1.3.1 参数介绍 1.3.2 认识2208电机 2 驱动板接口介绍 2.1 PCB接口(MCU)定义 2.2 功能描述 2.2.1 电机驱动接口 2.2.2 编码器接口 2.2.3 电流输入引脚接口 2.…...

Inception模型详解及代码分析

模型背景 Inception系列模型由Google团队提出,旨在解决CNN分类模型面临的两大挑战: 如何在增加网络深度的同时提升分类性能 如何在保证分类准确率的同时降低计算和内存开销 Inception V1通过引入 并行卷积结构 和 1x1卷积 ,巧妙地解决了这两个问题,在保证模型质量的前提下…...

Springboot AOP 每个接口运行前 修改入参

控制台log输出为何频频失踪?   wxss代码为何频频失效?   wxml布局为何乱作一团?   究竟是道德的沦丧?还是人性的缺失?   让我们一起来 走 跑进科学 前言 麻蛋被这个功能恶心好久 终于解决了 特此记录一下 正文 Before("authCut()")public void cutProc…...

课题推荐——基于GPS的无人机自主着陆系统设计

关于“基于GPS的无人机自主着陆系统设计”的详细展开,包括项目背景、具体内容、实施步骤和创新点。如需帮助,或有导航、定位滤波相关的代码定制需求,请点击文末卡片联系作者 文章目录 项目背景具体内容实施步骤相关例程MATLAB例程python例程 …...

【深度学习】在深度学习训练过程中,数据量太少会导致模型过拟合还是欠拟合?

过拟合与欠拟合 过拟合 : 是指在训练集上表现非常好,但是在新的数据集上表现较差的现象。具体来说,模型在训练集上过度学习,捕捉了数据中的噪声和偶然性,导致它对训练数据的拟合非常精确,但缺乏泛化能力,无…...

js迭代器模式

以前JS原生的集合类型数据结构,只有Array(数组)和Object(对象); 而ES6中,又新增了Map和Set。四种数据结构各自有着自己特别的内部实现,但我们仍期待以同样的一套规则去遍历它们&…...

测试开发基础知识2

10.什么是等价类和边界值法? 1)等价类划分 等价类划分是将系统的输入域划分为若干部分,然后从每个部分选取少量代表性数据进行测试。等价类划分认为如果一个测试用例在某个等价类中的一个值上通过测试,那么它在这个类中的其他值上也…...

PromQL基础使用和案例解析

文章目录 PromQL简介数据类型1、瞬时数据 (Instant vector)2、区间数据 (Range vector)➢ Time Durations➢ Offest modifier➢ modifier 3、标量数据 (Scalar)4、字符串 (String) 条件匹配1、完全匹配2、正则匹配 运算符1、比较运算符2、算数运算符3、逻辑运算符4、聚合运算符…...

使用Python实现基于机器学习的垃圾邮件过滤

友们好! 我的新专栏《Python进阶》正式启动啦!这是一个专为那些渴望提升Python技能的朋友们量身打造的专栏,无论你是已经有一定基础的开发者,还是希望深入挖掘Python潜力的爱好者,这里都将是你不可错过的宝藏。 在这个专栏中,你将会找到: ● 深入解析:每一篇文章都将深…...

MySql根据经纬度查询距离

一、搭建测试 创建数据表() CREATE TABLE sys_test (id int(11) NOT NULL AUTO_INCREMENT COMMENT 主键ID,name varchar(20) DEFAULT NULL COMMENT 名称,longitude decimal(10,6) DEFAULT NULL COMMENT 经度,latitude decimal(10,6) DEFAULT NULL COMMENT 维度,PRIMARY KEY (id…...

Aviatrix Controller 未授权命令注入漏洞复现(CVE-2024-50603)

0x01 产品简介 Aviatrix Controller是一款强大的云网络管理平台,提供简化的跨云网络管理、自动化配置、安全策略、流量监控等功能,帮助企业实现更加灵活、安全和高效的云网络架构,特别适用于多云和混合云环境。主要用于编排和管理各种网络和连接解决方案。它为用户提供了一…...

数据结构与算法之二叉树: LeetCode 109. 有序链表转换二叉搜索树 (Ts版)

有序链表转换二叉搜索树 https://leetcode.cn/problems/convert-sorted-list-to-binary-search-tree/description/ 描述 给定一个单链表的头节点 head ,其中的元素 按升序排序 ,将其转换为 平衡 二叉搜索树 示例 1 输入: head [-10,-3,0,5,9] 输出:…...

Android NDK开发入门2之适应idm环境

环境搭建 Android NDK开发实战之环境搭建篇(so库,Gemini ai)-CSDN博客 初始配置 前面已经运行了一个简单的初始程序,现在我们来往初始程序添加类和函数,并成功运行的实验。 一级配置 第一层配置主要是cmake文件环境和一些编译选项。 build配置 可参…...

龙虎榜——20250610

上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

【JavaEE】-- HTTP

1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

无法与IP建立连接,未能下载VSCode服务器

如题,在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈,发现是VSCode版本自动更新惹的祸!!! 在VSCode的帮助->关于这里发现前几天VSCode自动更新了,我的版本号变成了1.100.3 才导致了远程连接出…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹,并新增内容 3.创建package文件夹...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器,其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机(Virtual Host)。 1. 简介 Nginx 使用 server_name 指令来确定…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...

selenium学习实战【Python爬虫】

selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...

IP如何挑?2025年海外专线IP如何购买?

你花了时间和预算买了IP,结果IP质量不佳,项目效率低下不说,还可能带来莫名的网络问题,是不是太闹心了?尤其是在面对海外专线IP时,到底怎么才能买到适合自己的呢?所以,挑IP绝对是个技…...