持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
基于缓存实现分布式锁
-
这里的缓存我们大多数情况下会认为是redis加锁,redis实现加锁的逻辑其实和数据库加锁是一样的。但是redis并没有唯一建这个特征,所以redis是在添加的地方做的手脚,他通过保证对于同一颗key值始终智能有一个线程能成功写入,并发时其他线程在写入就会失败。基于这个原理redis就可以实现锁的功能了。同时上锁失败也不会造成额外的开销。
-
在上锁时会涉及到五个属性
-
我们使用key来当锁,因为key是唯一的。
-
这里写的是锁竞争者的id,在解锁时,我们需要判断当前解锁的竞争者id是否为锁持有者。
-
这个参数我们填的是NX,意思是SET IF NOT EXIST,即当key不存在时,我们进行set操作;若key已经存在,则不做任何操作。
-
这个参数我们传的是PX,意思是我们要给这个key加一个过期时间的设置,具体时间由第五个参数决定;
-
与第四个参数相呼应,代表key的过期时间。
解锁
- 这解锁就自然对应了我们的删除操作了。只需要吧对应的key删除我们其他线程就可以正常的添加到redis中了。和mysql锁都存在一个问题如果A线程上锁之后被其他分布式的B线程进行删除了怎么办呢?那么我的锁就没有的安全性可言了。
- mysql中呢我们加入了线程ID机制,这样保证了其他线程无法参与,同样的在redis锁中我们同样加入线程ID作为key这样就保证了其他线程不能破坏这把锁了。同时也解决了我们的可冲入式的问题。
总结
- 相比mysql而言redis锁大家更喜欢使用,因为redis可言设置过期时间,这个机制避免了死锁的发生的概率