基于redis 实现分布式锁的方案
在电商项目中,经常有秒杀这样的活动促销,在并发访问下,很容易出现上述问题。如果在库存操作上,加锁就可以避免库存卖超的问题。分布式锁使分布式系统之间同步访问共享资源的一种方式
基于redis实现分布式锁的原理:
redis为单进程单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系。其次Redis提供一些命令SETNX,GETSET,这些命令是原子操作,利用这些特性,
可以很充分的实现分布式锁。SETNX,GETSET 命令如下:
SETNX key value
功能:当且仅当 key 不存在,将 key 的值设为 value ,并返回1;若给定的 key 已经存在,则 SETNX 不做任何动作,并返回0。
GETSET key value
功能:将给定 key 的值设为 value ,并返回 key 的旧值 (old value),当 key 存在但不是字符串类型时,返回一个错误,当key不存在时,返回null
实现要点:
1、避免死锁,必要的超时机制。设置时间戳,时间戳要精确到毫秒。如果获取锁失败,则说明锁被其他对象保持,检查其是否超时
2、释放锁时,避免释放非自己获得的锁,释放锁时,可以做一个是否超时的检查,如果超时说明锁就无需释放了
3、为了造成不必要的资源浪费,提高并发,最好在最小颗粒度上的块加锁
4、为了降低redis 压力,获取锁尝试时,循环之间一定要做sleep操作
参考源代码如下
// redis client
private Redistemplate tradeRedisTemplate
private Boolean setNX(String key, String value){
return redisConnection.setNX(key.bytes, value.bytes)
}
private String getSet(String key, String value){
byte[] result = redisConnection.getSet(key.bytes, value.bytes)
return new String(result)
}
//释放锁 key 锁名称,time 超时时间
public Void delDistributedLock(String key, Long time){
String lastTimeS = tradeRedisTemplate.opsForValue().get(key)
if(System.currentTimeMillis() - Long.parseLong(lastTimeS) < time){//避免删除非自己获取得到的锁
tradeRedisTemplate.delete(key)
}
}
//加锁 key 锁名称,time 超时时间
public Boolean acquireDistributedLock(String key, Long time){
if(setNX(key, Long.toString(System.currentTimeMillis()))){ //SETNX成功,则成功获取一个锁
return true
}else{
//SETNX失败,说明锁仍然被其他对象保持,检查其是否已经超时
String lastTimeS = tradeRedisTemplate.opsForValue().get(key)
Long lastTime = Long.parseLong(lastTimeS)
//超时
if(System.currentTimeMillis() - lastTime > time){
String lastTimeRedis = getSet(key, Long.toString(System.currentTimeMillis()))
if(lastTimeRedis.equals(lastTimeS)){// 获取锁成功
return true
}
// 已被其他进程捷足先登了
}
}
return false
}
参考资料:
http://redis.io/commands/setnx
http://www.blogjava.NET/caojianhua/archive/2013/01/28/394847.html
基于redis 实现分布式锁的方案的更多相关文章
- 基于redis的分布式锁实现方案--redisson
实例代码地址,请前往:https://gitee.com/GuoqingLee/distributed-seckill redis官方文档地址,请前往:http://www.redis.cn/topi ...
- 基于Redis的分布式锁真的安全吗?
说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...
- 基于 redis 的分布式锁实现 Distributed locks with Redis debug 排查错误
小结: 1. 锁的实现方式,按照应用的实现架构,可能会有以下几种类型: 如果处理程序是单进程多线程的,在 python下,就可以使用 threading 模块的 Lock 对象来限制对共享变量的同步访 ...
- 基于redis 实现分布式锁(二)
https://blog.csdn.net/xiaolyuh123/article/details/78551345 分布式锁的解决方式 基于数据库表做乐观锁,用于分布式锁.(适用于小并发) 使用me ...
- 从零到一手写基于Redis的分布式锁框架
1.分布式锁缘由 学习编程初期,我们做的诸如教务系统.成绩管理系统大多是单机架构,单机架构在处理并发的问题上一般是依赖于JDK内置的并发编程类库,如synchronize关键字.Lock类等.随着业务 ...
- 基于Redis的分布式锁到底安全吗(下)?
2017-02-24 自从我写完这个话题的上半部分之后,就感觉头脑中出现了许多细小的声音,久久挥之不去.它们就像是在为了一些鸡毛蒜皮的小事而相互争吵个不停.的确,有关分布式的话题就是这样,琐碎异常,而 ...
- 基于Redis的分布式锁到底安全吗(上)?
基于Redis的分布式锁到底安全吗(上)? 2017-02-11 网上有关Redis分布式锁的文章可谓多如牛毛了,不信的话你可以拿关键词“Redis 分布式锁”随便到哪个搜索引擎上去搜索一下就知道了 ...
- 基于Redis的分布式锁安全性分析-转
基于Redis的分布式锁到底安全吗(上)? 2017-02-11 网上有关Redis分布式锁的文章可谓多如牛毛了,不信的话你可以拿关键词“Redis 分布式锁”随便到哪个搜索引擎上去搜索一下就知道了 ...
- 基于Redis的分布式锁和Redlock算法
1 前言 前面写了4篇Redis底层实现和工程架构相关文章,感兴趣的读者可以回顾一下: Redis面试热点之底层实现篇-1 Redis面试热点之底层实现篇-2 Redis面试热点之工程架构篇-1 Re ...
随机推荐
- java Io流向指定文件输入内容
package com.hp.io; import java.io.*; public class BufferedWriterTest{ public static void main(String ...
- IT基础架构规划方案一(网络系统规划)
背景 某集团经过多年的经营,公司业务和规模在不断发展,公司管理层和IT部门也认识到通过信息化手段可以更好地支撑公司业务运营.提高企业生产和管理效率.同时随着新建办公 ...
- [转载]C#委托和事件(Delegate、Event、EventHandler、EventArgs)
原文链接:http://blog.csdn.net/zwj7612356/article/details/8272520 14.1.委托 当要把方法作为实参传送给其他方法的形参时,形参需要使用委托.委 ...
- 【JS基础】数组
filter() 返回数组中的满足回调函数中指定的条件的元素. array1.filter(callbackfn[, thisArg]) 对数组array1中的每个元素调用回调函数callbackfn ...
- win7 由ie8升级ie11时安装不成功的一个原因
纯净win7系统更新好补丁好 升级ie一直提示不成功,之前重来没有遇到过.官方提示的解决办法: https://support.microsoft.com/zh-cn/kb/2872074 根据内容初 ...
- 传统软件和SaaS,差异究竟在哪里
这篇文章从创业起步阶段.产品形态和产品策略.市场竞争格局三个方面比较了中美 SaaS 领域的异同,在文章的最后,作者根据自己在 Box 的工作经历对在国内做 SaaS 的公司提出了四点建议. 我曾有幸 ...
- 释放Android的函数式能量(I):Kotlin语言的Lambda表达式
原文标题:Unleash functional power on Android (I): Kotlin lambdas 原文链接:http://antonioleiva.com/operator-o ...
- React Native JSX value should be expression or a quoted JSX text.
问题描述: 我在使用props时候, 我的写法是这样的 ... <View> <Person name='john' age=32 gender=true></Pers ...
- iOS---关于UIWebView
1.加载的web界面可以自由收缩 webView.scalesPageToFit = YES;
- iOS字体加载三种方式
静态加载 动态加载 动态下载苹果提供的多种字体 其他 打印出当前所有可用的字体 检查某字体是否已经下载 这是一篇很简短的文章,介绍了 iOS 自定义字体加载的三种方式. 静态加载 这个可以说是最简单最 ...