redis加锁实现方式
思考
- 是否有官方推荐(自己先思考如何实现,然后再参考其他人的实践,总结优缺点)
- 通过哪些方式可以实现锁
- 锁是否具有原子性
- 锁请求失败了如何处理
- 如果避免发生死锁
- 如果避免发生资源抢占
- 如果避免锁的误删
官方实现策略
- 安全性能:互斥。在任何给定的时刻,只有一个客户可以持有锁
- 活性属性A:无死锁。最终,即使锁定资源的客户端崩溃或被分区,也始终有可能获取锁
- 活性性质B:容错性。只要大多数Redis节点都启动了,客户端就可以获取和释放锁
储备知识
原子操作
解释一
原子操作是指不会被线程调度机制打断操作,这种操作一旦开始,就一直到结束,
中间不会有任何context switch(切换到另外一个线程)
解释二
原子性就是指该操作是不可再分的。不论是多核还是单核,具有原子性的量,同一时刻只能有一个线程来对它进行操作。
原子操作可以是一个步骤,也可以是多个步骤,但是其顺序不可以被打乱,也不可以被切割而只执行其中的一部分(不可中断性)。
将操作视作一个整体,资源在该次操作中保持一致,这是原子性的核心特征。
可用加锁命令
INCR SETNS SET
加锁命令优劣分析
INCR
实现思路
key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作进行加一。
然后其它用户在执行 INCR 操作进行加一时,如果返回的数大于 1 ,说明这个锁正在被使用当中
实现方式
- 客户端A请求服务器获取key的值为1表示获取了锁
- 客户端B也去请求服务器获取key的值为2表示获取锁失败
- 客户端A执行代码完成,删除锁
- 客户端B在等待一段时间后在去请求的时候获取key的值为1表示获取锁成功
- 客户端B执行代码完成,删除锁
remark
加入过期时间是为了防止意外退出,锁没有删除,锁一直存在,以至于无法再次获取锁资源
demo
- r e d i s − > i n c r ( redis->incr( redis−>incr(key);
- r e d i s − > e x p i r e ( redis->expire( redis−>expire(key, $ttl); //设置生成时间为1秒
缺点
借住Expire设置,不再是原子操作。
SETNX
实现思路
如果key不存在,则将key设置为value,如果key已存在,则SETNX不做任何操作
实现方式
- 客户端A请求服务端设置key的值,如果设置成功,表示加锁成功
- 客户端B请求服务器设置key的值,如果返回失败,表示加锁失败
- 客户端A执行代码完成,删除锁
- 客户端B在等待一段时间后再去请求设置key值,设置成功
- 客户端B执行代码完成,删除锁
demo
- r e d i s − > s e t N X ( redis->setNX( redis−>setNX(Kkey, $value);
- r e d i s − > e x p i r e ( redis->expire( redis−>expire(key, $ttl);
缺点
不是原子操作
非原子性潜在问题:无法实现互斥,出现单点故障时,比如说如果Redis主机坏了怎么办?好吧,
让我们增加一个假设!如果主机不可用,我们增加一个备机,请使用它。不幸的是,这是不可行的。
这样做我们就无法实现互斥的安全属性,因为Redis复制是异步的。
场景描述
- 客户机A获取主机中的锁。
- 在向从机发送对密钥的写入之前,主机崩溃。
- 备机被提升为主机。
- 客户端B获取已为其持有锁的同一资源A的锁。违反安全规定!(在A拥有锁的同时,B也用用了锁)
- 有时,在特殊情况下,比如在故障期间,多个客户机可以同时持有锁,这是非常好的。
如果是这种情况,则可以使用基于复制的解决方案。否则,我们建议实现本文档中描述的解决方案。
SET
实现思路
设置key的同时,这只过期时间
实现方式
- 客户端A请求服务器设置key的值,如果设置成功就表示加锁成功
- 客户端B也去请求服务器设置key的值,如果返回失败,那么就代表加锁失败
- 客户端A执行代码完成,删除锁
- 客户端B在等待一段时间后在去请求设置key的值,设置成功
- 客户端B执行代码完成,删除锁
demo
r e d i s − > s e t ( redis->set( redis−>set(key, $value, array(‘nx’, ‘ex’ => $ttl)); //ex表示秒
存在问题
以上几种方式仍存在的问题
- redis发现锁失败了要怎么办?中断请求还是循环请求?
- 循环请求的话,如果有一个获取了锁,其它的在去获取锁的时候,是不是容易发生抢锁的可能?
- 锁提前过期后,客户端A还没执行完,然后客户端B获取到了锁,这时候客户端A执行完了,会不会在删锁的时候把B的锁给删(非原子操作的影响)
解决办法
针对问题1:使用循环请求,循环请求去获取锁
针对问题2:针对第二个问题,在循环请求获取锁的时候,加入睡眠功能,等待几毫秒在执行循环
针对问题3:在加锁的时候存入的key是随机的。这样的话,每次在删除key的时候判断下存入的key里的value和自己存的是否一样
do { //针对问题1,使用循环$timeout = 10;$roomid = 10001;$key = 'room_lock';$value = 'room_'.$roomid; //分配一个随机的值针对问题3$isLock = Redis::set($key, $value, 'ex', $timeout, 'nx');//ex 秒if ($isLock) {if (Redis::get($key) == $value) { //防止提前过期,误删其它请求创建的锁//执行内部代码Redis::del($key);continue;//执行成功删除key并跳出循环}} else {usleep(5000); //睡眠,降低抢锁频率,缓解redis压力,针对问题2}
} while(!$isLock);
官方提供分布式redis锁说明
参考
【锁】redis加锁的几种方法
线程安全之原子操作
原子操作
相关文章:
redis加锁实现方式
思考 是否有官方推荐(自己先思考如何实现,然后再参考其他人的实践,总结优缺点)通过哪些方式可以实现锁锁是否具有原子性锁请求失败了如何处理如果避免发生死锁如果避免发生资源抢占如果避免锁的误删 官方实现策略 安全性能&#…...
ClickHouse--08--SQL DDL 操作
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 SQL DDL 操作1 创建库2 查看数据库3 删除库4 创建表5 查看表6 查看表的定义7 查看表的字段8 删除表9 修改表9.1 添加列9.2 删除列9.3 清空列9.4 给列修改注释9.5 修…...
5种风格非常经典的免费wordpress主题
免费wordpress主题下载 高端大气上档次的wordpress主题,也可以是免费的,可以在线免费下载。 https://www.wpniu.com/themes/288.html wordpress免费主题 高端大气的wordpress免费主题,LOGO在顶部左侧,导航菜单在顶部右侧。 ht…...
「数据结构」哈希表2:实现哈希表
🎇个人主页:Ice_Sugar_7 🎇所属专栏:Java数据结构 🎇欢迎点赞收藏加关注哦! 实现哈希表 🍉扩容🍉插入🍉获取value🍉源码 🍉扩容 在讲插入之前需要…...
ITK 图像分割(一):阈值ThresholdImageFilter
效果: Video: 区域增加分割 1、itkThresholdImageFilter 该类的主要功能是通过设置低阈值、高阈值或介于高低阈值之间,则将图像值输出为用户指定的值。 如果图像值低于、高于或介于设置的阈值之间,该类就将图像值设置为用户指定的“外部”值…...
2023.2.6
#include<stdio.h> #include<string.h> //冒泡排序 void bubb(int arr[],int len) {for(int i1;i<len;i){for(int j0;j<len-i1;j){if(arr[j1]<arr[j]){int tarr[j];arr[j]arr[j1];arr[j1]t;}}} } //select排序 void select(int arr[],int len) {int min0;…...
例39:使用List控件
建立一个EXE工程,在窗体上放一个文本框,一个列表框和三个按钮输入如下的代码: Sub Form1_Command1_BN_Clicked(hWndForm As hWnd, hWndControl As hWnd)List1.AddItem(Text1.Text)End SubSub Form1_Command2_BN_Clicked(hWndForm As hWnd, h…...
浏览器内核的主要功能模块介绍
浏览器内核是浏览器的核心部分,负责解析网页内容、渲染页面和处理用户交互。一个典型的浏览器内核主要包括以下几个功能模块: 1. **解析器(Parser)**: 解析器负责解析网页内容,包括HTML…...
如何流畅进入Github
前言 以下软件是免费的,放心用 一、进入右边的下载链接https://steampp.net/ 二、点击下载 三、点击接受并下载 四、随便选一个下载链接进行下载 五、软件安装好打开后,找到Github 六、点击全部启用 七、再点击左上角的一键加速 八、这个时候你再进Git…...
docker磁盘不足!已解决~
目录 🍟1.查看docker镜像目录 🧂2.停止docker服务 🥓3.创建新的目录 🌭4.迁移目录 🍿5.编辑迁移的目录 🥞6.重新加载docker 🍔7.检擦docker新目录 🍳8.删掉旧目录 1.查看doc…...
法国实习面试——计算机相关专业词汇
法语 1.Spcialit - 专业 2.Systme - 系统 3.Embarqus - 嵌入式 4.Logicielle - 软件 5.Distribus - 分布式 6.lectronique - 电子 7.nergie lectrique - 电能 8.Automatisation - 自动化 9.Une exprience de stage - 实习经验 10.Automobiles - 汽车 11.tre charg…...
LeetCode刷题计划
LeetCode刷题计划 推荐 代码随想录:https://github.com/youngyangyang04/leetcode-master 卡码网 练习ACM模式 https://kamacoder.com/ 01 #include <iostream> using namespace std;int main() {int a ,b;while(cin>>a>>b){cout<<ab<…...
2023全球云计算市场份额排名
关注卢松松,会经常给你分享一些我的经验和观点。 最近Synergy研究院发布了最新的全球云计算市场份额排名。 亚马逊依旧是以31%的的市场份额排名第一,微软azure24%排名第二,Google云11%排名第三,阿里云4%排名第四。腾讯云和IBM、…...
Oracle数据库
1. 请解释什么是分区表(Partitioned Table)以及它的优点。 分区表是一种数据库技术,它将一个大表分成多个小的、更易于管理的部分,每个部分称为一个分区。以下是Oracle分区表的一些优点: 提高查询性能:通…...
Spring Cloud Hystrix 参数配置、简单使用、DashBoard
Spring Cloud Hystrix 文章目录 Spring Cloud Hystrix一、Hystrix 服务降级二、Hystrix使用示例三、OpenFeign Hystrix四、Hystrix参数HystrixCommand.Setter核心参数Command PropertiesFallback降级配置Circuit Breaker 熔断器配置Metrix 健康统计配置Request Context 相关参数…...
阿里云服务器4核16G配置报价和CPU内存性能参数表
阿里云4核16G服务器优惠价格ECS云服务器经济型e实例26元1个月、149元半年、79元3个月,4核16G通用算力u1服务器、通用型g7、通用型g8i、AMD通用型g8a、性能增强通用型g8ae、高主频通用型hfg8i、AMD通用型g7a、内存型r7p等均提供4核16G配置。阿里云服务器网aliyunfuwu…...
数据结构:图文详解 队列 | 循环队列 的各种操作(出队,入队,获取队列元素,判断队列状态)
目录 队列的概念 队列的数据结构 队列的实现 入队 出队 获取队头元素 获取队列长度 循环队列的概念 循环队列的数据结构 循环队列的实现 判断队列是否为空 判断队列是否已满 入队 出队 得到队头元素 得到队尾元素 队列的概念 队列(Queue࿰…...
Debezium发布历史130
原文地址: https://debezium.io/blog/2022/10/10/debezium-2.0-cr1-released/ 欢迎关注留言,我是收集整理小能手,工具翻译,仅供参考,笔芯笔芯. Debezium 2.0.0.CR1 Released October 10, 2022 by Chris Cranford rel…...
【笔记】Harmony学习:下载安装 DevEco Studio 开发工具IDE
IDE 安装 从官网下载DevEco Studio 安装包后进行安装, 安装完毕后,本地环境可能要配置相关工具,可以通过下面的诊断检测一下本地环境,通过蓝色“Set it up now” 可以快速安装。 1. Node.js (for ohpm) 2. ohpm 下载op的包管理&a…...
Electron实战之入门
一、Electron简介 1.1 Electron是什么 Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的技术框架。 嵌入 Chromium 和 Node.js 到 二进制的 Electron 允许开发者使用 JavaScript 代码来创建允许在Windows、macOS和Linux等平台。 1.2 发展历程 2013 年的时候…...
【并发心法】别用 volatile 骗自己了!撕碎裸机并发的伪安全,用 C++ Atomics 与内存屏障镇压“乱序执行”的底层叛乱
摘要:在嵌入式 C/C 开发中,99% 的工程师误以为 volatile 是解决中断与主循环并发冲突的万能解药。本文将无情揭露这一长达数十年的认知毒瘤。我们将带你深入现代编译器(GCC/Clang)的优化黑盒与 ARM Cortex 高级内核的流水线深处&a…...
Fay数字人框架全攻略:从技术原理到商业落地的完整实践指南
Fay数字人框架全攻略:从技术原理到商业落地的完整实践指南 【免费下载链接】Fay Fay 是一个开源的数字人类框架,集成了语言模型和数字字符。它为各种应用程序提供零售、助手和代理版本,如虚拟购物指南、广播公司、助理、服务员、教师以及基于…...
从权重计分到算杀引擎:五子棋AI核心算法实战解析
1. 五子棋AI的算法演进:从基础评分到算杀引擎 五子棋作为一款经典策略游戏,其AI算法的核心在于如何评估棋盘局势并做出最优决策。早期AI主要依赖简单的评分机制,比如给不同的棋形(活二、活三、冲四等)赋予固定分值&…...
开源工具go-cursor-help:技术突破Cursor限制的效率提升方案
开源工具go-cursor-help:技术突破Cursor限制的效率提升方案 【免费下载链接】go-cursor-help 解决Cursor在免费订阅期间出现以下提示的问题: Youve reached your trial request limit. / Too many free trial accounts used on this machine. Please upgrade to pro…...
广州SEO优化对网站转化有什么帮助_广州SEO优化应该注意哪些问题
<h2>广州SEO优化对网站转化有什么帮助</h2> <p>在当今数字化时代,广州SEO优化成为了企业提升在线业务的关键策略。广州作为中国南方的重要城市,其互联网市场竞争激烈,掌握有效的SEO优化手段对于提升网站转化率至关重要。广…...
从报文周期到安全状态:ISO26262通信故障诊断的5个关键时间参数详解
从报文周期到安全状态:ISO26262通信故障诊断的5个关键时间参数详解 在智能驾驶系统快速发展的今天,确保车辆电子系统的功能安全已成为行业共识。ISO26262作为汽车功能安全的黄金标准,其核心在于建立一套完整的故障诊断与处理机制。本文将深入…...
为什么越来越多的STM32项目转向HAL库?从寄存器封装层次看开发效率提升
为什么STM32开发者纷纷拥抱HAL库?深度解析现代嵌入式开发效率革命 在嵌入式开发领域,STM32系列单片机凭借其出色的性能和丰富的生态,已成为工程师们的首选平台。然而,随着产品迭代速度的不断加快,开发效率成为衡量技术…...
实战:用MAF的“人机协同”功能,给你的AI工具调用加上一道安全锁(附C#代码)
企业级AI代理安全实践:基于MAF的人机协同审批架构设计 当财务系统自动驳回了一笔高管差旅报销,或是订单管理系统未经确认修改了客户历史数据时,企业往往需要付出高昂的信任成本来修复这类"自动化事故"。Microsoft Agent Framework&…...
Django CORS Headers 终极指南:10个企业级跨域架构设计技巧
Django CORS Headers 终极指南:10个企业级跨域架构设计技巧 【免费下载链接】django-cors-headers Django app for handling the server headers required for Cross-Origin Resource Sharing (CORS) 项目地址: https://gitcode.com/gh_mirrors/dj/django-cors-he…...
ECharts地图标注避坑指南:解决区域地图显示不全、标注错位等常见问题
ECharts地图标注避坑指南:解决区域地图显示不全、标注错位等常见问题 当你在使用ECharts绘制区域地图时,是否遇到过地图显示不全、标注点位置偏移、JSON数据格式错误等问题?这些问题看似简单,却可能耗费开发者大量时间排查。本文将…...
