我的编程空间,编程开发者的网络收藏夹
学习永远不晚

怎么利用Redis锁解决高并发

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

怎么利用Redis锁解决高并发

小编给大家分享一下怎么利用Redis锁解决高并发,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!

redis技术的使用:

redis真的是一个很好的技术,它可以很好的在一定程度上解决网站一瞬间的并发量,例如商品抢购秒杀等活动。。。

redis之所以能解决高并发的原因是它可以直接访问内存,而以往我们用的是数据库(硬盘),提高了访问效率,解决了数据库服务器压力。

为什么redis的地位越来越高,我们为何不选择memcache,这是因为memcache只能存储字符串,而redis存储类型很丰富(例如有字符串、LIST、SET等),memcache每个值最大只能存储1M,存储资源非常有限,十分消耗内存资源,而redis可以存储1G,最重要的是memcache它不如redis安全,当服务器发生故障或者意外关机等情况时,redsi会把内存中的数据备份到硬盘中,而memcache所存储的东西全部丢失;这也说明了memcache不适合做数据库来用,可以用来做缓存。

引言

这里我们主要利用Redis的setnx的命令来处理高并发。

setnx 有两个参数。第一个参数表示键。第二个参数表示值。如果当前键不存在,那么会插入当前键,将第二个参数做为值。返回 1。如果当前键存在,那么会返回0。

创建库存表

CREATE TABLE `storage` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `number` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1

设置初始库存为10

创建订单表

CREATE TABLE `order` (
 `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
 `number` int(11) DEFAULT NULL,
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1

测试不用锁的时候

$pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'root');
$sql="select `number` from storage where id=1 limit 1";
$res = $pdo->query($sql)->fetch();
$number = $res['number'];
if($number>0)
{
 $sql ="insert into `order` VALUES (null,$number)";

 $order_id = $pdo->query($sql);
 if($order_id)
 {

 $sql="update storage set `number`=`number`-1 WHERE id=1";
 $pdo->query($sql);
 }
}

ab测试模拟并发,发现库存是正确的。

mysql> select * from storage;
+----+--------+
| id | number |
+----+--------+
| 1 | 0 |
+----+--------+
1 row in set (0.00 sec)

在来看订单表

mysql> select * from `order`;
+----+--------+
| id | number |
+----+--------+
| 1 | 10 |
| 2 | 10 |
| 3 | 9 |
| 4 | 7 |
| 5 | 6 |
| 6 | 5 |
| 7 | 5 |
| 8 | 5 |
| 9 | 4 |
| 10 | 1 |
+----+--------+
10 rows in set (0.00 sec)

发现存在几个订单都是操作的同一个库存数据,这样就可能引起超卖的情况。

修改代码加入redis锁进行数据控制

<?php

class Lock
{
 private static $_instance ;
 private $_redis;
 private function __construct()
 {
 $this->_redis = new Redis();
 $this->_redis ->connect('127.0.0.1');
 }
 public static function getInstance()
 {
 if(self::$_instance instanceof self)
 {
  return self::$_instance;
 }
 return self::$_instance = new self();
 }

 
 public function set($key,$expTime)
 {
 //初步加锁
 $isLock = $this->_redis->setnx($key,time()+$expTime);
 if($isLock)
 {
  return true;
 }
 else
 {
  //加锁失败的情况下。判断锁是否已经存在,如果锁存在切已经过期,那么删除锁。进行重新加锁
  $val = $this->_redis->get($key);
  if($val&&$val<time())
  {
  $this->del($key);
  }
  return $this->_redis->setnx($key,time()+$expTime);
 }
 }


 
 public function del($key)
 {
 $this->_redis->del($key);
 }

}



$pdo = new PDO('mysql:host=127.0.0.1;dbname=test', 'root', 'root');
$lockObj = Lock::getInstance();
//判断是能加锁成功
if($lock = $lockObj->set('storage',10))
{
 $sql="select `number` from storage where id=1 limit 1";
 $res = $pdo->query($sql)->fetch();
 $number = $res['number'];
 if($number>0)
 {
 $sql ="insert into `order` VALUES (null,$number)";

 $order_id = $pdo->query($sql);
 if($order_id)
 {

  $sql="update storage set `number`=`number`-1 WHERE id=1";
  $pdo->query($sql);
 }
 }
 //解锁
 $lockObj->del('storage');

}
else
{
 //加锁不成功执行其他操作。
}

再次进行ab测试,查看测试结果

mysql> select * from `order`;
+----+--------+
| id | number |
+----+--------+
| 1 | 10 |
| 2 | 9 |
| 3 | 8 |
| 4 | 7 |
| 5 | 6 |
| 6 | 5 |
| 7 | 4 |
| 8 | 3 |
| 9 | 2 |
| 10 | 1 |
+----+--------+
10 rows in set (0.00 sec)

发现订单表没有操作同一个库存数据的情况。所以利用redis锁是可以有效的处理高并发的。

这里在加锁的时候其实是可以不需要判断过期时间的,这里我们为了避免造成死锁,所以加一个过期时间的判断。当过期的时候主动删除该锁。

看完了这篇文章,相信你对“怎么利用Redis锁解决高并发”有了一定的了解,如果想了解更多相关知识,欢迎关注亿速云行业资讯频道,感谢各位的阅读!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

怎么利用Redis锁解决高并发

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

redis怎么解决高并发

redis 提供多种高并发解决方案:1. 集群分片数据,提升吞吐量和容错性;2. 复制确保数据可用性和提升读性能;3. 管道减少网络开销,提高吞吐量;4. 事务保证原子性,防止数据不一致;5. lua 脚本减少通信,提高性能;6. 发布/订
redis怎么解决高并发
2024-06-03

redis链接高并发导致锁死怎么解决

当Redis遇到高并发的情况可能会导致锁死,可以考虑以下几种解决办法:1. 使用分布式锁:通过使用分布式锁,可以将锁的控制权交给其他节点,避免单点故障。可以使用Redis自带的RedLock或者第三方的Zookeeper、Etcd等实现分布
2023-08-23

Redis怎么加锁实现高并发

在Redis中可以使用SETNX命令实现简单的分布式锁。SETNX命令是一个原子操作,用于设置一个键的值,如果该键不存在,则设置成功并返回1,如果该键已经存在,则设置失败并返回0。使用SETNX命令可以实现基本的加锁和解锁操作,具体步骤如下
2023-08-31

redis锁如何解决并发

redis锁是一种解决并发访问共享资源时竞态条件的分布式锁机制。它通过以下步骤实现:使用setnx命令,在键不存在时设置一个键来获取锁。使用expire命令为锁设置一个过期时间,以防止死锁。使用del命令释放锁,当客户端完成对受保护资源的访
redis锁如何解决并发
2024-06-12

php redis并发锁怎么使用

Redis并发锁的原理和使用Redis并发锁基于SETNX命令,用于在Redis中设置一个唯一的键。当一个客户端获取锁时,它会发送SETNX,指定键和超时时间。如果成功,表示锁已被获取。使用方法:生成唯一键使用SETNX设置锁获取锁执行临界区代码释放锁(使用DEL)超时时间至关重要,防止死锁。注意:非阻塞锁定时间应适中定期刷新超时时间考虑网络延迟和故障替代方案:互斥锁、乐观锁和悲观锁。
php redis并发锁怎么使用
2024-04-13

redis如何解决高并发

redis 高效解决高并发问题,主要得益于以下机制:1)内存存储,极速读写;2)单线程事件循环,无锁竞争;3)多路复用 i/o,同时监听多个连接;4)优化数据结构,快速查找、插入和删除;5)复制和集群,负载均衡和容错;6)持久化,确保数据安
redis如何解决高并发
2024-06-12

详解利用redis + lua解决抢红包高并发的问题

抢红包的需求分析 抢红包的场景有点像秒杀,但是要比秒杀简单点。因为秒杀通常要和库存相关。而抢红包则可以允许有些红包没有被抢到,因为发红包的人不会有损失,没抢完的钱再退回给发红包的人即可。另外像小米这样的抢购也要比淘宝的要简单,也是因为像小米
2022-06-04

如何使用Redis解决高并发

这篇文章主要介绍了如何使用Redis解决高并发的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇如何使用Redis解决高并发文章都会有所收获,下面我们一起来看看吧。NoSQLNot Only SQL的简称。NoSQ
2023-07-05

redis怎么用于高并发

redis通过以下优化适用于高并发场景:1. 内存存储,消除磁盘i/o延迟;2. 针对高并发优化的数据结构;3. 主从复制提供冗余和可伸缩性;4. rdb和aof持久化机制确保数据安全;5. 集群工具提高可伸缩性和可用性;6. 发布/订阅实
redis怎么用于高并发
2024-05-21

redis怎么实现并发锁

Redis可以使用SETNX(SET if Not eXists)命令实现并发锁。以下是一个使用Redis实现并发锁的示例代码:```pythonimport redisimport timedef acquire_lock(redis_c
2023-08-30

redis如何解决高并发JAVA

Redis用于解决高并发Java问题,其机制包括:内存存储,绕过磁盘I/O瓶颈,提升性能。单线程模型,保证指令原子性和顺序性,避免竞争。数据结构优化,提供特定数据类型的快速访问。客户端连接池,管理连接,提高并发吞吐量。异步处理,减少客户端等待时间。持久化,通过快照和追加日志保证数据安全。集群模式,分片和负载均衡提升并发能力。复制和Sentinel,实现故障转移和高可用性。Pub/Sub,支持实时数据更新和消息队列。
redis如何解决高并发JAVA
2024-04-02

redis分布式锁发生死锁怎么解决

当Redis分布式锁发生死锁时,可以采取以下几种解决方案:1. 设置锁的超时时间:在获取锁时,设置一个合理的锁超时时间,确保即使锁没有被正常释放,也能够自动释放掉。可以使用Redis的`SET`命令设置带有超时时间的锁,然后在获取锁时检查是
2023-08-24

dubbo怎么解决高并发

要解决Dubbo的高并发问题,可以从以下几个方面着手:1. 调整Dubbo的配置:可以通过调整Dubbo的线程池和连接池等参数,增加线程数和连接数的数量,以提高系统的并发处理能力。2. 使用集群部署:可以将Dubbo的服务提供者节点进行集群
2023-10-20

redis并发锁时间怎么设置

在 Redis 中实现并发锁,可以使用 SETNX(SET if Not eXists)指令。该指令会在键不存在时设置键的值,如果键已经存在,则不执行任何操作。在并发锁的场景中,可以将锁的持有者设置为一个唯一的标识,比如使用线程或进程的 I
2023-08-30

使用Redis解决高并发方案及思路解读

目录NoSQLRedis痛点思路分布式锁锁续命扩展结语NoSQLNot Only SQL的简称。NoSQL是解决传统的RDBMS在应对某些问题时比较乏力而提出的。即非关系型数据库,它们不保证关系数据的ACID特性,数据之间一般没有关联,
2023-03-31

SpringBoot如何使用 Redis 分布式锁解决并发问题

这期内容当中小编将会给大家带来有关SpringBoot如何使用 Redis 分布式锁解决并发问题,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。问题背景现在的应用程序架构中,很多服务都是多副本运行,从而保证
2023-06-25

编程热搜

目录