【缓存策略】你知道 Cache Aside(缓存旁路)这个缓存策略吗

👉博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主

⛪️ 个人社区:个人社区
💞 个人主页:个人主页
🙉 专栏地址: ✅ Java 中级
🙉八股文专题:剑指大厂,手撕 Java 八股文

在这里插入图片描述

文章目录

      • 1. 缓存策略 Cache Aside 是什么?
      • 2. 缓存策略 Cache Aside 的应用场景
      • 3. 缓存策略 Cache Aside 的优缺点
      • 4. 用 Java 模拟使用 Cache Aside 策略
        • 1. 引入依赖
        • 2. 配置 Redis
        • 3. 创建缓存服务
        • 4. 创建用户服务
        • 5. 创建控制器
        • 6. 启动类

1. 缓存策略 Cache Aside 是什么?

Cache Aside(缓存旁路) 是一种常见的缓存策略,其核心思想是在读取数据时,先从缓存中读取,如果缓存中没有数据,则从数据库中读取,并将数据写入缓存;在写入数据时,直接更新数据库,并从缓存中移除该数据。

具体步骤:

  1. 读取数据

    • 尝试从缓存中读取数据。
    • 如果缓存中存在数据,直接返回。
    • 如果缓存中不存在数据,从数据库中读取数据。
    • 将从数据库中读取的数据写入缓存,然后返回数据。
  2. 写入数据

    • 直接更新数据库。
    • 从缓存中移除该数据,以避免缓存中的数据与数据库中的数据不一致。

2. 缓存策略 Cache Aside 的应用场景

Cache Aside 适用于以下场景:

  1. 读多写少:适用于读取操作远多于写入操作的场景,如新闻网站的文章阅读。
  2. 数据更新不频繁:适用于数据更新不频繁,但读取非常频繁的场景。
  3. 数据一致性要求不高:适用于对数据一致性要求不高的场景,可以容忍短暂的数据不一致。
  4. 高并发读取:适用于高并发读取的场景,可以显著减轻数据库的负载。

3. 缓存策略 Cache Aside 的优缺点

优点:

  1. 性能提升:通过缓存减少对数据库的访问次数,提高读取性能。
  2. 减轻数据库压力:减少数据库的读取请求,减轻数据库的负载。
  3. 灵活性:可以在不修改业务逻辑的情况下,通过缓存策略提升系统性能。

缺点:

  1. 数据不一致:在写入数据后,缓存中的数据可能已经过期,导致短暂的数据不一致。
  2. 缓存击穿:如果大量请求同时访问同一个缓存键,而该键在缓存中不存在,会导致大量请求直接打到数据库,造成数据库压力。
  3. 缓存雪崩:如果缓存中的数据在同一时间过期,大量请求会同时打到数据库,造成数据库压力。

4. 用 Java 模拟使用 Cache Aside 策略

下面是一个简单的 Java 示例,模拟使用 Cache Aside 策略。

1. 引入依赖

pom.xml 中添加 Redis 依赖(假设使用 Redis 作为缓存):

<dependencies><!-- Spring Boot Starter Data Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Spring Boot Starter Web --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Starter Test --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>
2. 配置 Redis

application.properties 中配置 Redis:

spring.redis.host=localhost
spring.redis.port=6379
3. 创建缓存服务

创建一个服务类来实现 Cache Aside 策略:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;@Service
public class CacheService {@Autowiredprivate RedisTemplate<String, String> redisTemplate;@Autowiredprivate UserService userService;public String getUserById(String userId) {// 尝试从缓存中读取数据String cachedUser = redisTemplate.opsForValue().get(userId);if (cachedUser != null) {return cachedUser;}// 如果缓存中没有数据,从数据库中读取String user = userService.getUserById(userId);if (user != null) {// 将数据写入缓存redisTemplate.opsForValue().set(userId, user);}return user;}public void updateUser(String userId, String userName) {// 直接更新数据库userService.updateUser(userId, userName);// 从缓存中移除该数据redisTemplate.delete(userId);}
}
4. 创建用户服务

创建一个简单的用户服务类,模拟数据库操作:

import org.springframework.stereotype.Service;@Service
public class UserService {public String getUserById(String userId) {// 模拟从数据库中读取用户数据// 实际应用中,这里应该是数据库查询操作return "User: " + userId;}public void updateUser(String userId, String userName) {// 模拟更新数据库中的用户数据// 实际应用中,这里应该是数据库更新操作System.out.println("Updating user: " + userId + " to " + userName);}
}
5. 创建控制器

创建一个控制器类,提供 RESTful API 接口:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@Autowiredprivate CacheService cacheService;@GetMapping("/user")public String getUser(@RequestParam String id) {return cacheService.getUserById(id);}@PostMapping("/user")public String updateUser(@RequestParam String id, @RequestParam String name) {cacheService.updateUser(id, name);return "User updated: " + id + " to " + name;}
}
6. 启动类

创建一个启动类来启动 Spring Boot 应用:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class CacheAsideApplication {public static void main(String[] args) {SpringApplication.run(CacheAsideApplication.class, args);}
}

运行项目

  1. 启动 Redis 服务器

    • 确保 Redis 服务器正在运行,可以通过命令 redis-server 启动。
  2. 启动 Spring Boot 应用

    • 运行 CacheAsideApplication 类的 main 方法,启动 Spring Boot 应用。
  3. 测试接口

    • 使用 Postman 或浏览器测试接口:
      • GET http://localhost:8080/user?id=1:读取用户数据。
      • POST http://localhost:8080/user?id=1&name=JohnDoe:更新用户数据。

精彩专栏推荐订阅:在下方专栏👇🏻
✅ 2023年华为OD机试真题(A卷&B卷)+ 面试指导
✅ 精选100套 Java 项目案例
✅ 面试需要避开的坑(活动)
✅ 你找不到的核心代码
✅ 带你手撕 Spring
✅ Java 初阶

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/469537.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2.操作系统常见面试问题2

2.19 说说什么是堆栈溢出&#xff0c;会怎么样&#xff1f; 堆溢出&#xff08;Heap Overflow&#xff09;是指程序在运行时向堆内存区域写入了超出预定大小的数据&#xff0c;导致堆内存区域的数据结构&#xff08;如动态分配的内存块&#xff09;被破坏&#xff0c;从而引发…

基于TI AM62A+FPGA实现FPDLINK III车载摄像头解决方案

功能概述 本模块主要包含FPDLINKIII/CML收发信号与HDMI/SDI/USB信号、千兆网络信号&#xff0c;支持客户按照按照指定功能定制 当前默认功能为FPD LINK III/CML转为HDMI/SDI/UVC信号 性能参数 名称 描述 供电接口 DC12V FPD LINK RX GM8914 FPD LINK TX GM8913 千兆网…

丹摩征文活动 | SD3+ComfyUI的图像部署实践

一、前言 作为Stability AI 推出的一款革命性的文本转图像开源模型&#xff0c;Stable Diffusion 3&#xff08;简称SD3&#xff09;在图像质量、文本内容生成、理解复杂指令以及资源利用效率方面&#xff0c;都有着不俗的表现。 SD3的Medium版本&#xff0c;拥有20亿参数&am…

介绍几个提取视频文案的Coze插件

用过coze的朋友应该都知道“链接读取”这个插件&#xff0c;它不但可以读取网页内容&#xff0c;而且还可以提取视频链接的内容&#xff0c;但是对于有些平台的网址&#xff0c;它就有些无能为力了。 这里就可以用到我们今天的主角之一“字幕获取”插件。 一、字幕获取插件 从…

MIT 6.S081 Lab1: Xv6 and Unix utilities翻译

Lab1: Xv6 and Unix utilities 文章目录 Lab1: Xv6 and Unix utilities实验任务启动xv6(难度&#xff1a;Easy)sleep(难度&#xff1a;Easy)pingpong&#xff08;难度&#xff1a;Easy&#xff09;Primes(素数&#xff0c;难度&#xff1a;Moderate/Hard)find&#xff08;难度&…

YOLOv11融合ICCV[2023]动态蛇形卷积Dynamic模块及相关改进思路|YOLO改进最简教程

YOLOv11v10v8使用教程&#xff1a; YOLOv11入门到入土使用教程 YOLOv11改进汇总贴&#xff1a;YOLOv11及自研模型更新汇总 《Dynamic Snake Convolution based on Topological Geometric Constraints for Tubular Structure Segmentation》 一、 模块介绍 论文链接&#xff…

Sam Altman:年底将有重磅更新,但不是GPT-5!

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;专注于分享AI全维度知识&#xff0c;包括但不限于AI科普&#xff0c;AI工…

信息网络安全——AES加密算法

算法背景介绍 该算法是由美国发明的&#xff0c;1997年NIST发布算法征集公告&#xff0c;98年入围15个候选算法&#xff0c;99年进入五强&#xff0c;00年凭借安全性&#xff0c;性能&#xff0c;大小实现特性为标准最终选定&#xff0c;01年正式发布AES标准。   选择AES主要…

arm 汇编技巧

汇编标号&#xff1a;f表示forward&#xff0c; b表示backward&#xff1a; Here is an example: 1: branch 1f 2: branch 1b 1: branch 2f 2: branch 1b Which is the equivalent of: label_1: branch label_3 label_2: branch label_1 label_3: branch label_4 label_4: bra…

初始JavaEE篇 —— 文件操作与IO

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;JavaEE 目录 文件介绍 Java标准库中提供操作文件的类 文件系统操作 File类的介绍 File类的使用 文件内容操作 二进制文件的读写操作…

华为网络设备这些“危险命令”,切记不能瞎操作!

在华为网络设备上&#xff0c;有一些“危险操作”命令&#xff0c;因为它们可能会对设备的正常运行、配置数据或网络安全产生重大影响。 在使用这些命令时&#xff0c;需要非常谨慎&#xff0c;确保理解其作用并备份当前配置。 删除配置或数据的命令 reset saved-configurat…

Linux中线程的基本概念与线程控制

Linux操作系统中线程 1、进程指的是加载进内存的程序&#xff0c;进程 内核数据结构 进程代码和数据 2、进程在执行ABCD四个函数时是一个单执行流&#xff0c;而如果想让AB函数和CD函数并发执行&#xff0c;我们通常会创建一个子进程&#xff0c;但这意味着需要创建新的进程…

Jenkins声明式Pipeline流水线语法示例

系列文章目录 docker搭建Jenkins2.346.3版本及常用工具集成配置(ldap、maven、ansible、npm等) docker安装低版本的jenkins-2.346.3,在线安装对应版本插件失败的解决方法 文章目录 系列文章目录jenkins流水线基础1、pipeline1.1、什么是pipeline&#xff1f;1.2、为什么使用pi…

Leetcode 找出字符串中第一个匹配项的下标

算法思想&#xff1a; 检查特殊情况&#xff1a;首先判断needle是否为空字符串。如果是空字符串&#xff0c;根据题意直接返回0&#xff0c;因为空子串默认在任何字符串的起始位置。 获取字符串长度&#xff1a;定义m为haystack的长度&#xff0c;n为needle的长度&#xff0c;…

股市下跌时,期权市场的应对策略有哪些?

在股票交易中&#xff0c;投资者对市场的下跌无能为力&#xff0c;只能眼睁睁地看着自己亏损。在期权交易中&#xff0c;交易方向灵活&#xff0c;也有应对市场下跌的交易策略。下面&#xff0c;我们整理了一些股市下跌时&#xff0c;期权市场的应对策略有哪些&#xff1f;希望…

【C++】 C++游戏设计---五子棋小游戏

1. 游戏介绍 一个简单的 C 五子棋小游戏 1.1 游戏规则&#xff1a; 双人轮流输入下入点坐标横竖撇捺先成五子连线者胜同一坐标点不允许重复输入 1.2 初始化与游戏界面 初始化界面 X 输入坐标后 O 输入坐标后 X 先达到胜出条件 2. 源代码 #include <iostream> #i…

Spring——容器:IoC

容器&#xff1a;IoC IoC 是 Inversion of Control 的简写&#xff0c;译为“控制反转”&#xff0c;它不是一门技术&#xff0c;而是一种设计思想&#xff0c;是一个重要的面向对象编程法则&#xff0c;能够指导我们如何设计出松耦合、更优良的程序。 Spring 通过 IoC 容器来…

微服务容器化部署实践(FontConfiguration.getVersion)

文章目录 前言一、整体步骤简介二、开始实战1.准备好微服务2.将各个微服务打包为镜像第一种第二种3. 将各个打包好的镜像,通过docker-compose容器编排,运行即可总结前言 docker容器化部署微服务: 将微服务容器化部署到 Docker 容器中是一个常见的做法,可以提高应用的可移…

提升法律文书处理效率的秘密武器:开源文档比对工具解析

本篇文章介绍了一款针对律师行业的免费开源文档比对工具&#xff0c;旨在解决法律文档的多版本比对难题。通过逐字、逐句精确比对、语义分析、批量处理等核心功能&#xff0c;该工具可高效识别文本差异&#xff0c;提升文书审查效率并降低错误风险。它支持多种文件格式&#xf…

把握鸿蒙生态崛起的机遇:开发者视角的探讨

​ 大家好&#xff0c;我是程序员小羊&#xff01; 前言&#xff1a; 近年来&#xff0c;鸿蒙系统&#xff08;HarmonyOS&#xff09;的发展备受瞩目。随着其在智能手机、智能穿戴、车载系统和智能家居等领域的广泛应用&#xff0c;鸿蒙系统正逐渐形成与安卓、iOS并列的三足鼎立…