Redis 分布式锁

如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源, 往往需要互斥来防止彼此干扰, 以保证一致性, 这时就需要用到分布式锁

分布式锁需要具备的几个条件
  1. 只有一个客户端能持有锁
  2. 加锁和解锁必须是同一个客户端
  3. 网络中断或宕机无法释放锁时,锁会自动清除,不能发生死锁
  4. 性能要好
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$host = '127.0.0.1';
$port = 6379;
$auth = '123456';

$redis = new \Redis();
$redis->connect($host, $port);
$redis->auth($auth) or die("redis password verification failed, auth={$auth}");
$redis->ping() == '+PONG' or die("redis connection is not available, ping={$redis->ping()}");

$expireTime = 10000;
// lockKey 必须唯一
$lockKey = 'test_1';
// lockValue 必须唯一
$lockValue = md5(uniqid(md5(microtime(true)), true));

// 加锁
$status = $redis->set($lockKey, $lockValue, ['nx', 'px' => $expireTime]);
if ($status) {
// 相关逻辑...
echo 'Add lock ok.' . PHP_EOL;

// 使用 redis 的 eval (lua 语法), 把对比和删除变成原子操作
$script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
$result = $redis->eval($script, [$lockKey, $lockValue], 1);
echo 'Del lock ' . ($result ? 'ok' : 'fail') . PHP_EOL;
} else {
echo 'Add lock fail' . PHP_EOL;
}
0%