분류

낙관적 잠금과 비관적 잠금 - 어느 쪽을 선택해야 할까요?

Alice와 Joe가 모두 Couchbase Server에서 동일한 데이터 항목을 읽었다고 가정합니다. 둘 다 데이터를 변경한 다음 새 버전을 데이터베이스에 다시 쓰려고 시도했습니다. 누구의 변경 사항을 저장해야 하나요? 앨리스의 것? 조의 것? 둘 다? 둘 다? 비관적 잠금과 낙관적 잠금을 둘러싼 논쟁에서 승자를 결정하는 것은 바로 이러한 질문입니다.

특히 개발자는 공유 데이터 항목에 대한 액세스를 직렬화하기 위해 잠금을 사용합니다. 하지만 어떤 잠금 체계가 를 선택해야 하나요?

이 블로그에서는 낙관적 잠금과 비관적 잠금에 대해 설명하고 두 가지의 차이점에 대해 설명하겠습니다. 또한 Couchbase에서 사용할 수 있는 낙관적 및 비관적 잠금 API에 대해 논의합니다. 서버를 통해 데이터에 대한 동시 액세스를 제어할 수 있습니다.

카우치베이스 서버에서 낙관적 잠금이란 무엇인가요?

Couchbase Server를 사용하여 애플리케이션과 같은 온라인 위키백과를 구축한다고 가정해 보겠습니다: 사용자는 문서를 업데이트하고 최신 문서를 추가할 수 있습니다. Alice가 이 애플리케이션을 사용한다고 가정해 보겠습니다. 에 대한 기사를 편집하려면 '자전거' 를 클릭하여 일부 정보를 수정합니다. Alice는 기사를 열고 하지만 저장을 누르기 전에 주의가 산만해져 책상에서 멀어집니다. 그동안 Joe가 자전거 기사에서 동일한 오류를 발견하고 다음과 같이 하려고 한다고 가정해 보겠습니다. 실수를 수정합니다.

애플리케이션에서 낙관적 잠금을 사용하는 경우 Joe는 문서를 편집하고 변경 내용을 저장할 수 있습니다. 앨리스가 돌아와서 변경 사항을 저장하려는 경우 앨리스 또는 애플리케이션은 다음을 수행합니다. 가 최신 업데이트를 처리한 후 앨리스의 작업이 문서를 변경하도록 허용합니다. 낙관적 잠금은 동시 편집으로 인한 데이터 충돌이 거의 발생하지 않는다는 "낙관적"인 관점을 취합니다. 동시 편집을 허용하는 것이 더 중요합니다.

카우치베이스 서버에서 비관적 잠금이란 무엇인가요?

이제 비즈니스 프로세스에 다음 중 하나 이상에 대한 독점 액세스가 필요하다고 가정해 보겠습니다. 문서 또는 문서 그래프입니다. 이전 예시를 참조하여 앨리스가 다음을 편집하는 경우 다른 사용자가 같은 문서를 편집하지 못하도록 설정합니다. Joe가 문서를 열려고 하면 페이지로 이동하면 앨리스가 잠금을 해제할 때까지 기다려야 합니다.

비관적 잠금을 사용하면 애플리케이션이 문서에 명시적으로 잠금을 설정해야 합니다. 는 사용자의 독점적인 액세스를 보장합니다. 사용자가 문서 액세스를 완료하면 다음과 같이 잠금을 설정할 수 있습니다. 를 수동으로 제거하거나 시간 초과를 사용하여 제거합니다.


그렇다면 어떤 것을 선택해야 할까요?

정답은 없습니다. 따라 다릅니다.. 잠금을 선택해야 합니다. 체계에 따라 달라집니다.

문서에 대한 경합이 심할 것으로 예상하지 않는 한, 낙관적으로 잠그는 것이 훨씬 더 효과적입니다. 비관적 잠금보다 오버 헤드가 적습니다. 필요한 항목을 가져 와서 빠르게 업데이트하고 시도하십시오.o 적용합니다. 시스템 내 다른 행위자가 먼저 적용했다면 성공할 때까지 다시 시도하면 됩니다.

비관적 잠금을 사용하면 특정 항목에 독점적으로 액세스할 수 있으며 다른 스레드는 액세스할 수 없습니다. 항목이 잠겨 있는 동안에는 항목에 액세스할 수 없습니다. 실패할 때는 반드시 잠금을 해제해야 합니다. 시리얼 개체를 가지고 있는데 우유 개체를 얻을 때까지 포기하지 않는다고 상상해 보세요. 하지만 여러분은 우유 물체를 가지고 있고 시리얼 물체를 얻을 때까지 포기하지 않을 것입니다. 타임아웃은 교착 상태를 깨거나 잠금을 해제하지 않는 클라이언트를 처리하는 데 사용할 수 있습니다. 

간소화를 위해 사용자는 애플리케이션 전체에서 동일한 잠금 전략을 선택할 수 있습니다. 이 는 애플리케이션 전반의 모든 다른 개체에 대한 액세스 요구 사항이 다음과 같은 경우 잘 작동합니다. 동일하다고 생각하지만 실제로는 그렇지 않습니다. 애플리케이션 객체마다 액세스 권한이 다릅니다. 요구 사항을 충족해야 합니다. 예를 들어 소셜 게임의 경우 다음과 같은 요구 사항이 있습니다.

1. 게임 플레이 중에 캐릭터 및 플레이어 인벤토리 정보에 많이 액세스합니다,

빠른 읽기-쓰기 액세스가 필요합니다. 첫 번째 선택 - 낙관적 잠금을 사용합니다. 다음 선택 -

비관적 잠금

2. 플레이어 계정 및 기본 설정은 플레이어 로그인 중 또는 게임 시작 시 읽습니다.

하지만 자주 업데이트되지는 않습니다. 낙관적 잠금은 여기에서도 잘 작동합니다.

카우치베이스 서버에서 비관적 잠금 얻기

카우치베이스 서버에서 잠금을 얻는 방법은 다음 단계로 구성됩니다:

  1. 가져오기 및 잠금 API를 사용하여 지정된 키의 값을 검색하고 해당 키를 잠급니다.
  2. 이제 애플리케이션이 문서를 독점적으로 제어할 수 있습니다.

카우치베이스 서버에서 낙관적 잠금 얻기

카우치베이스 서버에서 잠금을 얻는 방법은 다음 단계로 구성됩니다:

  1. CAS(확인 및 설정) API를 사용하여 CAS 리비전 번호 검색하기
카우치베이스 서버에서 잠금 해제하기

잠금을 수동으로 해제하려면 다음 단계를 수행하세요.:

  1. CAS를 사용하여 값을 수정하고 잠금을 해제합니다.

CAS의 비하인드 스토리

CAS 작업은 보다 고급 동시성 제어 메커니즘을 구축하는 데 사용할 수 있는 간단한 개념입니다. CAS는 객체를 처음 읽은 시간과 저장을 시도한 시간 사이에 다른 클라이언트에 의해 객체가 업데이트되었는지 여부를 확인합니다. 다른 클라이언트에 의해 객체가 수정된 경우 오류가 발생하고 애플리케이션은 값을 다시 읽고 작업을 다시 시도해야 합니다. 객체의 경합이 심하지 않고 데이터의 변환이 무효화되어 작업 낭비 없이 쉽게 작업을 재시도할 수 있는 경우, 낙관적 잠금은 평균적인 경우 높은 성능을 제공하는 좋은 솔루션입니다.

CAS와 상호 작용하는 일반적인 방법은 커뮤니티에서 개발한 다음과 같이 CAS 루프를 사용하는 것입니다. 멤캐시드 클라이언트 이동.

예를 들어 아래 상호작용 다이어그램과 같이 3개의 클라이언트가 있다고 가정해 보겠습니다. 세 클라이언트 모두 CAS를 사용하여 개체 X를 업데이트하려고 시도하며, 각 클라이언트가 한 번에 하나씩 업데이트에 성공합니다.

잠금을 해제하지 않으셨으니 카우치베이스가 대신 해제해드립니다.

가져오기 및 잠금 작업을 수행할 때 잠금의 만료 시간을 매개변수로 제공합니다. 키를 잠글 수 있는 기본 시간은 15초입니다. 15초가 지나도 수동으로 잠금을 해제하지 않으면 카우치베이스에서 자동으로 잠금을 해제합니다.

데이터베이스의 비관적 및 낙관적 잠금에 대한 최종 생각

낙관적 잠금이 모든 상황에서 최선의 해결책은 아닐 수 있습니다. 낙관적 잠금으로 잘 작동하는 사용 사례도 있지만, 비관적 잠금과 같은 더 엄격한 방식이 필요한 경우도 있습니다.

잠금 경합이 발생하면 애플리케이션에 문제가 발생할 수 있습니다. 스레드가 잠금을 유지하다가 OS에 의해 스케줄이 해제될 수 있습니다. 그러면 이 잠금을 획득하려는 모든 스레드가 차단됩니다. 한 가지 옵션은 원자 연산을 사용하여 가능한 경우 잠금을 완전히 피하는 것입니다. 이러한 API는 경합이 심한 데이터에 매우 유용할 수 있습니다.

그러나 정말 잠금이 필요하고 낙관적 잠금이 애플리케이션의 사용 사례 대부분을 커버한다고 생각한다면, Couchbase Server에서 CAS를 사용하는 낙관적 잠금은 구현하기가 매우 쉬우므로 시도하지 않을 이유가 없습니다.

이 문서 공유하기
받은 편지함에서 카우치베이스 블로그 업데이트 받기
이 필드는 필수 입력 사항입니다.

작성자

게시자 돈 핀토, 수석 제품 관리자, Couchbase

돈 핀토는 Couchbase의 수석 제품 관리자로 현재 Couchbase Server의 기능을 발전시키는 데 주력하고 있습니다. 데이터 기술에 대한 열정이 대단한 그는 과거에 기술 블로그와 백서 등 Couchbase Server에 관한 여러 기사를 저술한 바 있습니다. Couchbase에 입사하기 전에는 IBM에서 수년간 근무하며 DB2 정보 관리 그룹에서 소프트웨어 개발자의 역할을 수행했고, 가장 최근에는 Microsoft의 SQL Server 팀에서 프로그램 관리자로 근무했습니다. Don은 캐나다 토론토 대학교에서 컴퓨터 공학 석사 학위와 컴퓨터 공학 학사 학위를 받았습니다.

댓글 하나

  1. 자물쇠 따기는 예술입니다.
    합법적으로, 그리고 사용자의 허락을 받아 잠금을 분석하여 잠금을 해제합니다.
    컴포넌트입니다. 하지만 자물쇠 따기 는 대부분 범죄 및 도난과 관련이 있습니다.
    는 자물쇠 제조공에게 필수적인 기술입니다.

  2. 제임스 D 블룸 7월 16, 2014에서 5:31 오후

    이에 대한 코드 예제가 있나요? 여러 스레드에서 비관론을 사용하여 객체를 잠그려고 시도했을 때 다음과 같이 모든 스레드가 독립적으로 객체를 검색하고 저장할 수 있습니다:

    fastChangingCouchbaseClient.asyncCas(\"1\", 0l, \"일부 객체\", PersistTo.ZERO);
    for (i = 0; i < 5; i++) {
    새로운 스레드(() -> {
    System.out.println(i + \" START - \" + new Date());
    CASValue andLock = fastChangingCouchbaseClient.getAndLock(\"1\", 30);
    문자열 값 = (문자열) andLock.getValue();
    fastChangingCouchbaseClient.asyncCas(\"1\", 0l, \"일부 객체\", PersistTo.ZERO);
    System.out.println(i + \" END - \" + new Date());
    }).start();
    }

    출력은 다음과 같습니다:

    0 시작 - Wed Jul 16 18:23:49 BST 2014
    1 START - Wed Jul 16 18:23:49 BST 2014
    2 시작 - Wed Jul 16 18:23:49 BST 2014
    3 시작 - 수 7 월 16 18:23:49 BST 2014
    4 시작 - 수 7 월 16 18:23:49 BST 2014
    0 종료 - Wed Jul 16 18:23:49 BST 2014
    1 종료 - Wed Jul 16 18:23:49 BST 2014
    2 종료 - Wed Jul 16 18:23:49 BST 2014
    3 종료 - Wed Jul 16 18:23:49 BST 2014
    4 종료 - 수 7 월 16 18:23:49 BST 2014

    즉, 오류도 없고 차단도 없나요????

    1. 안녕하세요 제임스,

      어떤 버전의 Couchbase를 사용 중이며 어떤 버전의 Java 클라이언트를 사용하시나요?

      감사합니다,
      Don

    2. 제임스 D 블룸 7월 22, 2014에서 1:51 오후

      위의 문제는 대소문자 구분 값으로 \'0l\'을 사용했기 때문에 발생하는 문제라는 사실을 알게 되었습니다. '0\'을 대소문자 값으로 사용하면 (설계상) cas가 활성화되지 않는 것으로 밝혀졌습니다. 초기 cas 값을 \'0\'에서 \'1\'로 변경하자 정상적으로 작동했습니다.

  3. [...] 낙관적 잠금과 비관적 잠금, 어느 쪽을 선택해야 할까요? 앱에 잠금이 필요한 경우 먼저 CAS(낙관적 잠금)를 사용한 후 GetL(비관적 잠금)을 사용하는 것이 좋습니다. [...]

  4. 댓글 남기기

    카우치베이스 카펠라를 시작할 준비가 되셨나요?

    구축 시작

    개발자 포털에서 NoSQL을 살펴보고, 리소스를 찾아보고, 튜토리얼을 시작하세요.

    카펠라 무료 사용

    클릭 몇 번으로 Couchbase를 직접 체험해 보세요. Capella DBaaS는 가장 쉽고 빠르게 시작할 수 있는 방법입니다.

    연락하기

    카우치베이스 제품에 대해 자세히 알고 싶으신가요? 저희가 도와드리겠습니다.