跳到主要内容

RedLock

2025年01月20日
柏拉文
越努力,越幸运

一、认识


RedLockRedis 官方提出的一种分布式锁算法,旨在提高分布式环境下的锁可靠性。它通过多个 Redis 实例来实现 更高的容错性和可靠性。RedLock 工作原理为:

  1. 客户端依次向多个(N)独立的 Redis 实例尝试加锁(使用相同的唯一值)。

  2. 如果在大多数 Redis 节点(N/2 + 1)中成功获取锁,则认为获取锁成功。

  3. 如果在一定时间内未获取到足够的锁,释放已获得的锁,并返回失败。

  4. 锁的超时时间需要比整个获取锁的时间长,确保在发生问题时锁能过期自动释放。

RedLock 适合多实例、分布式、大规模使用。

二、实现


const { Redlock } = require('redlock');
const redis = require('ioredis');

// 连接多个 Redis 实例
const redisClient1 = new redis({ host: '127.0.0.1', port: 6379 });
const redisClient2 = new redis({ host: '127.0.0.1', port: 6380 });
const redisClient3 = new redis({ host: '127.0.0.1', port: 6381 });

// 创建 Redlock 实例
const redlock = new Redlock([redisClient1, redisClient2, redisClient3], {
driftFactor: 0.01, // 时钟漂移因子
retryCount: 3, // 重试次数
retryDelay: 200, // 重试延迟时间
retryJitter: 200 // 额外的随机延迟防止竞争
});

// 获取锁
async function acquireLock() {
try {
const lock = await redlock.lock('locks:my_resource', 10000);
console.log('锁已获取');

// 模拟业务逻辑处理
await new Promise((resolve) => setTimeout(resolve, 5000));

// 释放锁
await lock.unlock();
console.log('锁已释放');
} catch (err) {
console.error('获取锁失败', err);
}
}

acquireLock();
  • driftFactor:考虑时钟漂移补偿。

  • retryCount:如果获取锁失败,最多重试 3 次。

  • retryDelay:两次重试之间的时间间隔。

  • retryJitter:防止多个客户端同时竞争锁。

  • lock.unlock(): 释放锁,避免资源长时间被占用。

三、用法