实战Redis与MySQL双写一致性的缓存模式

​Redis和MySQL都是常用的数据存储系统,它们各自有自己的优缺点。在实际应用中,我们可能需要将它们结合起来使用,比如将Redis作为缓存,MySQL作为持久化存储。

在这种情况下,我们需要保证Redis和MySQL的数据一致性,也就是当数据在Redis中进行修改时,也要相应地在MySQL中进行修改,反之亦然。


Cache-Aside Pattern

Cache-Aside Pattern(也称为 Lazy-Loading 缓存模式)是一种常见的缓存设计模式,用于在应用程序中手动管理缓存数据。在这种模式下,应用程序负责在需要的时候将数据加载到缓存中,以便提高数据的访问速度和性能。

Cache-Aside 模式的工作流程如下:

1. 读取数据

当应用程序需要读取数据时,它首先会检查缓存中是否存在所需数据。如果数据存在于缓存中,应用程序直接从缓存中获取数据。如果数据不在缓存中,应用程序会从主数据源(如数据库)中获取数据,并将数据加载到缓存中。

2. 写入数据

当应用程序执行写操作(如创建、更新、删除)时,它首先会更新主数据源中的数据。然后,应用程序手动更新或使缓存中的相关数据失效,以确保缓存中的数据保持与主数据源一致。

3. 缓存失效

在 Cache-Aside 模式中,缓存失效是由应用程序来管理的。这意味着应用程序需要根据数据的更新频率和业务需求,手动决定何时使缓存数据失效,以便在下次访问时重新加载最新的数据。

4.代码示例

基于Spring Cloud的Cache-Aside Pattern缓存模式可以通过Spring框架的缓存抽象和Spring Cloud的服务组件来实现。在这种模式下,应用程序负责手动地管理缓存数据的加载和失效。以下是一个基于Spring Cloud的Cache-Aside Pattern缓存模式的伪代码示例:

  • 定义缓存配置和服务

首先,需要定义一个缓存配置类和一个缓存服务类来管理缓存和数据读写操作。

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@EnableCaching
public class CacheConfig {@Beanpublic CacheManager cacheManager() {return new ConcurrentMapCacheManager("myCache"); // 创建一个名为 "myCache" 的缓存}
}@Service
public class CacheService {private final Cache cache;public CacheService(CacheManager cacheManager) {this.cache = cacheManager.getCache("myCache"); // 获取名为 "myCache" 的缓存}public Object getDataFromCache(String key) {Cache.ValueWrapper valueWrapper = cache.get(key);if (valueWrapper != null) {return valueWrapper.get();}return null;}public void putDataInCache(String key, Object data) {cache.put(key, data); // 将数据加载到缓存中}public void invalidateCache(String key) {cache.evict(key); // 使缓存中的数据失效}
}
  • 使用缓存服务

业务逻辑中,可以使用缓存服务来读取和写入数据。

@Service
public class BusinessService {private final DataService dataService;private final CacheService cacheService;@Autowiredpublic BusinessService(DataService dataService, CacheService cacheService) {this.dataService = dataService;this.cacheService = cacheService;}public Object fetchData(String key) {Object cachedData = cacheService.getDataFromCache(key);if (cachedData != null) {return cachedData;} else {Object newData = dataService.fetchDataFromDataSource(key);cacheService.putDataInCache(key, newData);return newData;}}public void updateData(String key, Object newData) {dataService.updateDataSource(key, newData); // 更新主数据源cacheService.invalidateCache(key); // 使缓存中的数据失效}
}
  • 使用示例:

可以通过业务服务来读取和更新数据。

@RestController
public class MyController {private final BusinessService businessService;@Autowiredpublic MyController(BusinessService businessService) {this.businessService = businessService;}@GetMapping("/data/{key}")public Object getData(@PathVariable String key) {return businessService.fetchData(key); // 从缓存或数据源获取数据}@PostMapping("/data/{key}")public void updateData(@PathVariable String key, @RequestBody Object newData) {businessService.updateData(key, newData); // 更新数据并使缓存失效}
}

在这个示例中,我们使用了Spring框架的缓存注解和缓存管理器来实现Cache-Aside Pattern。通过CacheService来操作缓存数据的读写,通过BusinessService来处理业务逻辑,保证从缓存读取数据或将数据加载到缓存时的一致性。


Read-Through/Write through

Read-Through和Write-Through是两种常见的缓存模式,用于更有效地管理缓存中的数据读取和写入操作。它们分别用于在数据被读取和写入时自动操作缓存和主数据源。下面我将详细介绍这两种缓存模式,并提供基于Spring的伪代码示例。

Read-Through缓存模式

在Read-Through缓存模式中,当应用程序尝试读取缓存中的数据时,如果缓存中不存在该数据,会自动从主数据源(如数据库)中读取数据,并将数据加载到缓存中,以便下次读取时能够直接从缓存中获取。

工作流程:

  1. 应用程序尝试从缓存读取数据。

  2. 如果缓存中存在数据,应用程序直接从缓存中获取。

  3. 如果缓存中不存在数据,应用程序从主数据源中读取数据,并将数据加载到缓存中。

Write-Through缓存模式

在Write-Through缓存模式中,当应用程序执行写操作时,数据会首先被写入缓存,然后自动同步更新到主数据源(如数据库)中,以保持数据的一致性。

工作流程:

  1. 应用程序执行写操作,将数据写入缓存。

  2. 缓存自动将写入的数据同步更新到主数据源中。

代码示例

基于Spring Cloud的Read-Through和Write-Through缓存模式可以通过Spring框架的缓存抽象和Spring Cloud的服务组件来实现。这两种模式是更为自动化的缓存管理方法,它们分别处理数据的读取和写入操作,无需应用程序手动介入。以下是基于Spring Cloud的伪代码示例:

Read-Through缓存模式示例

  • 定义缓存配置和服务:

首先,需要定义一个缓存配置类和一个数据服务类,用于管理缓存和数据读取操作。

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@EnableCaching
public class CacheConfig {@Beanpublic CacheManager cacheManager() {return new ConcurrentMapCacheManager("myCache"); // 创建一个名为 "myCache" 的缓存}
}@Service
public class DataService {@Autowiredprivate DataRepository dataRepository; // 假设有一个数据仓库@Cacheable(value = "myCache", key = "#key")public Data getData(String key) {return dataRepository.findById(key).orElse(null);}
}
  • 使用缓存服务:

在业务逻辑中,可以使用缓存服务来读取数据。

@RestController
public class MyController {private final DataService dataService;@Autowiredpublic MyController(DataService dataService) {this.dataService = dataService;}@GetMapping("/data/{key}")public Data getData(@PathVariable String key) {return dataService.getData(key); // 从缓存或数据仓库获取数据}
}

Write-Through缓存模式示例

  • 定义缓存配置和服务:

同样,你需要定义一个缓存配置类和一个数据服务类,用于管理缓存和数据写入操作。

@Configuration
@EnableCaching
public class CacheConfig {@Beanpublic CacheManager cacheManager() {return new ConcurrentMapCacheManager("myCache"); // 创建一个名为 "myCache" 的缓存}
}@Service
public class DataService {@Autowiredprivate DataRepository dataRepository; // 假设有一个数据仓库@CachePut(value = "myCache", key = "#data.key")public Data updateData(Data data) {dataRepository.save(data); // 更新数据到数据仓库return data;}
}
  • 使用缓存服务:

可以使用缓存服务来写入数据。

@RestController
public class MyController {private final DataService dataService;@Autowiredpublic MyController(DataService dataService) {this.dataService = dataService;}@PostMapping("/data")public Data updateData(@RequestBody Data newData) {return dataService.updateData(newData); // 写入数据到缓存和数据仓库}
}

在这些示例中,@Cacheable@CachePut注解用于实现Read-Through和Write-Through缓存模式。DataService类负责在数据读取和写入时处理缓存和主数据源之间的同步。


Write behind

Write-Behind缓存模式是一种缓存设计模式,它将写入操作先缓存起来,然后在合适的时机异步地将数据写入主数据源(例如数据库)。这种模式可以提高写入操作的性能和响应时间,同时通过异步写入减少主数据源的负载。

工作原理

  1. 当应用程序执行写入操作时,数据首先会被写入缓存,然后标记为"脏数据"。
  2. 后台异步线程定期或在特定事件触发时,将"脏数据"批量写入主数据源。

这种模式在需要频繁写入操作的场景中特别有用,因为它将写入操作进行了批处理,减少了与主数据源的交互次数,从而提高了性能。

Write-Behind缓存模式的优点

  • 提高写入操作的性能:写入操作首先在缓存中完成,减少了对主数据源的直接写入次数,从而提高了写入性能。
  • 减轻主数据源负载:异步写入减少了主数据源的负载,特别是在高并发的情况下。
  • 高吞吐量:通过批量写入的方式,可以提高系统的吞吐量。

代码示例

基于Spring Cloud的Write-Behind缓存模式可以使用Spring框架的缓存抽象和Spring Cloud的服务组件来实现。这种模式可以提高写入操作的性能和响应时间,同时通过异步写入减少主数据源的负载。以下是基于Spring Cloud的Write-Behind缓存模式的伪代码示例:

  • 定义缓存配置和服务:

首先,需要定义一个缓存配置类和一个缓存服务类,用于管理缓存和数据写入操作。

import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;@Configuration
@EnableCaching
@EnableAsync
public class CacheConfig {@Beanpublic CacheManager cacheManager() {return new ConcurrentMapCacheManager("myCache"); // 创建一个名为 "myCache" 的缓存}@Beanpublic ThreadPoolTaskExecutor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(25);return executor;}
}@Service
public class CacheService {@Autowiredprivate DataRepository dataRepository;@CachePut(value = "myCache", key = "#data.key")@Asyncpublic void writeBehind(Data data) {// 异步将数据写入主数据源writeDataToDataSource(data);}private void writeDataToDataSource(Data data) {dataRepository.save(data); // 写入数据到主数据源}
}
  • 使用缓存服务:

在业务逻辑中,可以使用缓存服务来写入数据。

@RestController
public class MyController {private final CacheService cacheService;@Autowiredpublic MyController(CacheService cacheService) {this.cacheService = cacheService;}@PostMapping("/data")public void writeData(@RequestBody Data newData) {cacheService.writeBehind(newData); // 异步写入数据到缓存和主数据源}
}

在这个示例中,我们使用了Spring框架的@CachePut注解和异步任务来实现Write-Behind缓存模式。CacheService负责在数据写入缓存的同时,异步地将数据写入主数据源。这样可以提高写入性能,并减轻主数据源的负载。

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

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

相关文章

微信支付的委托代扣功能服务如何申请开通?

扣款服务(原委托代扣服务,以下均用委托代扣)是微信支付旗下的重要产品 1、委托代扣是指商户取得用户的扣款授权后,向微信支付发起从用户账户扣款至商户账户的扣款指令,微信支付无需验证用户的支付密码,即可…

记录一下,Vcenter清理/storage/archive空间

一、根因 vpostgres:这个目录可能包含与 vCenter Server 使用的 PostgreSQL 数据库相关的归档文件过多,导致空间被占用。 二、处理过程 1、SSH登陆到Vcenter. 2、df -Th **图中可以看到 /storage/archive 使用占比很高。 /storage/archive 目录通常用…

fiddler抓包06_抓取https请求(chrome)

课程大纲 首次安装Fiddler,抓https请求,除打开抓包功能(F12)还需要: ① Fiddler开启https抓包 ② Fiddler导出证书; ③ 浏览器导入证书。 否则,无法访问https网站(如下图&#xff0…

Qt优秀开源项目之二十三:QSimpleUpdater

QSimpleUpdater是开源的自动升级模块,用于检测、下载和安装更新。 github地址:https://github.com/alex-spataru/QSimpleUpdater QSimpleUpdater目前Star不多(911个),但已在很多开源项目看到其身影,比如Not…

web网站的任意文件上传下载漏洞解析

免责申明 本文仅是用于学习检测自己搭建的任意文件上传下载漏洞相关原理,请勿用在非法途径上,若将其用于非法目的,所造成的一切后果由您自行承担,产生的一切风险和后果与笔者无关;本文开始前请认真详细学习《‌中华人民共和国网络安全法》‌及其所在国家地区相关法规内容【…

【D3.js in Action 3 精译_023】3.3 使用 D3 将数据绑定到 DOM 元素

当前内容所在位置: 第一部分 D3.js 基础知识 第一章 D3.js 简介(已完结) 1.1 何为 D3.js?1.2 D3 生态系统——入门须知1.3 数据可视化最佳实践(上)1.3 数据可视化最佳实践(下)1.4 本…

Three.js 3D人物漫游项目(中)

本文目录 前言最终效果展示1、人物添加阴影1.1 添加地板1.1.1 效果 1.2 模型castShadow1.2.1 效果 1.3 轨道控制器1.3.1 效果 2、创建建筑物2.1 代码2.2 效果 前言 在数字技术的浪潮中,三维图形渲染技术以其独特的魅力,正逐步渗透到我们生活的方方面面&a…

手机、平板电脑编程———未来之窗行业应用跨平台架构

一、平板编程优点 1. 便携性强 - 可以随时随地携带平板进行编程,不受地点限制,方便在旅行、出差或休息时间进行学习和开发。 2. 直观的触摸操作 - 利用触摸屏幕进行代码编辑、缩放、拖动等操作,提供了一种直观和自然的交互方式。 …

联想(lenovo) 小新Pro13锐龙版(新机整理、查看硬件配置和系统版本、无线网络问题、windows可选功能)

新机整理 小新pro13win10新机整理 查看硬件配置和系统版本 设置-》系统-》系统信息 无线网络问题 部分热点可以,部分不可以 问题:是因为自己修改了WLAN的IP分配方式为手动分配,导致只能在连接家里无线网的时候可以,连接其他…

Unity 高亮插件HighlightPlus介绍

主要是对官方文档进行了翻译(我做了一些补充和一些小的调整) 但是如果你只是想快速入门: Unity 高亮插件Highlight Plus快速入门-CSDN博客 注意:官方文档本身就落后实际,但对入门仍很有帮助,核心并没有较大改变,有的功能有差异,以实际为准.(目前我已校正了大部分差异,后续我…

vue3 自定义el-tree树形结构样式

这里样式设置主要用到了 windcss 实现效果 模拟数据 这里也可以用模拟的数据,下面用的是后端请求的真实数据 [{"id": 5,"rule_id": 0,"status": 1,"create_time": "2019-08-11 13:36:09","update_time": "…

微信小程序拨打电话点取消报错“errMsg“:“makePhoneCall:fail cancel“

问题:微信小程序中拨打电话点取消,控制台报错"errMsg":"makePhoneCall:fail cancel" 解决方法:在后面加上catch就可以解决这个报错 wx.makePhoneCall({phoneNumber: 181********}).catch((e) > {console.log(e) //用…

金钥匙系列:Kubernetes (K8s) 服务集群技术栈学习路线

维护Kubernetes (K8s) 服务集群是一个复杂且多层次的技术任务,涉及容器化技术、集群管理、网络、安全、监控等多个领域。为了成为一名优秀的K8s集群维护工程师,技术栈需要广泛且深入。本文将为你详细介绍从零开始到深入掌握K8s集群维护的职业技术栈学习路…

在MAC中Ollama开放其他电脑访问

ollama安装完毕后默认只能在本地访问,之前我都是安装其他的软件之后可以结合开放其他端口访问,其实是可以新增或修改下电脑的系统配置,就可以打开端口允许除本机IP或localhost访问。 步骤如下: 1、查看端口(默认是&…

使用 Anaconda 环境在Jupyter和PyCharm 中进行开发

目录 前言 一、在特定环境中使用jupyter 1. 列出所有环境 2. 激活环境 3. 进入 Jupyter Notebook 二、在特定环境中使用pycham 1. 打开 PyCharm 2. 打开设置 3. 配置项目解释器 4. 选择 Conda 环境 5. 应用设置 6. 安装所需库(如果需要) 总结 &#x1f3…

大模型爬虫—ScrapeGraphAI

大模型爬虫—ScrapeGraphAI 一、介绍 ScrapeGraphAI是一个网络爬虫 Python 库,使用大型语言模型和直接图逻辑为网站和本地文档(XML,HTML,JSON 等)创建爬取管道。 只需告诉库您想提取哪些信息,它将为您完成! scrapegraphai有三种主要的爬取管道可用于从网站(或本地文…

统信服务器操作系统【搭建FTP】设置介绍

如何在操作系统上安装vsftp服务。设置匿名用户登录、设置授权用户密码访问功能,并介绍使用匿名方式、授权用户方式访问vsftp服务。本文适用于A、D、E三个服务器操作系统版本,除安装方式的差异,其他设置均相同。 文章目录 功能概述一、功能介绍二、准备环境三、安装步骤1. 在…

(undone) 学习语音学中关于 i-vector 和 x-vector

来源:https://ieeexplore.ieee.org/stamp/stamp.jsp?tp&arnumber8461375 (这是一篇跟 X-vector 有关的论文) 这里有更适合初学者的两个资料: 1.https://www.youtube.com/watch?vR3rzN6JYm38 (MIT教授的youtube视频) 2.https://people.c…

linux 基础(一)mkdir、ls、vi、ifconfig

1、linux简介 linux是一个操作系统(os: operating system) 中国有没有自己的操作系统(华为鸿蒙HarmonyOS,阿里龙蜥(Anolis) OS 8、百度DuerOS都有) 计算机组的组成:硬件软件 硬件:运算器&am…

数据结构和算法之树形结构(1)

文章出处: 数据结构和算法之树形结构(1) 关注码农爱刷题,看更多技术文章!! 树形结构是数据结构四种逻辑结构之一,也是被广泛使用的一种逻辑结构,它描述的是数据元素之间一对多的逻辑关系。树是一种非线性的数据结构&a…