redis 분포 식 자물쇠 의 실현 및 문제점 분석

11522 단어 redis 학습
Implementing a distributed lock manager with Redis.redis 를 사용 하여 분포 식 잠 금 관 리 를 실현 합 니 다.
우리 가 서로 다른 프로 세 스 나 스 레 드 로 같은 자원 을 처리 해 야 할 때 자 물 쇠 는 비교적 중요 하 다.redis 의 분포 식 자 물 쇠 는 redlock 이 라 고 합 니 다.
다음은 redis 로 분포 식 잠 금 관 리 를 어떻게 실현 하 는 지 살 펴 보 자.
github 에 redis 분포 식 자 물 쇠 를 사용 하 는 공식 적 인 예 가 있 습 니 다.https://github.com/ronnylt/redlock-php
php 로 예 를 들 면:
redis 서버 세 대 정의:
$servers = [   
['127.0.0.1', 6379, 0.01],  
['127.0.0.1', 6389, 0.01],   
['127.0.0.1', 6399, 0.01],];
자물쇠 관리 만 들 기:    
$redLock = new RedLock($servers);
그리고 키 를 잠 그 고 잠 긴 시간 을 설정 합 니 다.시간 은 밀리초 단위 이다.
$lock = $redLock->lock('my_resource_name', 1000);
false 로 돌아 가 는 데 실패 하면 다음 데 이 터 를 되 돌려 줍 니 다.
Array
(
  
[validity] => 9897.3020019531
  
[resource] => my_resource_name
  
[token] => 53771bfa1e775
)
내 가 처음에 이것 을 보 았 을 때 생각 나 는 것 은 왜 이런 형식 으로 자 물 쇠 를 채 워 야 하 는 지,우리 의 일반적인 업무 에서 set 명령 을 직접 사용 해 야 하 는 지 하 는 것 이다.
키 하나 에 값 과 만 료 시간 을 설정 하면 곧 잠 글 수 있 나 요?공식 적 으로 어떻게 설명 하 는 지 살 펴 보 자.
잠 금 의 의 미 는 이 메커니즘 이 같은 시간 동안 하나의 요청 만 조작 할 수 있다 는 것 이다.
간단 한 예 를 들 어,예 를 들 어 당신 은 세 대의 기계 가 쓰기 조작 을 해 야 합 니 다.데이터 의 정확성 을 확보 하기 위해 서,당신 은 동시에 한 대의 기계 만 진행 할 수 있 습 니 다.
write 작업,write 작업 을 하기 전에 자 물 쇠 를 가 져 와 야 합 니 다.자 물 쇠 를 얻 은 기 계 는 조작 할 수 있 습 니 다.다른 두 대의 기 계 는 기 다 려 야 합 니 다.
자 물 쇠 를 풀 고 자 물 쇠 를 가 져 와 야 조작 할 수 있 습 니 다.
현재 운영 체 제 는 flock 과 유사 한 명령 을 제공 하여 파일 을 잠 그 지만 여러 대의 기계 에서 어떻게 작 동 합 니까?하면,만약,만약...
권한 은 분포 식 클 러 스 터 서비스 입 니까?
우선 우 리 는 하나의 사상 을 확립 해 야 한다.우 리 는 공공 장소 에 자 물 쇠 를 저장 해 야 한다.모든 서비스 가 자 물 쇠 를 가 져 올 때 이 공공 장소 에서 가 져 옵 니 다.
이것 은 우리 가'잠 금 시스템'이 필요 하 다 는 것 을 의미한다.redis 는 메모 리 를 매개 로 하 는 빠 른 데이터베이스 이다.
자물쇠 의 디자인:한 대의 redis 의 자 물 쇠 는 매우 간단 합 니 다.단지 하나의 key 를 설정 할 뿐 이지 만 그 중의 한 가지 문제 도 심각 한 문 제 를 초래 할 수 있 습 니 다.
자,그 안에 존재 하 는 함정 을 분석 해 보 자.
1.클 라 이언 트 와 redis 서버 는 반드시 네트워크 를 통 해 명령 이 발생 해 야 한다.이것 은 전송 에서 서버 로 실행 하 는 것 을 의미 하 는데 그 중에서 일정한 지연 시간 이 존재 할 것 이다.
이 기간 동안 redis 는 다른 명령 을 실행 합 니 다.이것 은 당신 이 가 져 와 야 할 값 을 변화 시 킬 수 있 습 니 다.이 키 를 조작 하 는 연결 을 만 드 는 프로그램 이 하나 밖 에 없다 는 것 을 어떻게 보증 합 니까?먼저 get 재 set 는 모두 비 원자 적 인 조작 입 니 다),당신 은 setnx 를 사용 하여 이 문 제 를 해결 할 수 있 습 니 다.
2.자 물 쇠 를 얻 은 프로그램 이 무 너 지면 영원히 존재 하 는 자물쇠 가 되 고 아무 도 취소 하지 않 습 니 다.이 럴 때 우 리 는 기한 이 지난 시간 을 설정 해서 그것 을 해결 해 야 한다.
아마도 우리 의 코드 는 이 럴 것 이다.
MULTI
SETNX lock-key
PEXPIRE 10000 lock-key
EXEC
그러나 이것 은 또 다른 문 제 를 가 져 왔 다.expire 명령 은 setnx 의 실행 결 과 를 상관 하지 않 는 다.setnx 가 성공 하 든 안 하 든 expire 는 실 행 될 것 이다.그것 은
모든 연결 은 만 료 시간 을 업데이트 하고 키 는 영원히 만 료 되 지 않 는 키 가 됩 니 다.
위 에서 가장 간단 한 방법 입 니 다.redis 는 단일 프로 세 스 이기 때문에 사실 우 리 는 문 제 를 완벽 하 게 해결 하 는 또 다른 방법 이 있 습 니 다.스 크 립 트 를 통 해 key 를 얻 을 수 있 습 니 다.
lua 스 크 립 트 를 실행 하여 key 를 가 져 오고 key 의 만 료 시간 을 설정 할 수 있 습 니 다.redis 는 이 스 크 립 트 를 캐 시 합 니 다.eval 또는 evalsha 를 통 해 실행 할 수 있 습 니 다.
스 크 립 트 내용,이렇게 하면 원자 적 인 조작 을 실현 할 수 있 습 니 다.키 와 expire 가 모두 설정 되 었 음 을 보증 합 니 다.다음은 공식 적 으로 제공 하 는 lua 스 크 립 트 입 니 다.
---- Set a lock
---- KEYS[1]   - key
-- KEYS[2]   - ttl in ms
-- KEYS[3]   - lock content
local key     = KEYS[1]
local ttl     = KEYS[2]
local content = KEYS[3]
 
local lockSet = redis.call('setnx', key, content)
 
if lockSet == 1 then
  redis.call('pexpire', key, ttl)
end
 
return lockSet

node.js 로 작 성 된 redis 작업 스 크 립 트 라 이브 러 리 파일 을 다시 제공 합 니 다.분포 식 잠 금,메시지 큐 및 기타 민감 한 병행 작업 코드 를 실현 하 는 데 도움 을 줍 니 다.
이 오픈 소스 의 nodejs 스 크 립 트 라 이브 러 리 는 warlock 이 라 고 합 니 다.주 소 는?https://github.com/thedeveloper/warlock

좋은 웹페이지 즐겨찾기