基于Redis实现分布式锁(转载)
原文地址:http://blog.csdn.net/ugg/article/details/41894947
Redis命令介绍
使用Redis实现分布式锁,有两个重要函数需要介绍
SETNX命令(SET if Not eXists)
语法:
SETNX key value
功能:
当且仅当 key 不存在,将 key 的值设为 value ,并返回1;若给定的 key 已经存在,则 SETNX 不做任何动作,并返回0。
GETSET命令
语法:
GETSET key value
功能:
将给定 key 的值设为 value ,并返回 key 的旧值 (old value),当 key 存在但不是字符串类型时,返回一个错误,当key不存在时,返回nil。
GET命令
语法:
GET key
功能:
返回 key 所关联的字符串值,如果 key 不存在那么返回特殊值 nil 。
DEL命令
语法:
DEL key [KEY …]
功能:
删除给定的一个或多个 key ,不存在的 key 会被忽略。
兵贵精,不在多。分布式锁,我们就依靠这四个命令。但在具体实现,还有很多细节,需要仔细斟酌,因为在分布式并发多进程中,任何一点出现差错,都会导致死锁,hold住所有进程。
加锁实现
SETNX 可以直接加锁操作,比如说对某个关键词foo加锁,客户端可以尝试
SETNX foo.lock <current unix time>
如果返回1,表示客户端已经获取锁,可以往下操作,操作完成后,通过
DEL foo.lock
命令来释放锁。
如果返回0,说明foo已经被其他客户端上锁,如果锁是非堵塞的,可以选择返回调用。如果是堵塞调用调用,就需要进入以下个重试循环,直至成功获得锁或者重试超时。理想是美好的,现实是残酷的。仅仅使用SETNX加锁带有竞争条件的,在某些特定的情况会造成死锁错误。
处理死锁
在上面的处理方式中,如果获取锁的客户端端执行时间过长,进程被kill掉,或者因为其他异常崩溃,导致无法释放锁,就会造成死锁。所以,需要对加锁要做时效性检测。因此,我们在加锁时,把当前时间戳作为value存入此锁中,通过当前时间戳和Redis中的时间戳进行对比,如果超过一定差值,认为锁已经时效,防止锁无限期的锁下去.
使用Redisson:
分布式Lock
Redisson redisson = Redisson.create();
RLock lock = redisson.getLock("anyLock");
// Most familiar locking method
lock.lock();
// Lock time-to-live support
// releases lock automatically after 10 seconds
// if unlock method not invoked
lock.lock(10, TimeUnit.SECONDS);
// Wait for 100 seconds and automatically unlock it after 10 seconds
boolean res = lock.tryLock(100, 10, TimeUnit.SECONDS);
...
lock.unlock();
分布式MultiLock
RLock lock1 = redissonInstance1.getLock("lock1");
RLock lock2 = redissonInstance2.getLock("lock2");
RLock lock3 = redissonInstance3.getLock("lock3");
RedissonMultiLock lock = new RedissonMultiLock(lock1, lock2, lock3);
lock.lock();
分布式ReadWriteLock
RReadWriteLock rwlock = redisson.getLock("anyRWLock");
// Most familiar locking method
rwlock.readLock().lock();
// or
rwlock.writeLock().lock();
// Lock time-to-live support
// releases lock automatically after 10 seconds
// if unlock method not invoked
rwlock.readLock().lock(10, TimeUnit.SECONDS);
// or
rwlock.writeLock().lock(10, TimeUnit.SECONDS);
// Wait for 100 seconds and automatically unlock it after 10 seconds
boolean res = rwlock.readLock().tryLock(100, 10, TimeUnit.SECONDS);
// or
boolean res = rwlock.writeLock().tryLock(100, 10, TimeUnit.SECONDS);
...
lock.unlock();
分布式Semaphore
RSemaphore semaphore = redisson.getSemaphore("semaphore");
semaphore.acquire();
semaphore.acquire(23);
semaphore.tryAcquire();
semaphore.tryAcquire(23, TimeUnit.SECONDS);
semaphore.release(10);
semaphore.release();
分布式AtomicLong
RAtomicLong atomicLong = redisson.getAtomicLong("myAtomicLong");
atomicLong.set(3);
atomicLong.incrementAndGet();
atomicLong.get();
分布式AtomicDouble
RAtomicDouble atomicDouble = redisson.getAtomicDouble("myAtomicDouble");
atomicDouble.set(2.81);
atomicDouble.addAndGet(4.11);
atomicDouble.get();
分布式CountDownLatch
RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.trySetCount(1);
latch.await();
// in other thread or other JVM
RCountDownLatch latch = redisson.getCountDownLatch("anyCountDownLatch");
latch.countDown();
分布式Blocking Queue
RBlockingQueue<SomeObject> queue = redisson.getBlockingQueue("anyQueue");
queue.offer(new SomeObject());
SomeObject obj = queue.peek();
SomeObject someObj = queue.poll();
SomeObject ob = queue.poll(10, TimeUnit.MINUTES);
除此之外,还支持Queue, Deque, Blocking Deque
基于Redis实现分布式锁(转载)的更多相关文章
- 转载:基于Redis实现分布式锁
转载:基于Redis实现分布式锁 ,出处: http://blog.csdn.net/ugg/article/details/41894947 背景在很多互联网产品应用中,有些场景需要加锁处理,比如 ...
- 基于Redis的分布式锁真的安全吗?
说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...
- 基于redis的分布式锁(转)
基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...
- 基于redis 实现分布式锁的方案
在电商项目中,经常有秒杀这样的活动促销,在并发访问下,很容易出现上述问题.如果在库存操作上,加锁就可以避免库存卖超的问题.分布式锁使分布式系统之间同步访问共享资源的一种方式 基于redis实现分布式锁 ...
- 基于redis的分布式锁
<?php /** * 基于redis的分布式锁 * * 参考开源代码: * http://nleach.com/post/31299575840/redis-mutex-in-php * * ...
- 基于 Redis 的分布式锁
前言 分布式锁在分布式应用中应用广泛,想要搞懂一个新事物首先得了解它的由来,这样才能更加的理解甚至可以举一反三. 首先谈到分布式锁自然也就联想到分布式应用. 在我们将应用拆分为分布式应用之前的单机系统 ...
- 基于redis的分布式锁实现
1.分布式锁介绍 在计算机系统中,锁作为一种控制并发的机制无处不在. 单机环境下,操作系统能够在进程或线程之间通过本地的锁来控制并发程序的行为.而在如今的大型复杂系统中,通常采用的是分布式架构提供服务 ...
- 基于redis的分布式锁(不适合用于生产环境)
基于redis的分布式锁 1 介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分 ...
- 基于 redis 的分布式锁实现 Distributed locks with Redis debug 排查错误
小结: 1. 锁的实现方式,按照应用的实现架构,可能会有以下几种类型: 如果处理程序是单进程多线程的,在 python下,就可以使用 threading 模块的 Lock 对象来限制对共享变量的同步访 ...
- redis系列:基于redis的分布式锁
一.介绍 这篇博文讲介绍如何一步步构建一个基于Redis的分布式锁.会从最原始的版本开始,然后根据问题进行调整,最后完成一个较为合理的分布式锁. 本篇文章会将分布式锁的实现分为两部分,一个是单机环境, ...
随机推荐
- vlc 控件属性和方法
VLC调研 VLC控件支持的参数和方法 VLC对象列表 Vlc Plugin Object的方法 l VersionInfo:成员, 返回版本信息的字符串 l vlc.ve ...
- flask 之(五) --- 对象|钩子|拆分
内置对象 request: 请求的所有信息 session 服务端会话技术的接口 config: 当前项目的配置信息,模板中可以直接使用 g:global 在单次请求过程中,实现全局数据共享 ...
- CodeForces 1249A --- Yet Another Dividing into Teams
[CodeForces 1249A --- Yet Another Dividing into Teams] Description You are a coach of a group consis ...
- c++ | final
C++11的关键字final有两个用途:(1).禁止虚函数被重写:(2).禁止基类被继承. 在派生类中,可以同时使用overried和final.
- (转)Jquery+Ajax实现Select动态定数据
解决思路: 在数据库中建立类型字典式表.将下拉框需要添加的项,在数据库表里中文.英文名称对应起来. 下拉框动态绑定数据库表中需要字段. <div id="bgDiv" sty ...
- Shell初学(五)bash shell的基本功能
记住,所谓的bash shell 并不单纯指的是shell脚本,其实是Linux系统的所有指令集. shell脚本 只是汇总了指令集到文件,然后按流程和顺序执行. [1]如何查看我们的预设shell ...
- java-阿里云发送短信
<!--aliyun短信sdk--> <dependency> <groupId>com.aliyun</groupId> <artifactId ...
- 列出bug的几种状态
1.New:(新的) 当某个“bug”被发现的时候(第一次),测试人员需要与项目负责人沟通以确认发现的的确是一个bug,如果被确认是一个bug,就将其记录下来,并将bug的状态设为New. 2.Ass ...
- golang 多线程查找文件内容
package main import ( "fmt" "io/ioutil" "os" "path/filepath" ...
- Git复习(十一)之常见命令用法
创建版本库 git init 进入一个文件,执行该命令此时目录下多了一个.git的目录,这个目录是Git来跟踪管理版本库的,没事千万不要手动修改这个目录里面的文件,不然改乱了,就把Git仓库给破坏了. ...