首页 » 网站推广 » phpsetnx技巧_分布式锁系列一基于Redis SETNX敕令实现分布式锁

phpsetnx技巧_分布式锁系列一基于Redis SETNX敕令实现分布式锁

访客 2024-11-21 0

扫一扫用手机浏览

文章目录 [+]

目前大多数单体运用系统中,微做事运用系统中以及分布式系统中,Redis作为缓存中间件被广泛利用。
Redis被公认的是基于内存的,高效的,支持多种数据构造的缓存框架,Redis官方网站有这样一段话,对其进行了清晰的描述:

Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache, and message broker. Redis provides data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes, and streams.

phpsetnx技巧_分布式锁系列一基于Redis SETNX敕令实现分布式锁

从Redis的官方文档描述,Redis不仅仅可以用来作为高效的数据缓存;基于Redis的高等特性,我们可以基于Redis实现行列步队,分布式锁等功能。

phpsetnx技巧_分布式锁系列一基于Redis SETNX敕令实现分布式锁
(图片来自网络侵删)

在单体运用系统中,所有的业务和功能都在一个运用系统中,也相称所有业务和功能都在一个线程中运行,如果须要对某一资源或者某一变量进行加锁操作,我们完备可以基于程序本身利用的措辞的锁机制来实现,比如Java我们可以采取synchronized和Lock的实现类。

在分布式和微做事系统中,不同功能或者不同业务被拆分成独立的运用,并且完成独立的功能。
在支配办法上独立的运用分别被支配到不同的机器上,以及采取集群化支配,一个独立的运用被支配为多个副本。
比较于单体运用最直不雅观的差异是:不同的功能或者不同的业务是跨进程运行。

那么,在分布式运用系统中,我们如何对某一竞争资源进行加锁操作呢?

答案:当然是我们须要一种分布式锁机制。

实现分布式锁有多种办理方案,常用的办理方案整理如下:

基于Redis对字符串操作命令SETNX实现;基于Zookeeper的临时有序节点实现;

由于Redis是单线程的,基于命令SETNX(set if not exists)可以实现锁的机制;

当一个key在Redis中不存在时;返回1(成功);

当一个key在Redis中存在时;返回0(失落败);

127.0.0.1:6379> SETNX abc 1(integer) 1127.0.0.1:6379> SETNX abc 1(integer) 0

在Redis的帮助文档中,对该SETNX命令是这样描述的:

127.0.0.1:6379> help @string ........................................ SETNX key value summary: Set the value of a key, only if the key does not exist since: 1.0.0

下面我们通过一个大略的demo来演示下,基于Redis如何实现分布式锁机制。

新建一个Java工程redis-distributed-lock,maven依赖如下:

<dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId></dependency>

redisson封装了对Redis的大多数操作命令,相称于Redis的Java客户端。
我们只须要做大略的配置,就可以像redis-cli那样操作Redis。
当然,这里也可以选择其他的Redis Java客户端,例如Jedis,RedisTemplate等。

定义一个main函数

public class RedisLockDemo { public static void main(String[] args) throws IOException { Config config = new Config(); config.useSingleServer().setAddress("redis://localhost:6379"); config.useSingleServer().setPassword("123456"); RedissonClient redissonClient = Redisson.create(config); RLock rLock = redissonClient.getLock("lock"); for (int i = 0; i < 20; i++) { //开启自线程 new Thread(() -> { //加锁 rLock.lock(); System.out.println(Thread.currentThread().getName() + " 获取锁"); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } finally { //开释锁 rLock.unlock(); } }).start(); } }}

在这里我们采取多线程来仿照一个分布式系统,每一个线程代表一个独立的运用系统。
我们在同一韶光开启20个线程,这20个线程同时去抢占锁,如果某一线程抢占到锁,则打印“获取到锁”,没有抢占到锁的线程则处于等待状态。
当某一线程抢占到锁后,完成操作后开释掉锁,则其他未抢占到锁的线程被唤醒,并且同时再一次去抢占锁。

运行mian函数实行结果如下:

实行结果

从代码层面和运行结果层面,我们可以看到基于Redis实现了分布式锁的机制。
redisson这个Java版的Redis客户端封装了对锁的实现细节,详细封装了如下:

所有线程同时抢占锁,以及抢占到锁的线程开释锁;未抢占到锁的线程壅塞等待;抢占到锁的线程开释锁后,唤醒未抢占到锁的线程,并且同时再次抢占锁;

参考:

https://redis.io/

demo源码:

https://github.com/bq-xiao/distributed-lock-demo.git

不积跬步,无以至千里;不积小流,无以成江海!

标签:

相关文章

今日头条算法引领个化信息时代的变革

信息爆炸时代已经到来。每个人都是信息的接收者和传播者。面对海量的信息,人们往往感到无所适从。为了解决这一问题,各大互联网公司纷纷推...

网站推广 2025-01-31 阅读1 评论0

今日头条算法信息推荐的秘密武器

信息爆炸的时代已经来临。人们每天都会接触到大量的信息,而如何从这些信息中筛选出有价值的内容,成为了亟待解决的问题。今日头条算法作为...

网站推广 2025-01-31 阅读1 评论0

今日头条算法精准推荐背后的技术奥秘

信息爆炸的时代已经来临。我们每天都要面对海量的信息,如何从这些信息中筛选出自己感兴趣的内容,成为了每个人都关心的问题。今日头条作为...

网站推广 2025-01-31 阅读1 评论0