php redis 기반 분포 식 잠 금 실례 상세 설명
물론 redis 의 단일 노드 가 극단 적 인 상황 에 잠 겨 있 는 것 도 문제 가 있 습 니 다.만약 에 귀하 의 업무 가 가끔 실 효 를 허용 한다 고 가정 하면 단일 노드 의 redis 잠 금 방안 을 사용 하면 충분 하고 간단 하 며 효율 이 높 습 니 다.
redis 잠 금 이 실 효 된 경우:
클 라 이언 트 1 마스터 노드 에서 자 물 쇠 를 가 져 왔 습 니 다.
master 가 다운 되 었 습 니 다.자 물 쇠 를 저장 하 는 key 가 아직 slave 노드 에 동기 화 되 지 않 았 습 니 다.
slave 마스터 로 승급
클 라 이언 트 2 새로운 master 에서 같은 자원 의 자 물 쇠 를 가 져 옵 니 다.
그래서 클 라 이언 트 1 과 클 라 이언 트 2 동료 가 같은 자원 의 자 물 쇠 를 가지 고 자물쇠 의 안전성 이 깨 졌 다.
만약 에 우리 가 이런 극단 적 인 상황 을 고려 하지 않 는 다 면 단일 노드 redis 자 물 쇠 를 바탕 으로 하 는 대체적인 절 차 를 실현 해 야 한다.
set cache_key random_seed NX PX 30000
위의 이 set 명령 을 분해 하면:
setnx cache_key random_seed
expire cache_key 30
이 두 조 의 명령 이 실 행 된 효 과 는 같 지만 두 번 째 는 비 원자 적 인 작업 입 니 다.setnx 를 실 행 했 지만 expire 가 실패 하면 이 key 는 계속 존재 하고 풀 수 없 는 상황 이 발생 합 니 다.redis 의 작가 도 단일 노드 redis 자 물 쇠 를 사용 할 때 무 작위 피 드 를 key 의 값 으로 설정 하 는 것 이 필요 하 다 고 지적 했다.클 라 이언 트 가 풀 어 준 자 물 쇠 는 반드시 자신 이 가지 고 있 는 자물쇠 여야 한다 고 보장 했다.자 물 쇠 를 가 져 올 때 set 는 난수 가 아니 라 고정 값 이 라 고 가정 합 니 다.
그러면 다음 과 같은 상황 이 발생 할 수 있 습 니 다.
클 라 이언 트 1 잠 금 획득 성공
클 라 이언 트 1 은 어떤 조작 에서 오랫동안 막 혔 다.
만 료 시간 이 되 었 습 니 다.자 물 쇠 는 자동 으로 풀 립 니 다.(그러나 클 라 이언 트 1 에서 볼 때 자 물 쇠 를 가지 고 있 는 것 같 습 니 다)
클 라 이언 트 2 가 같은 자원 에 대한 자 물 쇠 를 가 져 왔 습 니 다.
클 라 이언 트 1 은 차단 에서 회복 되 었 고 자신 이 가지 고 있 는 자 물 쇠 를 풀 었 습 니 다.즉,클 라 이언 트 2 가 가지 고 있 는 자 물 쇠 를 풀 었 습 니 다.
클 라 이언 트 2 의 잠 금 이 클 라 이언 트 1 에 의 해 안전성 을 잃 었 는 지 여부 입 니 다.
자 물 쇠 를 풀 어 주 는 작업 은 많은 사람들 이 직접 del 명령 을 사용 합 니 다.이것 은 매우 큰 문제 가 있 을 것 입 니 다.이 key 가 자 물 쇠 를 채 워 서 삭제 되 는 것 을 보장 할 수 없습니다.이 럴 때 는 임 의 수 를 써 야 한다.
잠 금 해제 동작 은 세 단계 입 니 다:
get 보유 자물쇠
이 자물쇠 가 자신 이 가지 고 있 는 지 아 닌 지 를 판단 하 세 요.
보유 자물쇠 삭제
그래서 이 세 단 계 는 원자 성 을 확보 해 야 한다.lua 스 크 립 트 로 실행 합 니 다.redis 공식 에서 스 크 립 트 파일 을 제공 하 였 습 니 다.
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
이 스 크 립 트 를 실행 할 때 앞의 무 작위 수 를 argv[1]의 값 으로 전송 하고 cachekey 는 keys[1]의 값 으로 전 달 됩 니 다.
public class RedisLockHelper {
@Resource
private R2mClusterClient r2mClusterClient;
/**
* setNx , expire
*
* @param key key
* @param value
* @param expire
* @return
*/
private String setLock(String key, String value, long expire) {
return this.set(key, value, "NX", "PX", expire);
}
/**
* key value
* r2m key value==value 1
* r2m key value!=value 0
*
* @param key
* @return
*/
private boolean atomDelete(String key, String value) {
List<String> values = new ArrayList<>();
values.add(value);
String sb = "if redis.call('get',KEYS[1])==ARGV[1] then " +
" return redis.call('del',KEYS[1]) " +
" else " +
" return 0" +
" end";
if (this.eval(sb, key, values) == 1) {
return true;
}
return false;
}
private Long eval(String mobel, String key, List<String> value) {
return (Long) this.r2mClusterClient.eval(mobel, key, value);
}
private String set(String key, String value, String nxxx, String expx, long time) {
return this.r2mClusterClient.set(key, value, nxxx, expx, time);
}
}
r2m ClusterClient 는 jedis 클 라 이언 트 의 패키지 입 니 다.phop 기반 redis 의 분포 식 잠 금 인 스 턴 스 에 대한 상세 한 설명 은 여기까지 입 니 다.더 많은 phop 기반 redis 의 분포 식 잠 금 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Redis 해시에 대한 완벽한 가이드변경 가능하므로 필요에 따라 쉽게 변경하고 업데이트할 수 있습니다. Redis 해시는 구조가 평평하므로 JSON에서와 같이 여러 수준을 가질 수 없습니다. redis 해시의 명명 규칙은 hash:key 로 입력되므로...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.