Redis实现分布式锁机制的原理

Redis中实现分布式锁机制
加锁

  1. 使用setnx(商品ID,1);
  2. 返回0,代表redis里面有数据,即数据已经加锁;
  3. 返回1,代表redis里面没有数据,即可以获得锁。

解锁
使用redis的del 商品ID命令,删除其中的变量

锁超时
使用expired命令设置超时时间(在加锁的时候设置过期时间)

请求1
请求2
从数据库中获取商品信息
从数据库中获取商品信息
订单服务1
Redis中间件
订单服务2
数据库

Redis中间件将多进程访问变为多线程访问,因此,虽然订单服务是并发地发送请求,但是经过Redis后,变成了串行访问。
这样就能保证在购买同一个商品,实现分布式锁。

上述过程存在三个问题:

1.非原子操作

上述的锁超时机制中,先执行setnx,后执行expire。若中间服务器宕机了,可能导致死锁;

解决方案:使用Redis中提供的set命令:set(key, value, expire)

2. 误删锁

数据操作1没有完成,若设置超时时间为30秒,即操作没有在30秒之内完成;
此时另一个数据操作2过来,并加锁;
数据操作1操作完成,将数据操作2的锁删除了。

解决方案:判断是不是自己的锁,只删除自己的锁,利用之前set的value来区分是否是自己的锁。例如,value设置的是线程ID,则在删除锁的时候带着商品ID和线程ID是不是自己的锁,是则删除。

3. 提前释放锁

问题2中没有解决如何保证数据处理完成之后才释放锁的问题,这里可以通过守护线程方式解决。

解决方案:同时开辟两个线程,线程1是专门用来处理数据的线程,线程2是守护线程。守护线程主要负责在即将过期的时候判断是否处理完成,若未处理完成则加时。

注意:此时,若该服务器宕机,Redis会自动解锁。

猜你喜欢

转载自blog.csdn.net/zyxhangiian123456789/article/details/106810513