redis setnx 分布式锁_Redis 分布式锁PHP

Redis 分布式锁的作用

在单机环境下,有个秒杀商品的活动,在短时间内,服务器压力和流量会陡然上升。这个就会存在并发的问题。想要解决并发需要解决一下问题

1、提高系统吞吐率也就是qps 每秒处理的请求书

解决问题一:采用内存型数据库提高系统的qps

解决问题二:就要用到经常会遇到的锁,例如MySQL 有读锁、写锁、排他锁、悲观锁、乐观锁。不过这里只讨论redis来实现锁

简单版设置锁

$redis = new Redis();
$redis->connect('127.0.0.1', 6379); //连接Redis
$expire = 10;//有效期10秒
$key = 'lock';//key
$value = time() + $expire;//锁的值 = Unix时间戳 + 锁的有效期
$lock = $redis->setnx($key, $value);
//判断是否上锁成功,成功则执行下步操作
if(!empty($lock))
{
//下步操作...
}

如果以这样的简单版设置锁就能解决所有问题,未免也太小看 锁 在程序中应用了。

按正常的操作示例基本上都是这样写的。但是这样写有一些问题

1、假如有10000 个请求访问了redis 不存在的键,这样请求就是指接到了MySQL数据,造成CPU短时间内达到100%甚至宕机。这样场景俗称缓存击穿造成的缓存雪崩。

解决问题:引用reids setnx 方法的作用是,当设置的key 不存在时,设置新的值。这样就避免了缓存击穿的问题。检测键的过期时间,避免产生死锁

解决死锁问题

$expire = 10;//有效期10秒
$key = 'lock';//key
$value = time() + $expire;//锁的值 = Unix时间戳 + 锁的有效期
$status = true;
while($status)
{
$lock = $redis->setnx($key, $value);
if(empty($lock))
{
$value = $redis->get($key);
if($value < time())
{
$redis->del($key);
}
}else{
$status = false;
//下步操作....
}
}

2、分布式集群业务业务场景下,每台服务器是独立存在的。多台服务器怎么通过一个标识来相互竞争锁呢。这里就用到了分布式锁

这里简单介绍一下,以MYSQL 的事务机制来延生。事务四个特性ACID,有四种隔离级别:为提交读、已提交读、可重复读、串行化。这些特性都只在单台服务器上生效。到了分布式集群了,数据在不同的服务器上,紧靠事务很难保持数据的一致性及隔离性,事务的作用就意义不大了。Redis也是如此。

正确的分布式锁的打开方式

/**
* 实现Redis分布锁
*/
$key = 'demo'; //要更新信息的缓存KEY
$lockKey = 'lock:'.$key; //设置锁KEY
$lockExpire = 10; //设置锁的有效期为10秒
//获取缓存信息
$result = $redis->get($key);
//判断缓存中是否有数据
if(empty($result))
{
$status = TRUE;
while ($status)
{
//设置锁值为当前时间戳 + 有效期
$lockValue = time() + $lockExpire;
/**
* 创建锁
* 试图以$lockKey为key创建一个缓存,value值为当前时间戳
* 由于setnx()函数只有在不存在当前key的缓存时才会创建成功
* 所以,用此函数就可以判断当前执行的操作是否已经有其他进程在执行了
* @var [type]
*/
$lock = $redis->setnx($lockKey, $lockValue);
/**
* 满足两个条件中的一个即可进行操作
* 1、上面一步创建锁成功;
* 2、 1)判断锁的值(时间戳)是否小于当前时间 $redis->get()
* 2)同时给锁设置新值成功 $redis->getset()
*/
if(!empty($lock) || ($redis->get($lockKey) < time() && $redis->getSet($lockKey, $lockValue) < time() ))
{
//给锁设置生存时间
$redis->expire($lockKey, $lockExpire);
//******************************
//此处执行插入、更新缓存操作...
//******************************
//以上程序走完删除锁
//检测锁是否过期,过期锁没必要删除
if($redis->ttl($lockKey))
$redis->del($lockKey);
$status = FALSE;
}else{
/**
* 如果存在有效锁这里做相应处理
* 等待当前操作完成再执行此次请求
* 直接返回
*/
sleep(2);//等待2秒后再尝试执行操作
}
}
}

结尾

文章从知识面的广度(mysql)、示例代码优缺点的简介及应用的场景,区别于其他博客文章。嘿嘿~

2b9bcff80612507db0303dc32c8dd8c8.png

更多精彩

敬请关注“PHP技术大全”微信公众号

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

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

相关文章

mysql备份至本地,mysql备份(本地+远程)

整体规划生产环境的mysql数据库&#xff0c;应当每日进行备份&#xff0c;并对较远之前的备份进行删除&#xff0c;由于担心mysql服务器本身崩溃&#xff0c;因此需要考虑将备份的文件同时保存到其他服务器&#xff0c;这样能提高数据安全。备份的方式使用mysqldump&#xff0c…

WinForm窗体自适应分辨率

我们自己编写程序的界面&#xff0c;会遇到各种屏幕分辨率&#xff0c;只有自适应才能显的美观。实际上&#xff0c;做到这点也很简单&#xff0c;就是首先记录窗体和它上面控件的初始位置和大小&#xff0c;当窗体改变比例时&#xff0c;其控件的位置和大小也按此比例变化即可…

ping端口_干货分享:shell脚本批量telnet ip 端口

问1&#xff1a;亲&#xff0c;请教个问题&#xff0c;我这边有200台服务器&#xff0c;怎么看它是否在线呢&#xff1f;答&#xff1a;简单&#xff0c;下载个PingInfoView直接批量ping下&#xff0c;能ping通的就在线&#xff0c;反之离线。问2&#xff1a;那怎么看我这200台…

关于PHP代码的开始和结束标签书写,关于PHP结束标签?gt;的使用细节

当PHP解析一个文件时&#xff0c;会寻找开始&#xff0c;标记告诉PHP开始和停止解释其中的代码。此种方式的解析可以使PHP嵌入到各种不同的文档中&#xff0c;凡是在一对开始和结束标记之外的内容都会被PHP解析器忽略。大多数情况下PHP都是嵌入在HTML文档中的。单行注释仅仅注释…

IIS 7.0 部署MVC

开发的MVC 3.0 项目&#xff0c;在部署服务上还是与需要花一点功夫&#xff0c;这里把遇到的问题罗列出来。 本文主要介绍IIS 7.5中安装配置MVC 3.0的具体办法&#xff01; 部署必备&#xff1a; Microsoft .net FrameWork 4.0安装包 安装ASP.NET MVC 3.0 如果 Asp.NET v4.0.30…

python 爬虫 包_Python爬虫包BeautifulSoup实例(三)

一步一步构建一个爬虫实例&#xff0c;抓取糗事百科的段子先不用beautifulsoup包来进行解析第一步&#xff0c;访问网址并抓取源码# -*- coding: utf-8 -*-# Author: HaonanWu# Date: 2016-12-22 16:16:08# Last Modified by: HaonanWu# Last Modified time: 2016-12-22 20:17:…

phpdesigner8 php7.0,大家千万别用PHPDesigner8 的项目替换,多说是泪,改整个站点中!

PHP PHPDesigner 项目 替换 乱码 大家千万别用PHPDesigner8 的项目替换,多说是泪,改整个站点中!整个项目中文全是乱码,部分文件UTF-8编码变成ANSI编码,不知道有没有大神教我怎么还原回复讨论(解决方案)没有用svn么&#xff1f;没有的话碰上这种问题真的是蛋痛.没有用svn么&…

python 日志不会按照日期分割_python实现日志按天分割

本文实例为大家分享了python实现日志按天分割的具体代码&#xff0c;供大家参考&#xff0c;具体内容如下日志格式&#xff1a;1.1.1.1 - - [30/Apr/2015:00:34:55 0800] “POST /iDataService/services/MemRoomService HTTP/1.0” 200 405 “-” “Axis/1.4” “-”1.1.1.1 - …

如何分析网站日志文件

很多新手站长对于如何分析网站日志文件一筹莫展&#xff0c;打开.log日志文件看到的只有密密麻麻的数字和字母&#xff0c;细看能看出是什么含义&#xff0c;但是想要系统科学的去进行分析太耗时间&#xff0c;这时一般只能借助于第三方日志分析软件&#xff0c;而下面介绍一种…

不是有效的函数或过程名_过程和函数

VBA代码有两种组织形式&#xff0c;一种是过程&#xff0c;另一种就是函数。其实过程和函数有很多相同之处&#xff0c;除了使用的关键字不同之外&#xff0c;还有不同的是&#xff1a;函数有返回值&#xff0c;过程没有。函数可以在Access窗体&#xff0c;查询中像一般的Acces…

怎么下载php源文件,设计了一个php下载当前文件,却把php源文件下载下来了,为何?...

当我点a.txt下载后&#xff0c;打开txt文件&#xff0c;发现里面的内容不是a.txt本身的内容&#xff0c;而是该php文件中除了php代码的其他文本内容&#xff0c;这样该如何解决&#xff1f;资料下载回复讨论(解决方案)$file_name”a.txt”;$file_dir”./”;if(!file_exists($fi…

自己构造构造函数

/*** description 扩展function的原型* function* obj this的上下文*/if(!Function.prototype.bind){Function.prototype.bind function(obj){var slice [].slice,args slice.call(arguments,1),self this,nop function(){},bound function(){return self.apply(this ins…

浏览器快捷键_浏览器快捷键,让你事半功倍

随着互联网时代的发展&#xff0c;手机、电脑已经成为人们生活中不可或缺得一部分&#xff0c;无论是生活还是工作。尤其是办公室族&#xff0c;几乎每天都要面对电脑7/8个小时&#xff0c;查找各种信息或者浏览新闻&#xff0c;浏览器无可厚非的成为了装机必备的软件&#xff…

java f.lenth返回值,这个是什么意思,求仔细说明

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼import java.io.File;import java.io.IOException;import java.util.Random;import java.util.Scanner;public class Test {boolean flagtrue;int count;String word;public static void main(String[] args) {Test t new Test();…

MySQL中的常用函数

1、 字符串函数 2、 字符串函数 模数和被模数任何一个为NULL结果都为NULL。 3、 日期和时间函数 4、 流程函数 5、其他常用函数 MySQL Administrator&#xff08;图形化管理工具&#xff09; MySQL Query Brower&#xff08;客户端查询工具&#xff09; phpMyAdmin&#xff08;…

小程序iconfont报错_【经验】开发微信小程序经验总结

一.技术要求(语言方面)有H5或H4和CSS3的书写经验&#xff0c;没有建议观看B站中的 渡一教育-Web前端开发(html css不算语言)。强烈推荐他们的视频&#xff0c;主讲人没有口音且视频质量很高&#xff0c;是哈尔滨理工大学毕业之后进入阿里工作的Web前端工程师 姬成老师。JavaScr…

超市商品管理系统php,超市商品管理系统(含附源代码)超市商品管理系统(含附源代码).doc...

超市商品管理系统(含附源代码)超市商品管理系统(含附源代码)黔南民族师范学院软件设计课程设计报告题 目&#xff1a; 超市商品管理系统系部名称&#xff1a;计科系专业名称&#xff1a;信息管理与信息系统班 级&#xff1a;B12计信班学号&#xff1a;1208045139学生姓名 &…

IOS_OC_id ,NSObject, idlt;NSObjectgt;差别

我们常常会混淆下面三种申明&#xff08;我是没有留意过&#xff09;&#xff1a; 1. id foo1; 2. NSObject *foo2; 3. id<NSObject> foo3;第一种是最经常使用的&#xff0c;它简单地申明了指向对象的指针&#xff0c;没有给编译器不论什么类型信息&#xff…

python移动端web开发代码_移动web前端开发,前端开发工作总结,移动端页面开发-我主页-一个前端程序猿的博客...

热门推荐html/css一、escape和它们不是同一类简单来说&#xff0c;escape是对字符串(string)进行编码(而另外两种是对URL)&#xff0c;作用是让它们在所有电脑上可读。编码之后的...标签&#xff1a;03-22html/css场景&#xff1a; 在项目开发过t程中需要找到url中某个参数的值…

tablednd保存 php,JQuery-tableDnD 拖拽的基本使用介绍

在页面上导入js复制代码 代码如下:jquery-1.3.2.min.jsjquery.tablednd_0_5.js注意&#xff1a;一定要先导入jquery-1.3.2.min.js 否则出错。建table复制代码 代码如下:1Onesome text2Twosome text3Threesome text4Foursome text5Fivesome text6Sixsome text插入js代码复制代码…