ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 레플리카의 상태와 세가지 궁금증
    개발자 라이프/카프카 2022. 10. 29. 13:44
    반응형

    들어가며

    파티션의 레플리카는 그 상황에 따라 특정한 상태가 됩니다. 이번 글은 레플리카의 상태들에 대해 살펴봅니다. 나아가 3가지 궁금증에 대해 살펴보겠습니다. 

    레플리카의 상태

    레플리카는 그 생애 주기에 따라 아래와 같이 7가지 상태를 가집니다.

    • NewReplica : 컨트롤러가 파티션 재할당 과정에서 레플리카를 생성했을 때, 이 상태가 됩니다. 이 상태에선 팔로워 레플리카가 되라는 요청만 받을 수 있습니다.
    • OnlineReplica : 할당된 레플리카(assign replicas)에 속하게 되면 이 상태가 됩니다. 이 상태에선 리더, 팔로워 레플리카가 되라는 요청을 받을 수 있습니다. 
    • OfflineReplica : 레플리카가 불능이면 이 상태가 됩니다. 일반적으로 레플리카가 속해있는 브로커가 종료되었을 때 이 상태가 됩니다.
    • ReplicaDeletionStarted: 레플리카의 삭제가 시작되면 이 상태가 됩니다. 
    • ReplicaDeletionSuccessful : 레플리카 삭제 요청이 아무런 에러 코드없이 응답되면 이 상태가 됩니다.
    • ReplicaDeletionIneligible : 레플리카의 삭제가 불가능한 상태이면 이 상태가 됩니다.
    • NonExistentReplica : 레플리카의 제거가 성공적으로 이뤄지면 이 상태가 됩니다.

    그리고 레플리카의 각 상태는 아래 그림과 같이 전환될 수 있습니다.

    3가지 궁금증

    여기서 세가지 궁금증이 생겼습니다. 첫 번째는 레플리카 삭제가 불가능한 상태(ReplicaDeletionIneligible)는 정확하게 어떤 상태일까?이고, 두 번째는 ReplicaDeletionIneligible은 어떻게 바로 OnlineReplica로 전환될 수 있는 것일까?입니다. 그리고 마지막 세 번째는 ReplicaDeletionSuccessful 이후에 어떠한 조작으로 NonExistentReplica가 되는 것일까입니다.

    레플리카 삭제가 불가능한 상태(ReplicaDeletionIneligible)는 정확하게 어떤 상태일까?

    해당 상태가 지정되는 위치를 확인해보니, 정말로 토픽을 삭제하는 것을 실패하거나 혹은 레플리카를 삭제하는 것을 실패했을 때였습니다.

    현재 3.3 버전 기준입니다. 아마 이전과는 큰 차이는 없을 것 같습니다.

    그렇다면 레플리카 삭제는 언제 실패하는 걸까요? 코드 내에선 아래 2가지의 경우에 레플리카를 삭제할 수 없는 상황으로 정의하고 있습니다.

    • 레플리카를 호스팅하고 있는 브로커가 종료되어 있는 경우
    • 레플리카가 오프라인 된 디렉터리 내에 포함되어 있을 경우

    결국 레플리카에 접근할 수 없고, 그로 인해 삭제 작업을 할 수 없을 경우에 그 레플리카는 ReplicaDeletionIneligible(레플리카 삭제 불가) 상태가 됩니다. 이러한 메커니즘은 토픽 삭제 불가 상태와도 유사합니다.

    ℹ️ 브로커가 종료될 때 자신이 호스팅하고 있는 레플리카들 중 현재 토픽 삭제 요청 큐에 포함된 레플리카가 있다면, 마찬가지로 그 레플리카들은 모두 ReplicaDeletionIneligible 상태가 됩니다.

    ReplicaDeletionIneligible은 어떻게 바로 OnlineReplica로 전환될 수 있는 것일까?

    레플리카 삭제 불가 상태라는 것은 이미 레플리카가 삭제하길 원했던 것인데, 어떻게 다시 Online 상태로 변경될 수 있는 걸까요? 몇 가지 상황을 가정해볼 수 있습니다.

    • 제거되었다가, 동일한 이름과 파티션으로 다시 생성되었을 경우?(-> 남아있던 레플리카가 쓸모가 없어지는 상황이 많은 텐데?🤔)
    • 종료되었던 브로커가 다시 살아났을 때, 삭제까지 가는 과정에서의 일시적인 상태?

    가정들을 검증하기 위해 직접 레플리카 삭제 불가한 상황을 구성했습니다. 먼저 브로커 3대로 이루어진 클러스터에 파티션 3, 레플리카 3으로 구성된 토픽을 생성합니다. 그리고 브로커 1대를 종료시킨 뒤, 토픽을 삭제합니다. 마지막으로 종료된 브로커를 다시 시작합니다. 

    위 과정에서 주키퍼의 파티션 관련 znode는 다음과 같이 변했습니다.

    1번 브로커 종료 후 znode 정보. 0번 파티션의 isr에서 1번 브로커가 제외된 것을 알 수 있다.
    토픽 삭제 후 znode 정보.

    토픽 삭제 후에 조회한 znode 정보에는 2가지 특이한 점이 있는 것을 알 수 있습니다. 첫 번째는 leader 브로커가 `-1`로 잡힌 점이고, 두 번째는 isr이 당시의 컨트롤러였던 3번 브로커로 잡힌 점입니다. 먼저 관련해서 코드로 확인해본 결과, leader=-1 은 No Leader를 나타내는 것이었습니다.

    -1은 NoLeader를 나타낸다. -2인 경우는 삭제 중인 것을 나타낸다.

    그렇다면 왜 isr엔 컨트롤러 브로커가 잡히는 것일까요? 이 부분은 코드를 파봐도 잘 안 나와서 다음에 알아봐야겠습니다. 아무튼 znode 변화를 통해서 알 수 있는 것은 삭제 불가 상태가 된 레플리카의 파티션 정보가 조금 특이한 형태로 znode에 남아있다는 것입니다.

    ℹ️ 레플리카가 제거되기 전까지 주키퍼의 토픽 삭제 작업 정보를 저장하는 /admin/delete_topics 하위 경로에도 해당 토픽 정보가 계속 남아있습니다.

    그렇다면 위 과정에서 컨트롤러는 어떤 로그를 남길까요? 전체적인 로그를 확인해봤을 땐, 다음과 같은 흐름이었습니다.

    작업 각 파티션의 1번 레플리카 상태 각 파티션의 2번, 3번 레플리카 상태
    1번 브로커 종료 OnlineReplica -> OfflineReplica OnlineReplica
    토픽 삭제 요청 OfflineReplica
    -> ReplicaDeletionIneligible
    -> OfflineReplica (향후 삭제 재실행을 위해)
    OnlineReplica
    -> OfflineReplica
    -> ReplicaDeletionStarted
    -> ReplicaDeletionSuccessful
    1번 브로커 재시작 OfflineReplica
    -> OnlineReplica
    ReplicaDeletionSuccessful
    토픽 삭제 재실행 OnlineReplica
    -> OfflineReplica
    -> ReplicaDeletionStarted
    -> ReplicaDeletionSuccessful
    ReplicaDeletionSuccessful
    토픽 삭제 완료 ReplicaDeletionSuccessful
    -> NonExistentReplica

    상태 전환 로그를 통해서 알 수 있는 것은 다음 2가지였습니다.

    • ReplicaDeletionIneligible 상태가 일시적인 상태이고, 향후 재실행을 위해 OfflineReplica 상태로 다시 전환된다.
    • 브로커가 다시 실행되면 OfflineReplica는 OnlineReplica 상태로 전환된다.
    • 모든 레플리카가 ReplicaDeletionSuccessful이 되어야 완전한 토픽 삭제 완료가 되고, 모든 레플리카가 NonExistentReplica 상태가 된다.

    그렇다면 다시 돌아와서 ReplicaDeletionIneligible 상태에서 어떻게 바로 OnlineReplica로 전환될 수 있는 것일까요? 앞서 2가지의 가설을 생각했지만, ReplicaDeletionIneligible 상태가 워낙 일시적인 상태이기 때문에 2가지 가설 모두 해당하지 않았습니다. 이와 관련해선 적절한 코드 부분도 찾을 수가 없어서 스택오버플로우에 짧게나마 질문 글을 남겼습니다. ㅜㅜ

    향후 토픽 삭제 재실행을 위해 ReplicaDeletionIneligible 상태를 OfflineReplica 상태로 전환하는 메서드.

    ReplicaDeletionSuccessful 이후에 어떠한 조작으로 NonExistentReplica가 되는 것일까?

    앞서 삭제 불가 상태를 재현한 상황에서 토픽의 모든 레플리카가 ReplicaDeletionSuccessful 상태가 되었을 때, 이를 토픽 삭제 완료가 된 상태라고 판단하고 NonExistentReplica 상태로 전환시키는 것을 확인했습니다. 이와 관련된 코드 부분은 아래와 같습니다.

    토픽 삭제가 완료된 시점에, 해당 토픽의 모든 ReplicaDeletionSuccessful 상태의 레플리카는 NonExistentReplica 상태로 전환됩니다.
    토픽의 모든 레플리카의 상태가 ReplicaDeletionSuccessful 일 때, 해당 토픽의 삭제가 완료되었다고 판단합니다.

    위 resumeDeletions 메서드는 여러 상황에서 실행되며, StopReplica 요청이 에러 없이 응답 왔을 때 실행되기도 합니다. 따라서 삭제 불가 상태를 재현한 상황에선, 각 파티션의 1번 레플리카를 삭제하는 과정에서 호출될 것으로 추측할 수 있습니다.

    결론

    이번 글을 통해 레플리카의 상태에 대해 알아보고, 세 가지 궁금한 것에 대해 살펴봤습니다. 특히 삭제하는 과정과 연관되어 자세히 살펴보았는데, 그 과정에서 어떤 경우에 실패하는지, 또 실패했을 때 어떤 처리를 하는지에 대해 알 수 있었습니다. 몇 가지 궁금증이 더 생기긴 했지만, 이와 관련해선 다른 글로 살펴보도록 하겠습니다.

    반응형

    댓글

Designed by Tistory.