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

谷粒商城----缓存与分布式锁

1、缓存使用

为了系统性能的提升,我们一般都会将部分数据放入缓存中,加速访问。而 db 承担数据落盘工作。

哪些数据适合放入缓存?

 即时性、数据一致性要求不高的
 访问量大且更新频率不高的数据(读多,写少)

举例:电商类应用,商品分类,商品列表等适合缓存并加一个失效时间(根据数据更新频率来定),后台如果发布一个商品,买家需要 5 分钟才能看到新的商品一般还是可以接受的

在这里插入图片描述

data = cache.load(id);//从缓存加载数据
If(data == null){
data = db.load(id);//从数据库加载数据
cache.put(id,data);//保存到 cache 中
}
return data;

🚩注意:在开发中,凡是放入缓存中的数据我们都应该指定过期时间,使其可以在系统即使没有主动更新数据也能自动触发数据加载进缓存的流程。避免业务崩溃导致的数据永久不一致问题。

2、springboot整合redis(StringRedisTemplate)

    @AutowiredStringRedisTemplate stringRedisTemplate;@Testpublic void testStringRedisTemplate(){ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();ops.set("hello","world_"+ UUID.randomUUID().toString());String hello = ops.get("hello");System.out.println(hello);}

在这里插入图片描述

3、缓存使用-改造三级分类业务

在这里插入图片描述

缓存穿透,缓存击穿,缓存雪崩

在这里插入图片描述

在这里插入图片描述

4、分布式锁setnx

在这里插入图片描述

🚩优化一:过期时间(解决不释放锁导致死锁问题)

在这里插入图片描述

🚩优化二:过期时间和加锁同步setex+nx(解决加锁原子性问题)

在这里插入图片描述

在这里插入图片描述

🚩优化三:redis+lua脚本解决删锁原子性问题

在这里插入图片描述

    /*** 分布式锁*  lua脚本* @return*/public Map<String, List<Catelog2Vo>> getCatelogJsonFromDBWithRedisLock() {// 1.占分布式锁  设置这个锁10秒自动删除 [原子操作]String uuid = UUID.randomUUID().toString();Boolean lock = stringRedisTemplate.opsForValue().setIfAbsent("lock", uuid, 30, TimeUnit.SECONDS);if (lock) {// 2.设置过期时间加锁成功 获取数据释放锁 [分布式下必须是Lua脚本删锁,不然会因为业务处理时间、网络延迟等等引起数据还没返回锁过期或者返回的过程中过期 然后把别人的锁删了]Map<String, List<Catelog2Vo>> data;try {data = getDataFromDB();} finally {
//			stringRedisTemplate.delete("lock");String lockValue = stringRedisTemplate.opsForValue().get("lock");// 删除也必须是原子操作 Lua脚本操作 删除成功返回1 否则返回0String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";// 原子删锁stringRedisTemplate.execute(new DefaultRedisScript<>(script, Long.class), Arrays.asList("lock"), uuid);}return data;} else {// 重试加锁try {// 登上两百毫秒Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}return getCatelogJsonFromDBWithRedisLock();}}

5、redisson分布式锁

	@ResponseBody@RequestMapping("/index/hello")public String hello() {RLock lock = redissonClient.getLock("my-lock");// 阻塞式等待lock.lock();try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}return "hello";}

在这里插入图片描述
在这里插入图片描述

6、双写一致性与延迟双删

双写一致性

🚩双写一致性的解决方案一:可以在修改数据的方法加锁,就是每次只允许一个线程去修改数据库,这样就保证了Mysql和redis数据的一致性

🚩双写一致性的解决方案二:给redis设置过期时间,过期后就会去Mysql查最新的数据,保证最终数据一致

在这里插入图片描述

失效模式

在这里插入图片描述

延迟双删

延时双删的方案的思路是,为了避免更新数据库的时候,其他线程从缓存中读取不到数据,就在更新完数据库之后,再sleep一段时间,然后再次删除缓存。

sleep的时间要对业务读写缓存的时间做出评估,sleep时间大于读写缓存的时间即可。

流程如下:

1、线程1删除缓存,然后去更新数据库
2、线程2来读缓存,发现缓存已经被删除,所以直接从数据库中读取,这时候由于线程1还没有更新完成,所以读到的是旧值,然后把旧值写入缓存
3、线程1,根据估算的时间,sleep,由于sleep的时间大于线程2读数据+写缓存的时间,所以缓存被再次删除
4、如果还有其他线程来读取缓存的话,就会再次从数据库中读取到最新值
在这里插入图片描述

消息队列

这是网上很多文章里都有写过的方案。但是这个方案的缺陷会更明显一点。

先更新数据库,成功后往消息队列发消息,消费到消息后再删除缓存,借助消息队列的重试机制来实现,达到最终一致性的效果。

在这里插入图片描述

import redis.clients.jedis.Jedis;public class DelayedDoubleDeleteExample {private static final int DELAY_TIME = 1000; // 延迟双删时间,单位:毫秒// 模拟数据库private static String database = "Original Data";// 模拟缓存private static Jedis cache = new Jedis("localhost", 6379);public static void main(String[] args) throws InterruptedException {// 初始化缓存cache.set("key", database);// 更新数据updateDataInDatabase("Updated Data");Thread.sleep(DELAY_TIME); // 等待延迟双删时间// 获取数据String data = getData("key");System.out.println("Data: " + data);}private static void updateDataInDatabase(String newData) {// 先更新数据库database = newData;// 再删除缓存cache.del("key");System.out.println("Cache deleted");}private static String getData(String key) {// 先从缓存读取数据String data = cache.get(key);if (data == null) {// 缓存不存在,从数据库读取最新数据data = database;// 将数据写入缓存cache.set(key, data);System.out.println("Cache updated");}return data;}
}

7、Cannal

在这里插入图片描述

相关文章:

谷粒商城----缓存与分布式锁

1、缓存使用 为了系统性能的提升&#xff0c;我们一般都会将部分数据放入缓存中&#xff0c;加速访问。而 db 承担数据落盘工作。 哪些数据适合放入缓存&#xff1f;  即时性、数据一致性要求不高的  访问量大且更新频率不高的数据&#xff08;读多&#xff0c;写少&…...

【JavaEE进阶】Spring事务和事务传播机制

文章目录 一. 什么是Spring事务二. Spring中事务的实现1. Spring编程式事务2. 声明式事务2.1 trycatch下事务不会自动回滚的解决方案2.2 Transactional 作用范围2.3 Transactional 参数说明2.4 Transactional 工作原理 三. 事务的隔离级别1. 事务的四大特性2. Spring中设置事务…...

【Hive】drop table需注意外部表

什么是内部表&#xff0c;外部表&#xff1f; 比较专业的定义&#xff1a; 外部表需要转为内部表&#xff0c;执行删除操作才能真的删表结构删表数据。否则drop table仅是删除了表数据&#xff0c;表结构还是存在的。 alter table tb_name set TBLPROPERTIES(EXTERNALfalse);…...

【2023数学建模国赛】A题定日镜场的优化设计模型建立

2023年全国大学生数学建模竞赛A题定日镜场的优化设计&#xff0c;目前已写出第四版国赛A题思路和模型详细公式&#xff0c;目录如下&#xff1a; 一、 问题重述... 1 二、 问题分析... 1 三、 模型假设... 6 四、 问题一模型的建立和求解... 6 4.1 定日镜场坐标系的建立...…...

QT 事件与信号区别

事件&#xff08;Event&#xff09;和信号&#xff08;Signal&#xff09;是两个在编程中具有不同概念和用途的术语。 事件&#xff08;Event&#xff09;&#xff1a; 事件是程序运行过程中发生的特定动作或状态改变。可以是用户输入、硬件触发、系统通知等。 事件通常由操作…...

[Vue3 博物馆管理系统] 使用Vue3、Element-plus tabs组件构建选项卡功能

系列文章目录 第一章 定制上中下&#xff08;顶部菜单、底部区域、中间主区域显示&#xff09;三层结构首页 第二章 使用Vue3、Element-plus菜单组件构建菜单 第三章 使用Vue3、Element-plus走马灯组件构建轮播图 第四章 使用Vue3、Element-plus tabs组件构建选项卡功能 [第五…...

【算法专题突破】滑动窗口 - 长度最小的子数组(9)

目录 1. 题目解析 2. 算法原理 3. 代码编写 写在最后&#xff1a; 1. 题目解析 题目链接&#xff1a;209. 长度最小的子数组 - 力扣&#xff08;Leetcode&#xff09; 要注意的是&#xff0c;题目给的是正整数&#xff0c; 而题目要求并不难理解&#xff0c;就是找最短的…...

骨传导与入耳式耳机哪种音质好?该如何选择?

骨传导耳机和传统耳机的定位不同&#xff0c;所以没有可比性&#xff0c;如果一定要说哪款耳机音质好&#xff0c;答案是入耳式耳机音质比较好&#xff01; 首先入耳式耳机是直接塞入耳朵佩戴&#xff0c;会最大程度减少漏音&#xff0c;同时不会改变音质&#xff0c;会直接传…...

【多线程】Timer任务定时器实现与盲等原子性问题的解决

目录 一、定时器 二、标准库中的Timer 三、代码实现 四、死锁 一、定时器 代码中的定时器通常是在一定的时间执行对应的代码逻辑 二、标准库中的Timer public static void main(String[] args){Timer timer new Timer();timer.schedule(new TimerTask() {Overridepublic…...

SpringCloud-GetWay 路由网关

接上文 SpringCloud-Hystrix 服务降级与熔断 微服务也是如此&#xff0c;不是所有微服务需要直接暴露给外部调用&#xff0c;就需要使用路由机制&#xff0c;添加一层防护&#xff0c;让所有的请求全部通过路由来转发到各个微服务&#xff0c;并转发给多个相同微服务实例&#…...

使用生成式 AI 增强亚马逊云科技智能文档处理

数据分类、提取和分析对于处理大量文档的组织来说可能具有挑战性。传统的文档处理解决方案是手动的、昂贵的、容易出错的,并且难以扩展。利用 Amazon Textract 等 AI 服务,亚马逊云科技智能文档处理(IDP)允许您利用业界领先的机器学习(ML)技术来快速准确地处理任何扫描文档或图…...

谈论浏览器内核

浏览器内核是指浏览器使用的渲染引擎&#xff0c;用于解析并显示网页的内容。主要有以下几种浏览器内核&#xff1a; Trident&#xff08;IE内核&#xff09;&#xff1a;由Microsoft开发&#xff0c;被用于Internet Explorer浏览器。目前已经被Edge取代。 Gecko&#xff1a;…...

电商卖家保障数据隐私和安全用什么安全的浏览器?

在如今信息爆炸的时代&#xff0c;个人数据安全成为了一个备受关注的话题。越来越多的人意识到&#xff0c;保护个人数据的重要性。为此&#xff0c;安全浏览器应运而生&#xff0c;为用户提供更加安全可靠的上网环境&#xff0c;保障个人数据的安全。 一、数据安全的重要性 …...

ECS通过DNAT将C非专线网段并网

1.问题描述 客户需求&#xff1a;ECS1需要访问140.131.208.0/24 &#xff0c;由于140.131.208.0/24网段属于公网地址&#xff0c;在CSW侧为进行并网。 解决方案&#xff1a;故将ECS1发起的请求其在云内ECS2做DNAT&#xff0c;将该网段转换成CSW并网网段170.101.253.0/24&…...

g++模板显式实例化big file例子

前言 模板是编程中高级工具&#xff0c;类似C语言的宏生成代码&#xff0c;但却比宏更强大&#xff0c;例如&#xff0c;对于调试的支持&#xff0c;以及实现更严格的语法检查。 如果用节省代码来定义工具的好坏&#xff0c;无疑不管用C语言宏来生成代码&#xff0c;或者用C的…...

Redis 删除策略

文章目录 Redis 删除策略一、过期数据二、数据删除策略1、定时删除2、惰性删除3、定期删除4、删除策略对比 三、逐出算法 Redis 删除策略 一、过期数据 Redis是一种内存级数据库&#xff0c;所有数据均存放在内存中&#xff0c;内存中的数据可以通过TTL指令获取其状态 XX &a…...

自动化运维——ansible (五十二) (01)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 一、概述 1.1 为什么要用自动化运维软件 1.2 自动化运维 1.3 自动化运维要注意的方面 1.4 自动化运维主要关注的方面 1.5 常见的开源自动化运维软件 1.6 自动化运维软件…...

渗透测试漏洞原理之---【不安全的反序列化】

文章目录 1、序列化与反序列化1.1、引入1.2、序列化实例1.2.1、定义一个类1.2.2、创建 对象1.2.3、反序列化1.2.4、对象注入 2、漏洞何在2.1、漏洞触发2.1.2、定义一个类2.1.3、定义一个对象2.1.3、反序列化执行代码 2.2 为什么会这样 3、反序列化漏洞攻防3.1、PHP反序列化实例…...

建站系列(四)--- Web服务器之Apache、Nginx

目录 相关系列文章前言一、简介二、Apache与Nginx&#xff08;1&#xff09;Apache与Nginx的区别&#xff08;2&#xff09;Nginx相对于Apache的优点&#xff08;3&#xff09;Apache相对于Nginx 的优点&#xff08;4&#xff09;选择 三、反向代理与正向代理 相关系列文章 建…...

TCP和UDP的区别

TCP和UDP的区别 1、TCP面向连接&#xff08;如打电话要先拨号建立连接&#xff09;;UDP是无连接的&#xff0c;即发送数据之前不需要建立连接 2、TCP提供可靠的服务。也就是说&#xff0c;通过TCP连接传送的数据&#xff0c;无差错&#xff0c;不丢失&#xff0c;不重复&…...

【Gemini JavaScript开发支持终极指南】:20年谷歌AI工程师亲授7大避坑法则与实时调试秘技

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Gemini JavaScript开发支持概览 Gemini API 的 JavaScript 集成能力 Google Gemini 提供了官方 Node.js SDK&#xff08; google/generative-ai&#xff09;&#xff0c;支持在服务端与浏览器环境中调…...

如何免费解锁Cursor Pro:完整破解方案与实战指南

如何免费解锁Cursor Pro&#xff1a;完整破解方案与实战指南 【免费下载链接】cursor-free-vip [Support 0.45]&#xff08;Multi Language 多语言&#xff09;自动注册 Cursor Ai &#xff0c;自动重置机器ID &#xff0c; 免费升级使用Pro 功能: Youve reached your trial re…...

9.实战案例拆解

好的,我们开始。先别急着看那些“月入十万”的爽文,我这边先给你看一段我昨晚在调试一个树莓派Pico W的I2C总线时,在终端里敲出来的报错信息: [ERROR] I2C timeout: SDA line held low by device at 0x3C这条错误让我折腾了半小时。最后发现是传感器模块的电源纹波太大,导…...

多云配置管理工具MCP:统一编排AWS、GCP等云资源的实战指南

1. 项目概述&#xff1a;一个高效的多云配置管理工具 最近在梳理团队的基础设施配置时&#xff0c;发现了一个挺有意思的开源项目&#xff0c;叫 malminhas/mcp 。乍一看这个名字&#xff0c;你可能会有点懵&#xff0c;这缩写代表什么&#xff1f;其实&#xff0c;MCP 在这里…...

Visio从入门到精通:高效绘图与自定义库实战指南

1. Visio快速入门&#xff1a;从零到第一张流程图 第一次打开Visio时&#xff0c;很多人都会被满屏的工具栏和陌生的术语吓到。其实Visio的核心逻辑非常简单——就像小时候玩的拼图游戏。你只需要从左侧模具库拖出图形&#xff0c;在画布上拼接组合&#xff0c;再用连接线把它们…...

从虚拟到物理:电子系统原型设计的工程化策略与实战解析

1. 原型设计全景&#xff1a;从概念到实物的工程化思维 在电子系统设计领域&#xff0c;尤其是面对航空航天、汽车电子、通信设备这类高复杂、高可靠性要求的项目时&#xff0c;“原型”这个词的分量远超一个简单的模型。它不是一个可有可无的步骤&#xff0c;而是连接创意与产…...

NotebookLM播客化功能上线即爆火(2024Q2内部灰度测试TOP3功能首次公开)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;NotebookLM文档播客化功能详解 NotebookLM 的文档播客化&#xff08;Doc-to-Podcast&#xff09;功能将静态文本内容智能转化为自然流畅的语音叙述&#xff0c;支持多角色配音、语速调节与上下文感知停…...

Display Driver Uninstaller:显卡驱动问题的终极解决方案

Display Driver Uninstaller&#xff1a;显卡驱动问题的终极解决方案 【免费下载链接】display-drivers-uninstaller Display Driver Uninstaller (DDU) a driver removal utility / cleaner utility 项目地址: https://gitcode.com/gh_mirrors/di/display-drivers-uninstall…...

AI编程助手代码质量守护:Quality Guardian MCP实战指南

1. 项目概述&#xff1a;为AI编程助手打造的“质量守门员”如果你和我一样&#xff0c;日常重度依赖 Claude Code、Cursor 这类 AI 编程助手来写代码&#xff0c;那你肯定也遇到过这个头疼的问题&#xff1a;助手写的代码&#xff0c;语法上没问题&#xff0c;但一跑静态检查&a…...

别再被防火墙挡在门外!FileZilla Server在Windows下的完整端口放行指南(含被动模式配置)

FileZilla Server在Windows环境下的防火墙配置与端口管理实战 "为什么我的FTP客户端能连接却无法列出目录&#xff1f;"——这是许多初次配置FileZilla Server的用户常遇到的困惑。Windows防火墙就像一位严格的保安&#xff0c;如果不清楚FTP协议的特殊性&#xff0c…...