【博学谷学习记录】超强总结,用心分享|架构师-基于redis的分布式锁

一、分布式锁

分布式锁可通过mysql、zk、redis实现,其中redis分布式锁的性能最好,zk的一致性做的最好。
京东上可以抢购茅台,然而10万人抢10瓶茅台,并发量很大,后台程序处理稍不注意就容易产生超卖问题。本篇旨在阐述其中产生的问题以及如何解决。

二、问题

2.1 产生超卖问题,使用synchronized

产生超卖问题后,很多同学都会想到使用synchronized锁,本地jvm进程中多个线程能被锁住,但在分布式环境中则会失效。

即本地锁在多节点下会失效。我们需要使用分布式锁,期望在分布式环境下能够提供锁服务,且达到本地锁的效果

2.2 为什么需要分布式锁

1、为了效率:防止不同节点之间做相同的事情,浪费资源(定时任务)
2、为了安全:有些事情在同一时间只允许一个线程去做

2.3 redis分布式锁基于setnx命令—SET if Not eXists

分布式锁:互斥性、锁超时
锁超时:某线程获取锁后,设置超时时间,如果获取锁后执行超时,则释放锁—拒绝死锁的情况
可重入:方法获取锁后,该线程进行递归调用时,再去获取锁,也能获取到锁—避免死锁问题:已获取锁的线程,自己递归去获取锁,如果获取不到,就阻塞

2.4 基于redis实现分布式锁

if(setnx(key, value)==1){
expire(key, 30);
try{
	//业务
    }finally{
    //释放锁
    del key;
    }
}

2.4 原子性

代码中涉及到从redis中获取锁,并设置超时时间两步操作。
这两步操作需要保持原子性,redis是弱事务,那怎么保证原子性?
解决方案
方法1、lua脚本
方法2、2.6以后用set命令

在这里插入图片描述

2.5 业务超时锁释放导致错误解锁

业务执行时间大于锁超时时间,则产生2个问题:
1、线程A和线程B并行执行;
2、错误解锁—A可能把B的锁解了

解决办法:业务没执行完,锁不应该释放
锁续期,看门狗:给锁续期—A的守护线程

2.6 可重入

介绍可重入—避免死锁
加锁和解锁一定是成对出现的

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值