【Java】在高并发场景下,保证 Redis 缓存一致性的几种方案

在高并发场景下,保证 Redis 缓存一致性是一个常见的挑战。以下是几种常见的解决方案及其优缺点,以及相应的代码示例。

1. Cache Aside Pattern (旁路缓存模式)

原理
  • 读取数据时,先读缓存,如果缓存没有命中,再从数据库读取,并将数据写入缓存。
  • 更新数据时,先更新数据库,然后删除缓存。
优点
  • 简单易实现,适用于读多写少的场景。
  • 更新时立即删除缓存,能有效防止缓存数据不一致。
缺点
  • 存在短暂的不一致性窗口期。
  • 并发更新时可能导致缓存被频繁删除。
代码示例
public class CacheAsidePattern {private RedisTemplate<String, Object> redisTemplate;private DatabaseService databaseService;public CacheAsidePattern(RedisTemplate<String, Object> redisTemplate, DatabaseService databaseService) {this.redisTemplate = redisTemplate;this.databaseService = databaseService;}public Object get(String key) {Object value = redisTemplate.opsForValue().get(key);if (value == null) {synchronized (this) {value = redisTemplate.opsForValue().get(key);if (value == null) {value = databaseService.getFromDb(key);if (value != null) {redisTemplate.opsForValue().set(key, value);}}}}return value;}public void update(String key, Object value) {databaseService.updateDb(key, value);redisTemplate.delete(key);}
}

2. Read-Through Cache (读穿缓存)

原理
  • 读取数据时,如果缓存未命中,由缓存系统从数据库加载数据,并将其缓存。
优点
  • 自动加载数据到缓存,简化应用程序代码。
  • 减少缓存未命中带来的性能损失。
缺点
  • 实现复杂,需要自定义缓存加载逻辑。
  • 写操作没有明确处理,需结合其他策略保证一致性。
代码示例
public class ReadThroughCache {private RedisTemplate<String, Object> redisTemplate;private DatabaseService databaseService;public ReadThroughCache(RedisTemplate<String, Object> redisTemplate, DatabaseService databaseService) {this.redisTemplate = redisTemplate;this.databaseService = databaseService;}public Object get(String key) {Object value = redisTemplate.opsForValue().get(key);if (value == null) {value = databaseService.getFromDb(key);if (value != null) {redisTemplate.opsForValue().set(key, value);}}return value;}
}

3. Write-Through Cache (写穿缓存)

原理
  • 更新数据时,先更新缓存,再更新数据库。
优点
  • 数据始终保持一致性,适合高一致性要求的场景。
  • 简化读取逻辑,数据始终在缓存中。
缺点
  • 写操作性能较低,因为每次写操作都涉及数据库更新。
  • 如果数据库更新失败,缓存也会被污染。
代码示例
public class WriteThroughCache {private RedisTemplate<String, Object> redisTemplate;private DatabaseService databaseService;public WriteThroughCache(RedisTemplate<String, Object> redisTemplate, DatabaseService databaseService) {this.redisTemplate = redisTemplate;this.databaseService = databaseService;}public Object get(String key) {return redisTemplate.opsForValue().get(key);}public void update(String key, Object value) {redisTemplate.opsForValue().set(key, value);databaseService.updateDb(key, value);}
}

4. Write-Behind Cache (异步写缓存)

原理
  • 更新数据时,先更新缓存,然后异步地将数据写入数据库。
优点
  • 写操作性能较高,适用于写多读少的场景。
  • 减少了直接写数据库的延迟。
缺点
  • 实现复杂,需保证异步操作的可靠性。
  • 存在数据丢失的风险,需要处理异步操作失败的情况。
代码示例
public class WriteBehindCache {private RedisTemplate<String, Object> redisTemplate;private DatabaseService databaseService;private ExecutorService executorService;public WriteBehindCache(RedisTemplate<String, Object> redisTemplate, DatabaseService databaseService) {this.redisTemplate = redisTemplate;this.databaseService = databaseService;this.executorService = Executors.newFixedThreadPool(10);}public Object get(String key) {return redisTemplate.opsForValue().get(key);}public void update(String key, Object value) {redisTemplate.opsForValue().set(key, value);executorService.submit(() -> {databaseService.updateDb(key, value);});}
}

5. Consistent Hashing (一致性哈希)

原理
  • 通过一致性哈希算法,将缓存数据均匀分布到不同的缓存节点上。
优点
  • 提高缓存的可扩展性和容错性。
  • 数据分布均匀,减少单点压力。
缺点
  • 实现复杂,需要引入一致性哈希算法。
  • 适用于分布式缓存场景,对于单机缓存无显著优势。
代码示例
import java.util.SortedMap;
import java.util.TreeMap;public class ConsistentHashing {private TreeMap<Integer, RedisTemplate<String, Object>> hashRing = new TreeMap<>();private int numberOfReplicas;public ConsistentHashing(int numberOfReplicas, List<RedisTemplate<String, Object>> redisTemplates) {this.numberOfReplicas = numberOfReplicas;for (RedisTemplate<String, Object> redisTemplate : redisTemplates) {addNode(redisTemplate);}}private void addNode(RedisTemplate<String, Object> node) {for (int i = 0; i < numberOfReplicas; i++) {int hash = hash(node.toString() + i);hashRing.put(hash, node);}}public RedisTemplate<String, Object> getNode(String key) {if (hashRing.isEmpty()) {return null;}int hash = hash(key);if (!hashRing.containsKey(hash)) {SortedMap<Integer, RedisTemplate<String, Object>> tailMap = hashRing.tailMap(hash);hash = tailMap.isEmpty() ? hashRing.firstKey() : tailMap.firstKey();}return hashRing.get(hash);}private int hash(String key) {return key.hashCode() & 0x7fffffff;}
}

每种策略都有其适用的场景和特点,具体选择哪种方案需要根据实际的业务需求和系统特性来决定。

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

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

相关文章

SwiftUI 5.0(iOS 17)进一步定制 TipKit 外观让撸码如虎添翼

概览 在之前 SwiftUI 5.0&#xff08;iOS 17&#xff09;TipKit 让用户更懂你的 App 这篇博文里&#xff0c;我们已经初步介绍过了 TipKit 的基本知识。 现在&#xff0c;让我们来看看如何进一步利用 SwiftUI 对 TipKit 提供的细粒度外观定制技巧&#xff0c;让 Tip 更加“明眸…

蓝桥杯第十四届国赛B组刷题笔记

A-0子2023&#xff1a; 题目&#xff1a; 小蓝在黑板上连续写下从 11 到 20232023 之间所有的整数&#xff0c;得到了一个数字序列&#xff1a; &#x1d446;12345678910111213...20222023S12345678910111213...20222023。 小蓝想知道 &#x1d446;S 中有多少种子序列恰好等…

邦芒简历:简历自检指南,让你的求职之路更顺畅

当你精心完成一份简历后&#xff0c;是否曾想过再仔细审视一遍&#xff1f;一份完美的简历不仅是求职的敲门砖&#xff0c;更是展示你专业素养和个人魅力的窗口。为了让你在求职过程中脱颖而出&#xff0c;我们为你提供以下自检指南&#xff0c;帮助你完善简历&#xff0c;提高…

用Python爬取百度搜索结果并保存

项目目标 爬取百度上关键字为“粮食”的搜索结果&#xff0c;并保存&#xff0c;提交给客户&#xff0c;用于进一步分析我国粮食政策。 项目准备 软件&#xff1a;PyCharm 需要的库&#xff1a;json&#xff0c; requests&#xff0c;etree 项目分析 1&#xff09;如何进行…

人工智能应用层岗位—AI项目经理/AI产品经理

AI是一门技术&#xff0c;最终落实成产品才能具备商业价值 应用层&#xff0c;就是面向特定应用场景&#xff0c;形成人工智能软硬件产品或解决方案。主要包括行业AI解决方案和热门产品&#xff0c;如自动驾驶、机器人、智能家居、可穿戴的智能设备等 相应的&#xff0c;就会…

【算法】排序

排序算法在信息学非常常用。Hello&#xff01;大家好&#xff0c;我是学霸小羊&#xff0c;今天讲几个排序算法。 1.“打擂台”排序 思路&#xff1a;a[ i ]和a[ j ]打擂台&#xff08;i<j&#xff09;。 这个方法简单易懂&#xff0c;只需要看看需不需要交换。按从大到小…

element ui 的el-input输入一个字后失去焦点,需重新点击输入框才能再次输入!

解决方案&#xff1a; 我是form表单嵌套表格&#xff0c;里面的el-input输入框&#xff0c;输入第一个值的时候会突然失去焦点&#xff0c;需要再次点击输入框才能正常输入&#xff0c;原因是table的key值&#xff0c;需要改成正常的index即可&#xff0c;如果你是循环的&…

阿里云物联网平台python ADK 发布/订阅

基础知识学习参考&#xff1a; 1、使用消息通讯Topic 2、python link SDK 一、环境变量配置 1、python3.6&#xff1a;下载安装 2、安装paho-mqtt 1.4.0版本 pip install paho-mqtt1.4.03、安装安装Link SDK最新版本 pip install aliyun-iot-linkkit 4、下载python ADK…

elementui table 回显的时候勾选状态消失 分页切换的时候table的选中状态会被重置

<el-table v-loading"loading2" ref"multipleTable" :data"reportList" sort-change"handleReportSortChange" selection-change"handleReportSelectionChange">回显代码getReportList(){ //table列表的值this.loadin…

python-编写函数判断一个三位数是否为水仙花数。

【问题描述】要求编写函数isflower(n)判断一个三位数n是否为水仙花数,如果是&#xff0c;则返回True&#xff0c;否则返回False。在主程序中要求调用该函数并输出三位数中所有的水仙花数。所谓"水仙花数"是指一个3位数&#xff0c;其各位数字立方和等于该数本身。例如…

VirtualBox安装ubuntu22.04记录

一,VirtualBox 软件安装 虚拟机&#xff08;Virtual Machine&#xff09;指通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。在实体计算机中能够完成的工作在虚拟机中都能够实现。 常见的虚拟机软件主要有两款 VMware 和 VirtualBox 。VMwar…

Redis主从哨兵架构的故障转移

Redis主从哨兵架构的故障转移是一个确保系统高可用性的重要过程。以下是该过程的主要步骤和关键信息&#xff1a; 1. 哨兵监控与检测 主服务器失效检测&#xff1a;哨兵节点通过定期&#xff08;如每秒&#xff09;向主服务器发送PING命令来检测其是否可连接。如果主服务器在…

【最新区块链论文录用资讯】CCF A—FSE 2024 共4篇 附pdf

Conference&#xff1a;ACM International Conference on the Foundations of Software Engineering (FSE) CCF level&#xff1a;CCF A Categories&#xff1a;软件工程/系统软件/程序设计语言 Year&#xff1a;2024 Num&#xff1a;4 1 Title: Demystifying Invariant …

华纳云:在一个服务器上如何设置多个IP地址?

在一个服务器上设置多个IP地址的具体步骤取决于所使用的操作系统(例如Linux或Windows)。以下是如何在这两个常见操作系统上配置多个IP地址的简要指南&#xff1a; 在Linux上设置多个IP地址 1. 修改网络配置文件 以CentOS/RHEL为例&#xff0c;编辑网络接口配置文件。假设我们要…

项目启动 | 晟泰克再度牵手盘古信息,引入IMS V6系统实现数字化深度推进

当前&#xff0c;中国汽车零部件行业的数字化转型正在快速推进&#xff0c;数字化工业软件已经广泛应用于汽车零部件的研发、生产和服务等各个环节&#xff0c;赋能行业实现降本减存&#xff0c;提质增效&#xff0c;有力推动了行业高质量发展。 成立于2003年的合肥晟泰克汽车…

深度学习之加宽全连接

1.Functional API 搭建神经网络模型 1.1.利用Functional API编写宽深神经网络模型进行手写数字识别 import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.datasets import load_iris from sklearn.model_selection import train_test_spli…

决策树与机器学习实战【代码为主】

文章目录 &#x1f6f4;&#x1f6f4;引言&#x1f6f4;&#x1f6f4;决策树使用案例&#x1f6f4;&#x1f6f4;numpy库生成模拟数据案例&#x1f6f4;&#x1f6f4;决策树回归问题&#x1f6f4;&#x1f6f4;决策树多分类问题 &#x1f6f4;&#x1f6f4;引言 决策树是一种经…

1-Django开端--学生管理系统

目录 项目结构 前端页面: add_data.html class_data.html index.html apps.py models.py views.py settings,py urls.py ...实现简略的身架... 项目结构 前端页面: add_data.html --添加数据. {% extends index/index.html %}{% block content %} <div class&qu…

强化学习,第 2 部分:政策评估和改进

目录 一、介绍 二、关于此文章 三、求解贝尔曼方程 四、策略评估 4.1 更新变体 4.2 例描述 五、策略改进 5.1 V函数描述 5.2 政策改进定理 六、策略迭代 七、值迭代 7.1 算法描述 7.2 异步值迭代 八、广义策略迭代 九、结论 一、介绍 R强化学习是机器学习中的一…

Flask教程5:flask数据库SQLAlchemy

文章目录 SQLAlchemy为什么使用ORM SQLAlchemy SQLAlchemy是一个基于Python实现的ORM (Object Relational Mapping&#xff0c;对象关系映射&#xff09;框架。该框架建立在DB API (数据库应用程序接口系统) 之上&#xff0c;使用关系对象映射进行数据库操作。简言之便是将类和…