分布式锁:控制分布式系统不同进程共同访问共享资源的一种锁的实现,一般依托第三方组件来实现,而利用 Redis 实现则是工作中应用最多的一种

Redis 能够用来实现分布式锁的命令有 INCR、SETNX、SET,并利用过期时间命令 expire 作为辅助

  • 互斥性:锁的目的是获取资源的使用权,所以只让一个竞争者持有锁
  • 安全性:持有锁超时,可以释放,防止不必要的资源浪费,也可以防止死锁。
  • 对称性:同一个锁,加锁和解锁必须是同一个竞争者,这又称为锁的可重入性
  • 可靠性:需要有一定程度的异常处理能力、容灾能力

    INCR

    如果 key 不存在,则初始化值为 0,然后再利用 INCR 进行加 1 操作;后续用户如果获取到的值大于等于 1,说明已经被其他线程加锁;当持有锁的用户在执行完任务后,利用 DECR 命令将 key 的值减 1,则表示释放锁

    SETNX

    最简单的实现方式,直接用 setnx 命令加锁,通过 delete 解锁
    1
    setnx key <value>
    如果 key 不存在,则会将 key 设置为 value ,并返回 1;如果 key 存在,返回 0

    expire

    获取锁的服务意外挂掉,锁得不到释放就会造成死锁
    1
    set key <value> nx ex <seconds>

    owner

    放置其他服务使用 delete 命令释放不属于自己的锁

    原子化

    Redis + Lua 脚本实现复合操作原子化

    可靠性

  • 主从复制
  • 哨兵模式
  • 集群模式

    SET

    set 指令有非常复杂的参数,相当于合成了 setnx 和 expire 两条命令的功能;其命令格式如:
    1
    set($Key,$value, array('nx', 'ex'=>$ttl))