【缓存策略】你知道 Write Back(回写)这个缓存策略吗?

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

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

在这里插入图片描述

文章目录

      • 1. 缓存策略 Write Back 是什么?
      • 2. 缓存策略 Write Back 的应用场景
      • 3. 缓存策略 Write Back 的优缺点
      • 4. 用 Java 模拟使用 Write Back 策略
        • 缓存类
        • 测试类

1. 缓存策略 Write Back 是什么?

Write Back(回写) 是一种缓存策略,当数据被修改时,只在缓存中更新数据,而不是立即写回到主存储(如磁盘)。只有当缓存中的数据被替换出去时,才会将修改后的数据写回到主存储。

工作原理:

  1. 读取数据

    • 如果数据在缓存中存在且有效,直接从缓存中读取。
    • 如果数据不在缓存中或无效,从主存储中读取数据,并将其加载到缓存中。
  2. 写入数据

    • 当数据被修改时,只在缓存中更新数据。
    • 缓存中的数据标记为“脏”(dirty),表示该数据已被修改但尚未写回到主存储。
  3. 替换数据

    • 当缓存空间不足需要替换数据时,检查被替换的数据是否为“脏”。
    • 如果是“脏”数据,先将其写回到主存储,然后再替换出缓存。

2. 缓存策略 Write Back 的应用场景

  1. 高性能要求的系统

    • 适用于对写操作性能要求较高的系统,如数据库缓存、文件系统缓存等。
    • 通过减少写回主存储的次数,提高写操作的性能。
  2. 数据访问频率高的场景

    • 适用于数据访问频率高且写操作频繁的场景,如内存数据库、高速缓存系统等。
    • 通过减少主存储的写操作,降低系统负载。
  3. 网络延迟敏感的系统

    • 适用于网络延迟敏感的系统,如分布式缓存、远程存储系统等。
    • 通过减少网络传输次数,提高系统的响应速度。

3. 缓存策略 Write Back 的优缺点

优点:

  1. 写操作性能高
    • 写操作只需更新缓存,不需要立即写回到主存储,减少了写操作的开销。
  2. 减少主存储的写操作
    • 通过减少主存储的写操作次数,降低了系统负载,提高了整体性能。
  3. 适合高并发场景
    • 适用于高并发写操作的场景,能够有效提高系统的吞吐量。

缺点:

  1. 数据一致性问题
    • 缓存中的数据和主存储中的数据可能存在不一致,需要在数据替换时进行同步。
  2. 复杂性增加
    • 需要管理缓存中的“脏”数据,增加了系统的复杂性。
  3. 故障恢复困难
    • 如果缓存发生故障,未写回主存储的“脏”数据可能会丢失,影响数据的完整性。

4. 用 Java 模拟使用 Write Back 策略

下面是一个简单的 Java 示例,模拟使用 Write Back 策略的缓存系统。

缓存类
import java.util.HashMap;
import java.util.Map;public class WriteBackCache<K, V> {private final Map<K, CacheEntry<V>> cache;private final Map<K, V> mainStorage;public WriteBackCache() {this.cache = new HashMap<>();this.mainStorage = new HashMap<>();}public V get(K key) {CacheEntry<V> entry = cache.get(key);if (entry != null && !entry.isDirty()) {return entry.getValue();} else {V value = mainStorage.get(key);if (value != null) {cache.put(key, new CacheEntry<>(value, false));}return value;}}public void put(K key, V value) {cache.put(key, new CacheEntry<>(value, true));}public void evict(K key) {CacheEntry<V> entry = cache.remove(key);if (entry != null && entry.isDirty()) {mainStorage.put(key, entry.getValue());}}private static class CacheEntry<V> {private final V value;private boolean dirty;public CacheEntry(V value, boolean dirty) {this.value = value;this.dirty = dirty;}public V getValue() {return value;}public boolean isDirty() {return dirty;}public void setDirty(boolean dirty) {this.dirty = dirty;}}
}
测试类
public class WriteBackCacheTest {public static void main(String[] args) {WriteBackCache<String, String> cache = new WriteBackCache<>();// 初始数据cache.put("key1", "value1");cache.put("key2", "value2");// 读取数据System.out.println("Read key1: " + cache.get("key1")); // value1System.out.println("Read key2: " + cache.get("key2")); // value2// 修改数据cache.put("key1", "new_value1");System.out.println("Read key1 after update: " + cache.get("key1")); // new_value1// 替换数据cache.evict("key1");System.out.println("Read key1 after eviction: " + cache.get("key1")); // null// 重新读取数据System.out.println("Read key2: " + cache.get("key2")); // value2}
}
  1. 缓存类 WriteBackCache

    • 使用 HashMap 存储缓存数据和主存储数据。
    • CacheEntry 类用于存储缓存条目,包含数据值和脏标志。
    • get 方法从缓存或主存储中读取数据。
    • put 方法在缓存中更新数据,并标记为脏。
    • evict 方法在缓存中移除数据,如果数据是脏的,则写回到主存储。
  2. 测试类 WriteBackCacheTest

    • 初始化缓存并插入一些数据。
    • 读取和修改数据。
    • 替换数据并验证数据是否正确写回到主存储。

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

1小时构建Vue3知识体系-Vue的响应式,让数据动起来

本文转载自&#xff1a;https://fangcaicoding.cn/course/12/62 大家好&#xff01;我是方才&#xff0c;目前是8人后端研发团队的负责人&#xff0c;拥有6年后端经验&3年团队管理经验。 系统学习践行者&#xff01;近期在系统化输出前端入门相关技术文章&#xff0c;期望能…

Docker网络详解

安装Docker时&#xff0c;它会自动创建三个网络&#xff0c;bridge&#xff08;创建容器默认连接到此网络&#xff09;、 none 、host 网络模式简介Host容器将不会虚拟出自己的网卡&#xff0c;配置自己的IP等&#xff0c;而是使用宿主机的IP和端口。Bridge此模式会为每一个容…

宝塔面板部署前端项目(包含ssl证书部署)

环境&#xff1a; ①nginx&#xff08;这里使用的版本为1.21.41&#xff09; ②前端项目文件&#xff08;以根目录打包的文件&#xff09; ③域名 ④SLL数字证书的key文件和.pem文件&#xff08;我们这里用的是nginx部署&#xff0c;因此下载证书的时候&#xff0c;下载nginx对…

【区别】ONLYOFFICE心得体会,8.2与8.1区别

本站以分享各种运维经验和运维所需要的技能为主 《python零基础入门》&#xff1a;python零基础入门学习 《python运维脚本》&#xff1a; python运维脚本实践 《shell》&#xff1a;shell学习 《terraform》持续更新中&#xff1a;terraform_Aws学习零基础入门到最佳实战 《k8…

Equity-Transformer:求解NP-Hard Min-Max路由问题的顺序生成算法(AAAI-24)(未完)

文章目录 AbstractIntroduction问题表述MethodologyAbstract 最小最大路由问题旨在通过智能体合作完成任务来最小化多个智能体中最长行程的长度。这些问题包括对现实世界有重大影响的应用场景,但已知属于NP-hard问题。现有方法在大规模问题上面临挑战,尤其是在需要协调大量智…

ScrumMaster认证机构及CSM、PSM、RSM价值解析

近十年Scrum在国内备受关注&#xff0c;成为一种最流行的现代敏捷工作方式。ScrumMaster这一独特的角色&#xff0c;在企业内部推动Scrum落地的过程中越来越重要。各种ScrumMaster认证课程也蜂拥而至&#xff0c;甚至鱼目混珠。 我们为大家梳理了目前市面上出现的ScrumMaster认…

HLS实现图像二值化

最近在学习HLS语言&#xff0c;所以就自己摸索尝试了用HLS实现了图像二值化&#xff0c;把这个内容总结一下&#xff0c;分享出来。 首先打开HLS&#xff0c;然后新建一个Project&#xff0c;之后再在Source栏点击右键&#xff0c;选择New File...&#xff0c;创建名为pixelBi…

[ 内网渗透实战篇-1 ] 单域环境搭建与安装域环境判断域控定位CS插件装载CS上线

&#x1f36c; 博主介绍 &#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 _PowerShell &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 &#x1f389;点赞➕评论➕收藏 养成习…

通过物流分拣系统来理解RabbitMQ的消息机制

RabbitMQ作为一个消息中间件&#xff0c;通过队列和路由机制&#xff0c;帮助应用程序高效传递消息。而它的消息流转过程&#xff0c;其实可以用物流分拣系统来直观理解。 在一个典型的物流分拣系统中&#xff0c;包裹会经过多个节点&#xff08;比如分拣中心、配送站&#xf…

别再乱搜了 这 5个宝藏AE模板网站,小白也能做出大片级动画

Hello&#xff0c;大家好&#xff0c;我是后期圈&#xff01; 今天来聊聊一个后期人都绕不开的话题&#xff1a;AE模板网站&#xff01;模板可是后期人的福音&#xff0c;无论你是想要惊艳的开场动画&#xff0c;酷炫的转场效果&#xff0c;还是个性化的文字特效&#xff0c;一…

CSS 编写位置详解及优先级分析

在前端开发中,CSS 的编写位置对项目的组织结构和维护性至关重要。不同的编写位置不仅影响代码的可读性和复用性,还决定了样式应用的优先级。 本文将根据编写位置的不同,详细介绍其定义、使用场景和优先级。 行内样式(Inline Styles) 行内样式(又称:内联样式)是将 CS…

ChatGPT 搜索 vs Google 搜索

原文&#xff1a;Amanda Caswell - 2024.11.01 随着 OpenAI 推出的实时搜索功能&#xff0c;ChatGPT 正在逐步成为像 Google 这样的传统搜索引擎的竞争对手。ChatGPT 以其对话式的回答方式而闻名&#xff0c;它能够在没有广告干扰的情况下提供实时的上下文信息。 我迫不及待地…

多进程的操作和案例

文章目录 高效编程一、多任务原理二、进程1、概念2、使用进程3、全局变量在多个子进程中不能共享4、启动大量子进程5、map方法6、单进程与多进程复制文件对比7、进程间通信8、进程实现生产者消费者9、案例&#xff08;抓取斗图&#xff09; 高效编程 一、多任务原理 概念 现代…

【更新中】《硬件架构的艺术》笔记(二):时钟与复位

本章主要针对ASIC设计给出建议&#xff0c;独立于CAD工具以及工艺&#xff0c;主要针对模块设计和存储器接口。 同步设计 这是对时钟域控制最安全的方法&#xff0c;单个主时钟和单个主置位/复位信号驱动设计中所有时序器件。 避免使用行波计数器 行波计数器&#xff1a;用…

Spring Boot编程训练系统:架构设计与技术选型

3系统分析 3.1可行性分析 通过对本编程训练系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本编程训练系统采用SSM框架&#xff0c;JAVA作为开发语言&#…

DAY111PHP开发框架THIKNPHP反序列化POP利用链RCE执行文件删除

一、文件删除利用链分析 1、__destruct发现调用$this->removeFiles(); 2、removeFiles();函数方法file_exists&#xff0c;unlink($filename);文件删除功能 3、unserialize(base64_decode($_GET[id])); 有可控变量 4、pop文件删除利用链的使用 只有在这个类中调用 Files可…

如何使用亿图脑图MindMaster大纲功能

亿图脑图MindMaster作为一款出色的思维导图软件&#xff0c;具备丰富的编辑和展示功能。就拿大纲模式而言&#xff0c;用户可以清晰地浏览思维导图上的内容。因为大纲功能可以将思维导图上的内容以文档归纳的形式呈现出来&#xff0c;便于用户分类记忆。 自由切换思维导图模式…

Python的Eval函数执行结果和Lua脚本中LuaFunction的执行结果有何异同

最近在维护一个项目的时候&#xff0c;同时用到了Python和Lua两种脚本语言&#xff0c;发现很多有意思的东西&#xff0c;比如Python的Eval函数和Lua的LuaFunction函数&#xff0c;他们都是返回目标函数的句柄&#xff0c;那么在用法和机制上又有什么不同呢&#xff1f;为了全面…

DQN强化训练agent玩是男人就下xx层小游戏

游戏代码参考Python是男人就下一百层小游戏源代码_是男人就下一百层完整代码python-CSDN博客 在游戏作者代码基础上修改了下使该游戏在失败后能自动重新开始&#xff0c;方便后续能不间断训练 def reset_game(self):self.score 0self.end Falseself.last 6 * SIDEself.dire …

2024最新版JavaScript逆向爬虫教程-------基础篇之面向对象

目录 一、概念二、对象的创建和操作 2.1 JavaScript创建对象的方式2.2 对象属性操作的控制2.3 理解JavaScript创建对象 2.3.1 工厂模式2.3.2 构造函数2.3.3 原型构造函数 三、继承 3.1 通过原型链实现继承3.2 借用构造函数实现继承3.3 寄生组合式继承 3.3.1 对象的原型式继承…