레디 스 작은 이해의 잠금을 분산

1, 분산 시스템에서, 우리는 잠금 장치는 같은 JVM 하나의 스레드 만 액세스를 보장 할 수 사용하지만, 분산 시스템에서이 (잠금에서 작동하지 않습니다,이 시간은 우리가 분산 잠금을 사용한다 다양한 여기)가 레디 스 지칭

주문 레디 스의 setnx (키 값)에서 사용될 수있는 2 잠금 분산 달성 할

  SETNX : 키가있는 경우, 실패 0을 반환 존재하는 경우, 1을 반환, 설정 존재하지. 당신이 혼합하려면이 명령을 사용 (키, 시간) 만료 만료 시간을 설정할 수 있지만, 다음과 같은 문제는이 조합이 있습니다 :

   시도 {
         경우 (redisclient setnx (키 1) == 1.) { // 1 
            redisClient.expire (키 1000); // 2 
        } 
    } 마지막으로 { 
        redisClient.del (키); 
    }

  코드로서, 문제를 보면,하지만 극단적 인 경우 2에서 완료하면 컴퓨터가 잠금이 부정 될 것이다, 다운이 시간을 수행하지, 그리고 제거되지 않습니다, 즉 만료 setnx 두 명령은 원자 없습니다 배치된다 . 이 문제를 해결하려면 다음 명령 redis2.6 버전 사용할 수있는 세트를 (키, 값은 expirefime는 NX)는 이 문제를 해결할 수 setnx 같은과 함께이 명령을 해결하기 위해,하지만 더 많은 시간이 만료되었습니다.

는 A 기계 (만료 시간이 동시에 코드의 조각을 실행,이 두 개의 스레드가 발생합니다 다음, 잠금 다른 기계를 취득하는 다른 스레드 만료 내에서 프로그램 코드 실행이 완료되지 않으면, 그리고 : 3, 후에이 문제를 해결, 거기에 문제가있다 경우 잠 실수로 삭제 된 B 기계로 이어지는 키를 삭제합니다 fiηa11y에서) 실행 완료되지 않은 (의) 현재 컴퓨터를 얻기 위해 잠금

  (1) (실시 예에서 상기 데몬 스레드를 열 기계를 설명) 우리가 동일한 시스템에서 스레드 가드 시작이 때, 스레드가 만료 키의 동작 시간을 연장의 주요 역할은, 코드가 완료되도록 . 2, 실수로 삭제와 관련하여, 우리는 자신의 스레드 ID입니다 결정 삭제하기 전에, 스레드 ID로 설정 될 주어진 값 수 있으며, 그 경우는 다음 다음과 같은 코드를 삭제하다

     시도 { 
            .... 
        } 마지막으로 {
             경우 (threadId 같음 (redisclient가)) (키 얻을 { // 1 
                , redisclient.del) (키 // 2 
            } 
        }

  일반적으로 아무 문제가 있지만, 여기에 1, 2, 유사 이전 질문 --- 어떤 연결이 없습니다이 시점에서 원 자성이없는 , 그들은 여전히 잘못 될 수 있지만, 어떻게 해결하는 방법 삭제 할 원자 레디 스 명령 지원 액세스가 없다 그것은? 우리는 작업 할 수 루아 스크립트가 그런 식으로 뭔가를 쓸 수 있습니다이 경우로, 해결하기 위해

     문자열 luascript는 "레디 스 호는 (만약 '얻을 키 [1]) ARGV [1]을 다음 redis.call 반환 == ('델 'KEY [1]), 그렇지 단부 0"= ; 
        redisClient.eval (luaScript, Collection.singletonList (키) Collection.singletonlist (threadId));

다음과 같이 네, 여기, 기본적으로 아무 문제, 최종 코드는

  시도 { 
        문자열 luascript = "를 레디 스 호는 (만약 '얻을 키 [1]) ARGV [1]을 다음 redis.call를 반환 == ('델 'KEY [1]), 그렇지 0 끝" ; 
        문자열 threadId = 는 Thread.currentThread () getId ();
        반면 (redisclient 세트 (키 threadId 1000, NX) == 1 ) {
          // 해봐요 () 
        } 
    } 마지막 { 
        redisClient.eval (luaScript) (키 Collection.singletonList, Collection.singletonlist (threadId)); 
    }

 

 

추천

출처www.cnblogs.com/zhangweicheng/p/11495971.html