CSDN话题挑战赛第2期
回顾下Redis实现分布式锁
分布式锁需要满足哪些条件?
分布式锁需要满足的一些条件:
- 多进程互斥:同一时刻,只有一个进程可以获取锁。
- 保证锁可以释放:任务结束或出现异常,锁一定要释放,避免死锁。
- 阻塞锁(可选):获取锁失败时可否重试。
- 重入锁(可选):获取锁的代码递归调用时,依然可以获取锁。
Redis最基本的分布式锁实现方式
Redis使用setnx命令,这个命令的特征是如果多次执行,只有第一次执行会成功,可以实现
互斥
的效果。但是为了保证服务宕机时也可以释放锁,需要利用expire命令给锁设置一个有效期,过期后就失效释放了。
setnx lock thread-1 # 尝试获取锁
expire lock 10 # 设置有效期
那如果在设置expire之前服务宕机怎么办?解决办法:要保证set NX和expire(EX)命令的原子性。
redis的set命令可以这样操作:
set key value [NX] [EX time]
在释放锁的时候,如果自己的锁已经过期了,此时会出现安全漏洞,如何解决?
在锁中存储当前进程和线程标识,释放锁时对锁的标识判断,如果是需要删除的数据就删除,不是则放弃操作。但是这两步操作要保证原子性,需要通过Lua脚本来实现:
if redis.call("get",KEYS[1]) == ARGV[1] then
redis.call("del",KEYS[1])
end
如何实现数据库与缓存数据一致?
实现方案有下面几种:
- 本地缓存同步:
当前微服务的数据库数据与缓存数据同步,可以直接在数据库修改时加入对Redis的修改逻辑,保证一致。
- 跨服务缓存同步:
服务A调用了服务B,并对查询结果缓存。服务B数据库修改,可以通过MQ通知服务A,服务A修改Redis缓存数据。
- 通用方案:
使用Canal框架,伪装成MySQL的salve节点,监听MySQL的binLog变化,然后修改Redis缓存数据。
面对分布式锁留下了几个问题:
1.Redis可以实现可重入分布式锁吗?
2.Redis可重入分布式锁的获取锁和释放锁的实现方式怎样的呢?
这两个问题有会的朋友们欢迎在评论区留言交流解答。在技术的道路上欢迎您来指导解惑交流。
版权归原作者 小冷coding 所有, 如有侵权,请联系我们删除。