Redis分布式锁,蚂蚁金服面试题
1. 什么是分布式锁
分布式锁是控制分布式系统或不同系统之间共同访问共享资源的一种锁实现。如果不同的系统或同一个系统的不同主机之间共享了某个资源时,往往通过互斥来防止批次干扰。
分布式锁可以保证分布式部署的应用集群中,同一个方法在同一个操作只能被一台机器上的一个线程执行。
要满足一下三点:
1. 互斥性,在任意时刻,只能有一个客户端拥有锁去操作数据。
2. 不会产生死锁,即使某一客户端在使用过程中崩溃而没有解锁,也能保证不影响其他客户端加锁。
3. 解铃还须系铃人,加锁和解锁的必须是同一个客户端。
2. 分布式锁实现基本思路
1. 获取锁的时候,用 setnx 加锁,key为被锁的数据的唯一标识,value为当前服务器ip和任务标识的拼接,在释放锁的时候进行判断。并用expire命令为锁添加过期时间,超过该时间则自动释放锁。
2. 获取锁的时候调用 setnx,如果返回0,则该锁正在被别人使用,返回1则成功获取锁,还设置一个获取的超时时间。
3. 释放锁的时候,判断是不是该锁,若是,则执行 delete 进行释放。
3. Redis分布式锁经常遇到的问题
1. A服务加锁,key: job value: 127.0.0.1, 执行时间超过锁的时间。而这个时候服务B加锁,key: job value: 127.0.0.2。过了一段时间A服务执行完了,A解锁,但是这个锁是B加的。
解锁的时候加入判断,看看解锁和加锁是不是同一服务。
2. 可能遇到服务器崩溃的问题,A服务加锁,调用setnx,而这个时候服务器崩溃了,没有设置锁的超时时间。这就会导致其他的服务不能加锁。
解决的办法有两种,一个是使用Lua脚本,把两个命令合起来使用。另一种办法就是用 redisTemplate.execute 把两个命令合起来使用。
4. 常见的Redis使用场景
1. 集群的任务调度系统,在某个时间点出发调度,抢到锁的系统执行调度任务。
2. 在秒杀系统中,为防止被抢购的商品出现负数,可以使用分布式锁。
.....