Redis实现分布式锁(看这篇就够了)

Redis实现分布式锁(看这篇就够了)-mikechen

什么是分布式锁?

分布式锁,即分布式系统中的锁,是为了解决分布式系统共享资源访问的问题,在分布式系统加锁,这就是分布式锁。

 

为什么需要分布式锁?

在分布式环境中,多个进程或线程可能同时竞争访问共享资源,而分布式锁可以确保在给定的时间内,只有一个进程或线程能够成功获取锁并执行关键操作,从而保证了数据的一致性和正确性。

首先在传统单机部署的情况下,在Java多线程并发竞争资源场景,可以使用ReentrantLcokSynchronized进行互斥控制,用于解决单机并发共享资源问题。

如下图所示:

Redis实现分布式锁(看这篇就够了)-mikechen

但是在分布式系统后,由于分布式系统是分布在不同机器上,这将使原单机并发控制锁策略失效。

Redis实现分布式锁(看这篇就够了)-mikechen

为了解决这个问题就需要一种跨JVM的互斥机制,来控制共享资源的访问,这就是分布式锁要解决的问题。

 

Redis实现分布式锁

对于一个锁来说,其实只有两个操作,加锁和释放锁,下面我们看来看通过 Redis 要怎么实现?

下面是使用Redis实现分布式锁的步骤:

  1. 创建Redis连接:使用Redis客户端库连接到Redis服务器。
  2. 获取锁:尝试获取锁,可以使用Redis的SET命令设置一个带有超时时间的锁键,确保只有一个客户端能够成功设置该键。
  3. 执行关键操作:成功获取锁后,执行需要保护的关键操作,处理共享资源或关键任务。
  4. 释放锁:操作完成后,释放锁资源,删除锁键,让其他客户端有机会获取锁。

下面是一个使用Jedis作为Redis客户端库的分布式锁示例代码:

import redis.clients.jedis.Jedis;

public class DistributedLockExample {

    public static void main(String[] args) {
        // 创建Redis连接
        Jedis jedis = new Jedis("localhost", 6379);

        // 获取分布式锁
        String lockKey = "my_lock";
        String lockValue = "locked";
        int expirationTime = 10000; // 锁的过期时间,单位为毫秒

        // 尝试获取锁
        boolean isLocked = false;
        try {
            String result = jedis.set(lockKey, lockValue, "NX", "PX", expirationTime);
            isLocked = "OK".equals(result);
            if (isLocked) {
                // 成功获取锁,执行需要保护的代码
                System.out.println("Lock acquired. Performing the protected operation.");
                Thread.sleep(5000); // 模拟执行操作的耗时
            } else {
                // 未能获取到锁,执行相应的处理逻辑
                System.out.println("Failed to acquire the lock.");
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            // 释放锁
            if (isLocked) {
                jedis.del(lockKey);
                System.out.println("Lock released.");
            }
        }

        // 关闭Redis连接
        jedis.close();
    }
}

在上述示例中,我们使用Jedis客户端库创建了一个Redis连接。

然后通过使用jedis.set命令设置一个带有超时时间的锁键来获取锁,如果成功获取到锁,就执行需要保护的代码。

否则,输出相应的失败信息,最后,在释放锁时,使用jedis.del命令删除锁键。

mikechen

mikechen睿哥,10年+大厂架构经验,资深技术专家,就职于阿里巴巴、淘宝、百度等一线互联网大厂。

关注「mikechen」公众号,获知最新一线技术干货!

评论交流
    说说你的看法