주:

다운타임 없이 Kafka 및 Zookeeper 클러스터 마이그레이션

소개

많은 서비스(클라우드 네이티브 또는 온프레미스)는 잘 확장되는 메시징 기술이기 때문에 비동기 메시징 요구사항에 Kafka 클러스터를 사용합니다. 비즈니스 요구 사항으로 인해 노드 세트 또는 전체 클러스터를 교체해야 하는 경우가 있을 수 있습니다. 이 사용지침서에서는 작동 중지 시간 없이 Kafka 및 Zookeeper 클러스터를 새로운 노드 세트로 마이그레이션하는 방법에 대해 설명합니다.

문제 명세서

클러스터의 노드를 다른 노드로 교체하는 것이 어려운 이유는 무엇입니까? 로드 밸런서 뒤의 노드 세트에서 노드를 추가하거나 제거하는 것은 유비쿼터스입니다. 새 노드를 추가하고, 제거할 기존 노드를 드레인하고, 진행 중인 모든 연결이 종료되면 종료하고, 로드 밸런서 구성에서 제거합니다.

실제 당면 과제는 애플리케이션과의 상태 관리입니다. 일반적으로 응용 프로그램은 Stateless이며 데이터 관리 시스템(예: RDBMS(관계형 데이터베이스 관리 시스템)에 상태 지속성을 위임합니다. 이러한 응용 프로그램과 달리 Kafka와 Zookeeper는 로컬에서 상태를 관리합니다. 즉, 로컬 디스크를 사용하여 상태 지속성을 수행합니다. 즉, 기존 노드의 로컬 상태를 처리하지 않으면 노드를 다른 노드로 바꿀 수 없습니다.

또한 Kafka의 경우 단순히 노드를 추가해도 작업 로드 밸런싱 조정이 자동으로 시작되지 않습니다. 즉, 브로커 간에 토픽 파티션을 재분배합니다. 새 노드는 이 시점부터 생성된 새 토픽에 대한 작업 로드 공유에만 참여합니다.

쿼럼 기반 시스템(이 경우 Zookeeper)의 작동 문제 중 하나는 클러스터 크기를 미리 알아야 한다는 점입니다. 즉, 각 노드가 클러스터의 다른 모든 노드를 알고 있어야 합니다. 또한 한 번에 둘 이상의 노드(정확한 숫자는 기존 클러스터 크기에 따라 다름)를 추가하는 경우 새로 추가된 노드 중 하나가 리더가 되지 않도록 해야 합니다. 그렇지 않으면 데이터가 손실됩니다.

목표

필요 조건

Kafka 클러스터 이전

Kafka 클러스터의 노드 교체는 비교적 쉽습니다. 새 브로커를 추가하고 토픽 분할 영역 이전을 호출하고, 이전이 완료되면 이전 브로커를 해제할 수 있습니다. Kafka는 분할 영역 마이그레이션을 수행하기 위한 admin API를 제공합니다. alterPartitionReassignments는 항목에 분할 영역 복제본을 추가하고 ISR의 멤버가 될 때까지 기다린 다음 분할 영역 리더를 교체하는 방식으로 작동합니다.

이전 중개자에 대한 새 항목 분할 영역 지정을 사용 안함으로 설정해야 합니다(애플리케이션 논리가 런타임 시 토픽을 생성하는 경우). 그렇지 않으면 이 작업이 끝없는 이전 루프가 됩니다. 이를 위해 분할 영역 지정을 직접 지정할 수 있는 항목 생성 API의 변형을 사용할 수 있습니다. 따를 수 있는 샘플 알고리즘이 아래에 나열됩니다.

부기 작업과 함께 수행될 수 있는 마이그레이션에 대한 상위 레벨 단계입니다(마이그레이션 프로세스가 중지되거나 중간에 실패한 경우 다시 시작).

  1. 이전-새 중개자 ID 매핑이 제공되고 완료되었습니다.

  2. AdminClient를 사용하여 새 브로커를 사용할 수 있는지 확인합니다. 일부만 사용할 수 있는 경우 오류를 발생시키고 종료합니다.

  3. AdminClient를 사용하여 <kafka_topic_migration> 항목이 클러스터에 존재하는지 확인합니다.

    • <kafka_topic_migration> 항목이 존재하지 않을 경우 새 중개자에 복제본을 수동으로 지정하여 생성합니다. 이 항목은 이미 재지정된 항목의 부기에 사용되며 마이그레이션됨을 의미합니다.
  4. 소비자를 사용하여 처음부터 <kafka_topic_migration> 항목을 읽습니다. 각 메시지는 새 중개인에게 재할당된 주제 이름입니다.

  5. AdminClient를 사용하여 클러스터에서 사용 가능한 모든 항목을 나열합니다. 이 목록에서 <kafka_topic_migration> 항목을 제거합니다.

  6. 위의 두 단계에서는 새 중개인에 재할당할 항목을 찾습니다.

  7. 각 토픽에 대해 다음을 수행합니다.

    1. Map<TopicPartition,Optional<NewPartitionReassignment>> reassignment = new HashMap<>(); 맵을 생성합니다.

    2. AdminClient를 사용하여 해당 분할 영역을 찾기 위한 항목을 설명합니다.

    3. 각 분할 영역에 대해 다음을 수행합니다.

      1. 이전 복제본 ID(이전 브로커 ID)를 해당하는 새 브로커 ID로 바꾸어 NewPartitionReassignment 객체를 준비합니다. 브로커 ID 매핑에 복제본 ID에 해당하는 키가 포함되어 있지 않으면 경고를 기록하고 현재 ID를 사용하십시오(이 항목이 이미 마이그레이션되었으며 부기 작업이 누락되었을 가능성이 높습니다).

      2. 이 항목을 맵에 추가합니다.

    4. AdminClient를 사용하여 alterPartitionReassignments 메소드를 호출하여 재지정을 시작합니다.

    5. 루프를 실행하여 재지정(listPartitionReassignments)을 나열하고 크기가 0인지 확인하여 이 재지정이 완료되었는지 확인합니다. 각 루프 사이에 N 초 동안 잠을 자십시오.

    6. 각 파티션의 새 복제본이 원하는 복제본과 일치하는지 검증합니다.

    7. 이 항목 이름을 <kafka_topic_migration> 항목에 메시지로 푸시합니다.

  8. 재지정 및 종료할 주제가 더 이상 남아 있지 않으면 4-6단계를 반복합니다.

마이그레이션이 완료되면 이전 중개자를 해제하고 토픽 생성의 사용자정의 논리를 사용 안함으로 설정할 수 있습니다.

주: 이전 중개자를 해제하기 전에 이 클러스터에 대한 모든 클라이언트가 bootstrap.servers 구성을 새 중개자로 업데이트했는지 확인하십시오.

Zookeeper 클러스터 이전

쿼럼 기반 시스템(작업을 커밋하려면 최소 쿼럼의 투표가 필요함)이고 리더 재선거를 수행하면 쓰기 작업이 중지되고 Zookeeper 마이그레이션이 가장 어려운 부분입니다. 노드를 교체하는 방법에는 몇 가지가 있습니다. 한 가지 간단한 방법은 전체 클러스터의 롤링 재시작을 여러 번 수행하고 각 라운드에 새 노드를 추가하는 것입니다. 리더 노드가 여러 번 다시 시작되고 전체 마이그레이션 수행이 지연되어 이 접근 방법이 허용되지 않을 수 있습니다.

참고: 모든 데이터를 동기화하지 않고(데이터 손실을 유발) 새 노드가 리더가 될 위험이 있기 때문에 모든 새 노드를 참가자로 추가할 수는 없습니다.

참가자와 동일한 초기 구성에서 둘 이상의 조인 서버를 지정하지 마십시오. 현재 조인 서버는 기존 앙상블에 조인하고 있음을 알지 못합니다. 여러 조인이 참가자로 나열되면 독립 쿼럼을 형성하여 주 앙상블과 독립적으로 작업 처리와 같은 정보 분리 상황을 만들 수 있습니다. 초기 구성에서 여러 Joiner를 관찰자로 나열해도 됩니다.

3.5.0 이상의 Zookeeper 버전에서는 Zookeeper 앙상블의 동적 재구성을 지원합니다. 동적 재구성이 작동하려면 reconfigEnabled 플래그를 true로 설정해야 합니다. For more information, see Dynamic Reconfiguration of the ZooKeeper Ensemble.

마지막 커밋된 구성의 서버로 구성된 Joiner의 초기 구성을 사용하여 Observer 롤을 사용하여 새 노드를 앙상블에 추가할 수 있습니다. 예를 들어, 서버 4와 5가 (1, 2, 3)에 동시에 추가되면 4의 초기 구성은 (1, 2, 3, 4, 5)가 되고, 여기서 4와 5는 관찰자로 나열됩니다. 마찬가지로 5의 구성은 (1, 2, 3, 4, 5)입니다. 여기서 4와 5는 관찰자로 나열됩니다.

주: Joiner를 관찰자로 나열해도 실제로 관찰자가 되지는 않습니다. Joiner는 실수로 다른 Joiner와 함께 쿼럼을 형성하는 것을 막을 뿐입니다. 대신, 현재 구성에서 서버에 연결하고 조인이 없는 마지막 커밋된 구성(1, 2, 3)을 채택합니다. 현재 지시선에 연결한 후, 가입자는 시스템이 재구성되어 앙상블에 추가될 때까지 비투표 추종자가 됩니다(참가자 또는 관찰자, 원하는 대로).

모든 노드가 작동 및 실행되고 나면 API 재구성이 호출되어 새 노드를 참가자로 동적으로 추가하고 이전 노드를 앙상블에서 제거합니다. 예를 들어 CLI를 사용합니다.

reconfig -remove 1,2,3 -add
server.5=hostA:2111:2112;2113,6=hostB:2111:2112:participant;2113,7=
hostC:2111:2112:participant;2113*

이 단계 후에는 이전 노드를 해제할 수 있습니다.

참고:

확인

추가 학습 자원

docs.oracle.com/learn에서 다른 실습을 살펴보거나 Oracle Learning YouTube 채널에서 더 많은 무료 학습 콘텐츠에 액세스하십시오. 또한 education.oracle.com/learning-explorer를 방문하여 Oracle Learning Explorer가 되십시오.

제품 설명서는 Oracle Help Center를 참조하십시오.