>  기사  >  백엔드 개발  >  PHP Redis 잠금 및 잠금 해제

PHP Redis 잠금 및 잠금 해제

不言
不言원래의
2018-07-06 16:59:503323검색

이 기사에서는 특정 참조 가치가 있는 php redis의 잠금 및 잠금 해제를 주로 소개합니다. 도움이 필요한 친구들이 참고할 수 있습니다.

php+redis는 잠금 및 잠금 해제 작업을 실현합니다.

사업 배경 : 룸 체스와 카드 게임에서는 동시 작업으로 인한 Redis 데이터의 더티 읽기를 방지하기 위해 잠금이 필요합니다. 예를 들어 룸에 입장하는 사용자의 작업을 추가하는 경우:

PHP Redis 잠금 및 잠금 해제

동시성의 경우 get RoomUsers는 더티 읽기를 갖게 됩니다. ;


솔루션 아이디어: 다른 동시 클라이언트가 기다리는 동안 한 번에 한 명의 클라이언트만 작업할 수 있도록 룸을 잠급니다. 즉, ----- 잠금을 차단합니다. redis 추가 잠금 방법에는 incr, set, setnx, hSetnx가 있습니다. Redis 잠금의 여러 구현


여기서는 set 방법을 사용합니다

$roomId = $_GET['roomId'];
$user = $_GET['user'];             // '张三'
$key = "LockRoom:{$roomId}";
$value = $roomId.uniqid();
$ex = 3;
// 如果 $key 不存在的话,就设置 $key 的值为 $value,且有效期为 3s; 
// return TRUE / FALSE
while(true){
    $res  = $this->redis->set($key, $value, ['nx', 'ex' => $ex]);
    if($res) { break; }
    usleep(5000);
}

// 将用户添加进房间
$roomUsers = $this->redis->get("Room:{$roomId}:Users"); // ['李四', '王五']
$roomUsers[] = $user;
$this->redis->set("Room:{$roomId}:Users", $roomUsers); // ['李四', '王五', '张三']

Unlocking

: 물론 잠금을 해제해야 합니다. 작업 후 잠금을 해제하지 않으면 최소 3초를 기다려야 합니다.

잠금을 해제하려면 삭제를 사용하여 키를 삭제하세요. 하지만 여기에는 함정이 있습니다. client01이 키를 획득했다고 가정하면 삭제를 직접 사용할 수 없습니다. 잠금, 방에 입장할 사용자를 추가하는 과정에서 시간이 3초를 초과합니다. 이 때 client02도 잠금을 획득하고 3S를 설정한 다음, client01이 작업을 완료하고 키를 삭제하면 client02가 설정한 잠금이 설정됩니다.
lua 실행은 원자적이므로 삭제를 수행하려면 lua 코드를 사용하는 것이 좋습니다.

// 将用户添加进房间
$roomUsers = $this->redis->get("Room:{$roomId}:Users"); // ['李四', '王五']
$roomUsers[] = $user;
$this->redis->set("Room:{$roomId}:Users", $roomUsers); // ['李四', '王五', '张三']

// lua 脚本解锁
// 先判断 key的值是否为 value, TRUE 才会删除, 所以 $value 的设计要有随机唯一性
$script = 'if redis.call("get",KEYS[1]) == ARGV[1]
then
    return redis.call("del",KEYS[1])
else
    return 0
end ';
$this->redis->eval($script, array($key , $value), 1);
자세한 내용은 다음 기사를 참조하세요: Redis 잠금을 해제하는 올바른 자세
PHP에서 Redis를 작동하는 방법에 대한 문서도 있습니다: PhpRedis에는 set() 및 eval() 함수에 대한 설명이 있습니다

참고: 여기에서 Lua 스크립트를 사용하세요. PHP .ini는 shell_exec()와 같은 시스템 기능을 열어야 합니다.

위 코드는 참조용일 뿐입니다! !

위 내용은 이 글의 전체 내용입니다. 모든 분들의 학습에 도움이 되었으면 좋겠습니다. 더 많은 관련 내용은 PHP 중국어 홈페이지를 주목해주세요!

관련 권장사항:

PHP 및 매개변수 주석을 사용하여 Beanstalkd를 작동하는 방법

PHP로 구현된 인트라넷 침투 애플리케이션 Spike가 재구성되었습니다

위 내용은 PHP Redis 잠금 및 잠금 해제의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.