【Redis】回顾下Redis实现分布式锁

CSDN话题挑战赛第2期

回顾下Redis实现分布式锁

  • 分布式锁需要满足哪些条件?
  • Redis最基本的分布式锁实现方式
  • 如何实现数据库与缓存数据一致?

分布式锁需要满足哪些条件?

分布式锁需要满足的一些条件:

  • 多进程互斥:同一时刻,只有一个进程可以获取锁。
  • 保证锁可以释放:任务结束或出现异常,锁一定要释放,避免死锁。
  • 阻塞锁(可选):获取锁失败时可否重试。
  • 重入锁(可选):获取锁的代码递归调用时,依然可以获取锁。
    【Redis】回顾下Redis实现分布式锁_第1张图片

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可重入分布式锁的获取锁和释放锁的实现方式怎样的呢?
这两个问题有会的朋友们欢迎在评论区留言交流解答。在技术的道路上欢迎您来指导解惑交流。

你可能感兴趣的:(Redis知识点回顾,redis,分布式,数据库)