玖叶教程网

前端编程开发入门

Redis分布式锁最全详解(图文全面总结)

分布式锁是分布式系统的核心,也是大厂重点考察对象,下面我就全面来详解Redis分布式锁@mikechen

本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》里面。

分布式锁

分布式锁是一种用于在分布式系统中,协调多个进程、或者多个节点,对共享资源的访问机制。

如下图所示:

多台Jboss应用服务器上的JVM,需要访问:“共享变量”,这种典型的多个进程争夺资源,就需要分布式锁来保证资源安全性。

分布式锁可以确保同一时刻,只有一个节点能够修改数据,这样可以,防止数据冲突、和不一致的发生。

要实现分布式锁,一般需要,满足如下核心关键点:

1.互斥性

在同一时刻,只有一个客户端能持有锁;

比如:使用分布式缓存系统(如:Redis)的,SETNX(SET if Not eXists)命令来创建锁。

只有当锁不存在时才能成功创建,确保了互斥性。

2.可重入性

同一个客户端可以多次获取同一把锁,必须要确保是同一个客户端。

比如:每个客户端在获取锁时,附带一个唯一的标识(如:UUID),如果同一个客户端尝试多次获取同一把锁,可以通过这个标识来判断并允许重入。

3.高可用性

锁的获取、和释放操作应该是高可用的。

比如:将锁服务部署成主备结构,当主节点失效时,备节点可以立即接管。

4.容错性

如果持有锁的客户端崩溃,锁能够被其他客户端重新获取。

比如:设置锁的自动过期时间,即使客户端崩溃,锁在过期后也能被其他客户端获取。

Redis分布式锁实现

下面,我以Redis为例,实现分布式锁:

1.获取锁

使用 SET key value NX PX milliseconds 命令:

SET my_lock_key my_lock_value NX PX 10000

参数说明:

  • SET:用于设置键的值;
  • my_lock_value:锁的值(value),通常是唯一的标识符,例如:UUID,用于区分锁的持有者;
  • NX:表示“仅在键不存在时设置”,即如果键已经存在,则不会执行设置操作,这保证了只有一个客户端能够成功设置锁;
  • PX:设置键的过期时间(以毫秒为单位),这用于防止持有锁的客户端崩溃导致的死锁问题,即使客户端崩溃,锁也会在过期后自动释放。
  • PX 10000:设置锁的过期时间为10000毫秒(即:10秒),防止锁被永久占用。

2.释放锁

使用Lua脚本,可以确保锁的释放是原子操作:

脚本会检查,当前键的值是否与持锁客户端的值匹配,如果匹配则删除键;

如果不匹配,表示锁的持有者不是当前客户端,删除操作不会执行。

如下所示:

public void release() {
        // 使用Lua脚本来确保释放操作的原子性
        String script = 
            "if redis.call('get', KEYS[1]) == ARGV[1] then " +
            "return redis.call('del', KEYS[1]) " +
            "else " +
            "return 0 " +
            "end";
        jedis.eval(script, 1, lockKey, lockValue);
    }

参数说明:

  • redis.call('get', KEYS[1]):获取锁的当前值;
  • == ARGV[1]:检查当前值是否与持锁客户端的值(ARGV[1])匹配;
  • redis.call('del', KEYS[1]):如果匹配,则删除键,释放锁;

3.注意事项

  • 过期时间:确保设置适当的过期时间,避免锁被持有太长时间导致资源被锁定。
  • 错误处理:在实际应用中,需要处理可能的异常情况,例如Redis连接失败等。
  • 性能优化:在高并发环境下,确保Redis服务器的性能能够满足锁的需求,并适当调整Redis配置以优化性能。

以上

本篇已收于mikechen原创超30万字《阿里架构师进阶专题合集》里面。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言