Redis核心机制-缓存、分布式锁

news2025/4/7 10:00:16

目录

缓存

缓存更新策略

定期生成

实时生成

缓存问题

缓存预热(Cache preheating)

缓存穿透(Cache penetration)

缓存雪崩(Cache avalanche)

缓存击穿(Cache breakdown)

分布式锁

分布式锁基础实现

引入过期时间

引入校验id

引入lua脚本

引入watch dog(看门狗)

引入Redlock算法


缓存

缓存的核心思路就是把常用的数据放入访问速度更快的地方,方便随时读取。使用Redis作为缓存,数据是直接存储在内存上的,对于关系型数据库例如MySql来说速度更快。

为什么说关系型数据库性能不高?

1.数据库将数据存储在硬盘上,硬盘的IO速度没有内存快。

2.如果查询不能命中索引,就需要进行表的遍历,这就会大大增加硬盘IO次数。

3.关系型数据库会对SQL的执行做一系列的解析,校验,优化工作。

4.复杂查询更加消耗效率。(笛卡尔积)

 如果全部请求直接访问数据库,对于数据库压力很大,很容易使数据库服务器宕机。使用Redis缓存可以加快读操作,写操作还是得写在数据库中。

缓存更新策略

定期生成

每隔一定时间,对访问数据频次较高的数据进行统计,挑选出访问频次最高的前N%的数据,导入到Redis中。实时性比较低,面对突发情况不友好。如春节期间,“春节”的搜索频率变高,在平时搜索频率比较低。

实时生成

用户查询数据,如果没有在Redis中命中,就在数据库中查询,然后将结果更新到Redis中。如果Redis缓存满了,就可以使用内存淘汰策略进行删除:

FIFO(First In First Out)先进先出

将缓存中存在时间最久的数据淘汰。

LRU(Least Recently Used)淘汰最久未使用的

记录每个key的最近访问时间,把最近访问时间最老的key淘汰。

LFU(淘汰访问次数最少的)

记录每个key最近一段时间的访问次数,淘汰访问次数最少得到。

Random随机淘汰

随机淘汰缓存中的key。

缓存问题

缓存预热(Cache preheating)

刚刚启动Redis作为MySQL缓存时,Redis自身为空,所有请求都会直接直接访问数据库,从而对数据库造成很大的压力。

提前准备热点数据导入Redis中,使Redis更快提供服务,解决缓存预热问题。

缓存穿透(Cache penetration)

访问的key在Redis和MySQL中都不存在,此时key不会放入缓存中,后续如果接着访问这个key,依然会访问到数据库。这样会给数据库造成压力。

针对查询的key进行校验,如要查询的key为手机号,首先对key的格式进行校验。

针对数据库不存在的key也放入redis中。

使用布隆过滤器,判定key是否存在。

缓存雪崩(Cache avalanche)

短时间内,大量的key失效(Redis挂了/大量key同时过期),导致数据库压力增大。

部署高可用的Redis系统,完善监控报警体系。

不给key设置过期时间,或者设置过期时间时加入随机因子。

缓存击穿(Cache breakdown)

热点key突然过期,大量请求直接访问MySQL数据库。

将这些热点key设置为永不过期。

分布式锁

分布式系统中,当不同节点访问统一资源时,就需要通过锁进行互斥控制,避免出现类似“线程 安全”问题。在分布式这种多进程,多主机的的场景中,就需要有一台服务器进行记录加锁操作。

分布式锁基础实现

使用Redis实现分布式锁,本质上就是通过设置一个键值对,然后通过键值对来判定是否已有其他进程加锁。

例如在网上买票的时候,车站提供了多个服务器处理买票的请求,客户端每次买票需要查询车票数量,判断车票数量是否大于1,满足条件车票数量减一。在高并发情况下,可能会导致超卖情况,此时引入分布式锁。

此时服务器对数据库进行操作时,就会先判断Redis中是否有加锁的键值对,Redis中的key就可以代表车次,表示该车次的票正在其他进程中进行操作。Redis中提供了setnx操作,当key设置成功,则代表加锁成功,反之就代表已经有其他进程进行加锁了。设置成功后,就可以对数据库进行读写操作了,操作完成之后再把Redis上刚刚的key进行删除。

但是这个方案并不完整,当加锁的进程在执行删除key操作之前遇到问题(如宕机),此时删除操作不能进行,其他进程也不能获取锁

引入过期时间

为解决加锁后加锁进程意外宕机的情况,在设置key时顺便设置过期时间,表示进程持有锁的最大时间,达到时间后就会自动删除key,使用set ex nx命令进行设置,不能分开设置,由于Redis事务不能保证两个操作都能成功执行,可能就会出现set nx操作成功,但是expire失败的情况。此时任然会出现无法正确释放锁的问题。

但是仍然存在问题,其他进程也可以操作Redis删除key,此时加锁就失去了意义

引入校验id

为解决其他进程删除key,引入校验机制,在设置键值对时,value设置为可以识别加锁服务器的身份。在执行解锁操作时,先根据value判断是否为加锁的服务器。该逻辑用伪代码表示:

String key = "要加锁的资源id";
String serverId = "服务器的编号";
//加锁,设置过期时间为10s
redis.set(key,serverId,"NX","EX","10s");
//执行各种逻辑,如数据库的增删查改
select();
update();
delete();
insert();
//解锁,先判断是否为加锁进程
if(redis.get(key) == serverId) {
    redis.del(key);
}

在执行解锁操作时,解锁的逻辑是分为两步的,不是原子操作。一个服务器内部,可能是多线程的,同一个服务器内部,两个线程都在执行解锁操作,就可能导致del操作被重复执行,然后将其他加锁线程的锁给删除了。

引入lua脚本

 为了使解锁操作变为原子的,使用Redis支持的lua脚本,将查询和删除操作打包为原子操作,可以将上述代码编写成一个.lua后缀的文件,一个lua脚本会被Redis服务器以原子的方式进行执行。

引入watch dog(看门狗)

设置key过期时间后,任然存在当前任务没有执行完,key就过期了的情况,导致锁提前失效。引入watch dog,本质上是加锁的服务器上一个单独的线程,通过这个线程来对锁的过期时间进行“续约”。这个线程并不是Redis提供,而是业务服务器上的线程。

假设设置一个key,过期时间为10s,设定看门狗线程没3s检测一次。

当3s时间到的时候,看门狗就会判定当前任务是否完成。

如果完成,可通过lua脚本直接释放锁。

未完成,则将过期时间重新设置为10s(续约)。

这样就不用担心锁提前失效的问题。如果该服务器挂了,那么看门狗线程也随之挂了,没人给锁续约,到达过期时间后key就会过期,让其他服务器能够获取锁。

引入Redlock算法

 实践中Redis一般是以集群的方式部署的(至少是主从结构),Redis成为分布式锁可能会遇到一些极端情况:负责加锁的master节点刚刚进行加锁操作,然后就挂了,此时slave节点成了新的master节点,由于此时的key并没有同步给slave节点,导致加锁操作形同虚设。

解决办法:引入一组Redis节点,每一组Redis节点都包含master节点和slave节点,组与组之间的数据都是一致的,相互之间为“备份”关系。在进行加锁操作时,设置加锁操作的超时时间,比如设置为30ms,超过30ms没有加锁,则视为加锁失败。如果当前节点加锁失败。就立即尝试下一个节点,当加锁成功的节点超过总结点的一半,则视为加锁成功。即使某些节点挂了也不会影响锁的正确性。

文章结束,感谢观看! 

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

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

相关文章

如何在Ubuntu上安装Dify

如何在Ubuntu上安装Dify 如何在Ubuntu上安装docker 使用apt安装 # Add Dockers official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg…

Python FastApi(13):APIRouter

如果你正在开发一个应用程序或 Web API,很少会将所有的内容都放在一个文件中。FastAPI 提供了一个方便的工具,可以在保持所有灵活性的同时构建你的应用程序。假设你的文件结构如下: . ├── app # 「app」是一个 Python 包…

【算法竞赛】状态压缩型背包问题经典应用(蓝桥杯2019A4分糖果)

在蓝桥杯中遇到的这道题,看上去比较普通,但其实蕴含了很巧妙的“状态压缩 背包”的思想,本文将从零到一,详细解析这个问题。 目录 一、题目 二、思路分析:状态压缩 最小覆盖 1. 本质:最小集合覆盖问题…

常微分方程 1

slow down and take your time 定积分应用回顾常微分方程的概述一阶微分方程可分离变量齐次方程三阶线性微分方程 一阶线性微分方程不定积分的被积分函数出现了绝对值梳理微分方程的基本概念题型 1 分离变量题型 2 齐次方程5.4 题型 3 一阶线性微分方程知识点5.55.6 尾声 定积分…

Web前端页面搭建

1.在D盘中创建www文件 cmd进入窗口命令windowsR 切换盘符d: 进入创建的文件夹 在文件夹里安装tp框架 在PS中打开tp文件 创建网站&#xff0c;根目录到public 在浏览器中打开网页 修改文件目录名称 在public目录中的。htaccess中填写下面代码 <IfModule mod_rewrite.c >…

开源 LLM 应用开发平台 Dify 全栈部署指南(Docker Compose 方案)

开源 LLM 应用开发平台 Dify 全栈部署指南&#xff08;Docker Compose 方案&#xff09; 一、部署环境要求与前置检查 1.1 硬件最低配置 组件要求CPU双核及以上内存4GB 及以上磁盘空间20GB 可用空间 1.2 系统兼容性验证 ✅ 官方支持系统&#xff1a; Ubuntu 20.04/22.04 L…

BN 层的作用, 为什么有这个作用?

BN 层&#xff08;Batch Normalization&#xff09;——这是深度神经网络中非常重要的一环&#xff0c;它大大改善了网络的训练速度、稳定性和收敛效果。 &#x1f9e0; 一句话理解 BN 层的作用&#xff1a; Batch Normalization&#xff08;批归一化&#xff09;通过标准化每一…

金仓数据库KCM认证考试介绍【2025年4月更新】

KCM&#xff08;金仓认证大师&#xff09;认证是金仓KES数据库的顶级认证&#xff0c;学员需通过前置KCA、KCP认证才能考KCM认证。 KCM培训考试一般1-2个月一次&#xff0c;KCM报名费原价为1.8万&#xff0c;当前优惠价格是1万&#xff08;趋势是&#xff1a;费用越来越高&…

如何通过句块训练法(Chunks)提升英语口语

真正说一口流利英语的人&#xff0c;并不是会造句的人&#xff0c;而是擅长“调取句块”的人。下面我们从原理、方法、场景、资源几个维度展开&#xff0c;告诉你怎么用“句块训练法&#xff08;Chunks&#xff09;”快速提升英语口语&#xff1a; 一、什么是“句块”&#xff…

[ctfshow web入门]burpsuite的下载与使用

下载 吾爱破解网站工具区下载burpsuite https://www.52pojie.cn/thread-1544866-1-1.html 本博客仅转载下载链接&#xff0c;下载后请按照说明进行学习使用 打开 配置 burpsuite配置 burpsuite代理设置添加127.0.0.1:8080 浏览器配置 如果是谷歌浏览器&#xff0c;打开win…

vscode集成deepseek实现辅助编程(银河麒麟系统)【详细自用版】

针对开发者用户&#xff0c;可在Visual Studio Code中接入DeepSeek&#xff0c;实现辅助编程。 可参考我往期文章在银河麒麟系统环境下部署DeepSeek&#xff1a;基于银河麒麟桌面&&服务器操作系统的 DeepSeek本地化部署方法【详细自用版】 一、前期准备 &#xff08…

elementui的默认样式修改

今天用element ui &#xff0c;做了个消息提示&#xff0c;发现提示的位置总是在上面&#xff0c;如图&#xff1a; 可是我想让提示的位置到下面来&#xff0c;该怎么办&#xff1f; 最后还是看了官方的api 原来有个自定义样式属性 customClass 设置下就好了 js代码 css代码 效…

基于STM32的智能门禁系统设计与实现

一、项目背景与功能概述 在物联网技术快速发展的今天&#xff0c;传统门锁正在向智能化方向演进。本系统基于STM32F103C8T6微控制器&#xff0c;整合多种外设模块&#xff0c;实现了一个具备以下核心功能的智能门禁系统&#xff1a; 密码输入与验证&#xff08;4x3矩阵键盘&a…

基于SpringBoot的河道水情大数据可视化分析平台设计与实现(源码+论文+部署讲解等)

需要资料&#xff0c;请文末联系 一、平台介绍 水情监测数据大屏 - 平台首页 日均水位 日均水速 二、论文内容 摘要&#xff08;中文&#xff09; 本文针对河道水情监测领域的数据管理和可视化分析需求&#xff0c;设计并实现了一套河道水情大数据可视化分析平台。该平台基…

广告推荐算法:COSMO算法与A9算法的对比

COSMO算法与A9算法的概念解析 1. A9算法 定义与背景&#xff1a; A9算法是亚马逊早期为电商平台研发的核心搜索算法&#xff0c;主要用于优化商品搜索结果的排序和推荐&#xff0c;其核心逻辑围绕产品属性与关键词匹配展开。自2003年推出以来&#xff0c;A9通过分析商品标题…

【JS】使用滑动窗口得到无重复字符的最长子串

题目 思路 本题采用滑动窗口思想&#xff0c;定义左右指针作为滑动窗口的边界&#xff0c;使用Set数据结构处理重复字符&#xff0c;需要注意的是&#xff1a;每次遍历时采用Math.max方法实时更新最长子串的长度&#xff1b;当左指针移动时&#xff0c;set要删除对应字符。 步…

2025-04-05 吴恩达机器学习4——逻辑回归(1):基础入门

文章目录 1 分类问题1.1 介绍1.2 线性回归与分类1.2 逻辑回归 2 逻辑回归2.1 介绍2.2 Sigmoid 函数2.3 逻辑回归模型 3 决策边界3.1 概念3.2 线性决策边界3.3 非线性决策边界 4 代价函数4.1 不使用平方误差4.2 损失函数4.3 整体代价函数 5 梯度下降5.1 参数更新5.2 逻辑回归 vs…

P1125 [NOIP 2008 提高组] 笨小猴

#include<bits/stdc.h> using namespace std; int a[300],ma,mi105;//数组用来记录每个字符出现的次数&#xff0c;将mi初始为一个比较大的值 bool is_prime(int x){if(x0||x1)return false;for(int i2;i*i<x;i){if(x%i0)return false;}return true; }//判断是否为质…

Linux systemd 服务全面详解

一、systemd 是什么&#xff1f; systemd 是 Linux 系统的现代初始化系统&#xff08;init&#xff09;和服务管理器&#xff0c;替代传统的 SysVinit 和 Upstart。它不仅是系统启动的“总指挥”&#xff0c;还统一管理服务、日志、设备挂载、定时任务等。 核心作用 服务管理…

SortedSet结构之用户积分实时榜单实战

Redis 中的SortedSet结构非常适合用于实现实时榜单的场景&#xff0c;它根据成员的分数自动进行排序&#xff0c;支持高效的添加、更新和查询操作。 SortedSet实时榜单的一些典型应用场景&#xff1a; 游戏中的玩家排行榜&#xff1a;在多人在线游戏中&#xff0c;使用 Sorte…