Kafka 복제 구성: 데이터 내구성과 가용성 보장

포괄적인 복제 구성을 통해 강력한 데이터 내구성과 높은 가용성을 위해 Kafka의 성능을 활용하세요. 이 가이드는 Kafka의 복제 요소, 동기화 복제본(ISRs), 리더 선출을 쉽게 설명하고 내결함성에서의 역할을 실질적으로 이해하도록 돕습니다. 브로커 및 토픽 수준에서 복제를 구성하는 방법을 배우고, 프로듀서 `acks` 상호 작용을 이해하며, 랙 인식 복제와 같은 모범 사례를 구현하세요. 브로커 장애에 대비하여 데이터 안전성과 지속적인 운영을 보장하는 복원력 있는 Kafka 클러스터를 구축할 수 있는 지식을 갖추세요.

39 조회수

Kafka 복제 구성: 데이터 내구성과 가용성 보장

분산 시스템 환경에서 데이터 내구성과 고가용성은 매우 중요합니다. 선도적인 분산 이벤트 스트리밍 플랫폼인 Kafka는 강력한 복제 메커니즘을 통해 이러한 중요한 속성을 달성합니다. Kafka 복제를 이해하고 올바르게 구성하는 것은 브로커 장애를 견디고 지속적인 운영을 유지할 수 있는 탄력적이고 신뢰할 수 있는 데이터 파이프라인을 구축하는 데 필수적입니다.

본 문서는 Kafka의 복제 전략을 깊이 있게 다루며, 데이터가 여러 브로커에 걸쳐 복사되고 유지되는 방식의 핵심 개념을 설명합니다. 동기 복제본(ISR)의 역할, 리더 선출 메커니즘, 그리고 이러한 요소들이 어떻게 집단적으로 내결함성에 기여하는지 탐구할 것입니다. 또한, 데이터의 안전성과 접근성을 보장하기 위한 모범 사례와 함께 브로커 및 토픽 수준에서 복제를 구성하는 실질적인 지침을 제공할 것입니다.

이 가이드가 끝날 때쯤이면 Kafka 복제에 대한 포괄적인 이해를 갖추게 되어, 예상치 못한 장애가 발생하더라도 최적의 데이터 내구성과 고가용성을 위해 클러스터를 구성할 수 있는 역량을 갖추게 될 것입니다.

Kafka 복제 기본 사항 이해하기

Kafka의 아키텍처는 확장성과 병렬성을 위해 파티션 개념에 의존합니다. 이러한 파티션 내의 데이터가 손실되지 않고 브로커 장애 발생 시에도 계속 액세스할 수 있도록 보장하기 위해 Kafka는 복제를 사용합니다. 각 파티션에는 클러스터 내 여러 브로커에 분산된 여러 복사본, 즉 복제본이 있습니다.

복제본과 파티션

각 파티션에는 두 가지 유형의 복제본이 있습니다.

  • 리더 복제본: 각 파티션에 대해 하나의 복제본이 리더로 지정됩니다. 리더는 해당 파티션에 대한 모든 읽기 및 쓰기 요청을 처리합니다. 프로듀서는 항상 리더에게 데이터를 쓰고, 컨슈머는 일반적으로 리더로부터 읽습니다.
  • 팔로워 복제본: 파티션의 나머지 모든 복제본은 팔로워입니다. 팔로워는 해당 파티션 리더로부터 데이터를 수동적으로 복제합니다. 이들의 주요 역할은 백업 역할을 하여 리더가 실패할 경우 인계할 준비를 하는 것입니다.

복제 계수 (Replication Factor)

복제 계수는 Kafka 클러스터에 존재하는 파티션의 복사본 수를 정의합니다. 예를 들어, 복제 계수가 3이라는 것은 각 파티션에 하나의 리더와 두 개의 팔로워 복제본이 있음을 의미합니다. 복제 계수가 높을수록 내구성과 가용성은 증가하지만, 디스크 공간과 네트워크 대역폭도 더 많이 소비됩니다.

동기 복제본 (ISRs)

동기 복제본(ISRs)은 Kafka의 내구성 보장에 매우 중요한 개념입니다. ISR은 리더와 완전히 동기화되어 "동기화 상태"로 간주되는 복제본(리더 또는 팔로워)입니다. Kafka는 각 파티션에 대한 ISR 목록을 유지 관리합니다. 이 목록은 다음과 같은 이유로 매우 중요합니다.

  • 내구성: 프로듀서가 승인(acks)을 all 또는 -1로 설정하여 메시지를 보낼 때, 쓰기가 성공한 것으로 간주되기 전에 모든 ISR에 의해 메시지가 커밋될 때까지 기다립니다. 이는 메시지가 여러 브로커에 영구적으로 기록되었음을 보장합니다.
  • 가용성: 리더 브로커가 실패하면, 사용 가능한 ISR 중에서 새 리더가 선출됩니다. 모든 ISR이 최신 데이터를 가지고 있으므로 이 세트에서 새 리더를 선출하는 것은 데이터 손실을 보장합니다.

팔로워 복제본은 느리거나, 데이터 가져오기를 중단하거나, 충돌하면 동기화에서 벗어날 수 있습니다. Kafka는 이를 모니터링하며, 팔로워가 리더보다 너무 많이 지연되면(replica.lag.time.max.ms로 제어됨), ISR 목록에서 제거됩니다. 동기화되면 ISR 세트에 다시 참여할 수 있습니다.

리더 선출: 지속적인 가용성 보장

파티션의 현재 리더 복제본을 사용할 수 없게 되면(예: 브로커 충돌 또는 네트워크 문제), Kafka는 자동으로 리더 선출 프로세스를 시작합니다. 주된 목표는 나머지 ISR 중에서 새 리더를 선출하여 파티션이 읽기 및 쓰기에 계속 사용할 수 있도록 보장하는 것입니다.

선출 프로세스는 다음과 같이 작동합니다.

  1. 감지: 클러스터 컨트롤러(Kafka 브로커 중 하나로 선출됨)가 리더의 장애를 감지합니다.
  2. 선택: 컨트롤러는 해당 파티션의 나머지 ISR 중 하나를 새 리더로 선택합니다. 모든 ISR은 동일하고 최신 데이터가 보장되므로 이 프로세스는 데이터 일관성을 유지합니다.
  3. 업데이트: 컨트롤러는 클러스터의 모든 브로커에게 새 리더에 대해 알립니다.

비동기 리더 선출 (Unclean Leader Election)

Kafka는 unclean.leader.election.enable이라는 구성 매개변수를 제공하며, 이는 ISR이 하나도 없을 때(예: 모든 ISR이 동시에 충돌한 경우) 리더 선출이 어떻게 작동하는지를 결정합니다.

  • unclean.leader.election.enablefalse(기본값이자 권장 설정)인 경우, ISR이 없으면 Kafka는 새 리더를 선출하지 않습니다. 이는 비-ISR 팔로워를 선출하면 데이터 손실로 이어질 수 있으므로 가용성보다 데이터 내구성을 우선시합니다.
  • unclean.leader.election.enabletrue인 경우, Kafka는 ISR이 아니더라도 사용 가능한 모든 복제본 중에서 새 리더를 선출하며, 이는 커밋된 메시지를 모두 복제하지 않았을 수 있습니다. 이는 엄격한 데이터 내구성보다 가용성을 우선시하며 데이터 손실 위험이 있지만 파티션이 계속 작동하도록 보장합니다.

경고: unclean.leader.election.enable을 활성화하는 것은 매우 신중하게 수행해야 하며, 일반적으로 가용성이 절대적으로 중요하고 약간의 데이터 손실 위험을 감수할 수 있는 시나리오(예: 중요하지 않은 일시적인 데이터)에서만 수행해야 합니다. 대부분의 프로덕션 시스템에서는 false로 유지해야 합니다.

Kafka 복제 구성하기

복제 설정은 브로커 수준(새 토픽에 대한 기본값)과 토픽 수준(기본값을 재정의하거나 기존 토픽 수정) 모두에서 구성할 수 있습니다.

브로커 수준 구성

이 설정은 각 Kafka 브로커의 server.properties 파일에 정의되며, 명시적인 복제 설정 없이 생성된 모든 새 토픽의 기본값으로 적용됩니다.

  • default.replication.factor: 새 토픽의 기본 복제 계수를 설정합니다. 프로덕션의 경우, 값이 3인 경우가 일반적이며, 데이터 손실이나 다운타임 없이 n-1 (3-1=2) 브로커 장애를 허용합니다.
    properties default.replication.factor=3

  • min.insync.replicas: acksall 또는 -1로 설정되었을 때 프로듀서가 메시지를 성공적으로 쓰기 위해 필요한 최소 ISR 수를 정의하는 중요한 설정입니다. ISR 수가 이 값 미만으로 떨어지면 프로듀서는 오류(예: NotEnoughReplicasException)를 수신합니다. 이는 강력한 내구성 보장을 보장합니다.
    properties min.insync.replicas=2
    > : min.insync.replicas는 일반적으로 (replication.factor / 2) + 1 또는 replication.factor - 1로 설정해야 합니다. replication.factor=3의 경우, min.insync.replicas=2가 좋은 균형이며 브로커 하나 장애를 허용합니다.

  • num.replica.fetchers: 팔로워 브로커가 리더로부터 메시지를 가져오는 데 사용하는 스레드 수입니다. 이 수를 늘리면 많은 팔로워 복제본을 호스팅하는 브로커의 복제 처리량을 향상시킬 수 있습니다.
    properties num.replica.fetchers=1

토픽 수준 구성

새 토픽을 생성하거나 기존 토픽을 수정할 때 브로커 기본값을 재정의하고 특정 복제 설정을 적용할 수 있습니다.

특정 복제 설정으로 토픽 생성하기

kafka-topics.sh 명령줄 도구를 사용합니다.

kafka-topics.sh --create --bootstrap-server localhost:9092 \n                --topic my_replicated_topic \n                --partitions 3 \n                --replication-factor 3 \n                --config min.insync.replicas=2

이 예시에서 my_replicated_topic은 3개의 파티션을 가지며, 각 파티션은 3번 복제되고, 성공적인 쓰기(acks=all 사용 시)를 위해 최소 2개의 ISR이 필요합니다.

기존 토픽의 복제 설정 수정하기

일부 토픽 수준 복제 설정을 변경할 수 있습니다. 이 명령을 사용하여 기존 토픽의 replication-factor증가시킬 수는 있지만 직접 감소시킬 수는 없습니다. 감소시키려면 파티션의 수동 재할당이 필요합니다.

my_existing_topic의 복제 계수를 증가시키려면(예: 2에서 3으로):

kafka-topics.sh --alter --bootstrap-server localhost:9092 \n                --topic my_existing_topic \n                --replication-factor 3

기존 토픽에 min.insync.replicas를 설정하려면:

kafka-topics.sh --alter --bootstrap-server localhost:9092 \n                --topic my_existing_topic \n                --config min.insync.replicas=2

참고: 복제 계수를 늘리면 Kafka가 기존 데이터를 새 복제본에 복사하는 자동 프로세스가 트리거됩니다. 이는 특히 대규모 토픽의 경우 I/O 집약적일 수 있습니다.

프로듀서 보증 및 승인 (acks)

Kafka 프로듀서의 acks(승인) 설정은 전송된 메시지에 대한 내구성 보장을 결정합니다. 이는 min.insync.replicas와 함께 작동합니다.

  • acks=0: 프로듀서는 메시지를 브로커에 보내고 어떠한 승인도 기다리지 않습니다. 이는 내구성이 가장 낮지만(메시지 손실 가능) 처리량은 가장 높습니다.
  • acks=1: 프로듀서는 리더 복제본이 메시지를 수신하고 승인할 때까지 기다립니다. 리더가 팔로워가 메시지를 복제하기 전에 실패하면 데이터 손실이 발생할 수 있습니다.
  • acks=all 또는 acks=-1: 프로듀서는 리더가 메시지를 수신했을 뿐만 아니라 모든 ISR이 메시지를 수신하고 커밋할 때까지 기다립니다. 이는 가장 강력한 내구성 보장을 제공합니다. min.insync.replicas가 구성된 경우, 프로듀서는 성공적인 승인을 위해 해당 수의 ISR이 메시지를 커밋할 때까지 기다립니다. 이는 중요 데이터에 권장되는 설정입니다.

예시 프로듀서 구성(Java):

Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("acks", "all"); // 최고 내구성 보장

Producer<String, String> producer = new KafkaProducer<>(props);
// ... 메시지 전송

복제를 통한 내결함성 보장

Kafka 복제는 데이터 손실이나 서비스 중단 없이 브로커 장애를 허용하도록 설계되었습니다. 클러스터가 견딜 수 있는 동시 브로커 장애 수는 replication.factormin.insync.replicas 설정에 직접적으로 의존합니다.

  • replication.factor=N인 클러스터는 min.insync.replicas가 적절하게 설정되었다고 가정할 때, 최대 N-1개의 브로커 장애를 데이터 손실 없이 견딜 수 있습니다.
  • replication.factor=3이고 min.insync.replicas=2인 경우, 브로커 하나(리더 또는 팔로워)가 손실되어도 완전한 기능과 내구성을 유지할 수 있습니다. 두 번째 브로커가 실패하면 ISR 수는 1(또는 마지막 팔로워였다면 0)로 떨어져 acks=all을 사용하는 프로듀서가 차단되거나 실패하게 되어 데이터 안전을 우선시합니다.

모범 사례: 랙 인식 복제 (Rack-Aware Replication)

클라우드 환경에서 더욱 강력한 내결함성을 위해 Kafka 브로커와 그 복제본을 서로 다른 물리적 랙 또는 가용 영역에 분산시키는 것을 고려하십시오. Kafka는 랙 인식 복제를 지원하며, 컨트롤러는 단일 물리적 장애 도메인에서 여러 복제본을 손실할 가능성을 최소화하기 위해 파티션의 리더 및 팔로워 복제본을 서로 다른 랙에 분산시키려고 시도합니다.

이를 활성화하려면 각 브로커의 server.properties에서 broker.rack 속성을 설정합니다.

# 브로커 1의 server.properties에서
broker.id=1
broker.rack=rack-a

# 브로커 2의 server.properties에서
broker.id=2
broker.rack=rack-b

# 브로커 3의 server.properties에서
broker.id=3
broker.rack=rack-a

그러면 Kafka는 복제본을 다른 랙에 배치하려고 시도합니다.

복제 상태 모니터링

Kafka 클러스터의 복제 상태를 정기적으로 모니터링하는 것은 내구성이나 가용성에 영향을 미치기 전에 잠재적인 문제를 사전에 식별하는 데 필수적입니다. 확인해야 할 주요 메트릭은 다음과 같습니다.

  • UnderReplicatedPartitions (복제 부족 파티션 수): 복제 계수보다 적은 ISR을 가진 파티션 수입니다. 0이 아닌 값은 잠재적인 문제를 나타냅니다.
  • OfflinePartitionsCount (오프라인 파티션 수): 활성 리더가 없는 파티션 수입니다. 이는 심각한 중단과 데이터 가용성 상실을 의미합니다.
  • LeaderAndIsr/PartitionCount: 파티션당 리더 및 ISR의 총 수입니다.

You can check the replication status of a topic using the kafka-topics.sh command:

kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic my_replicated_topic

예시 출력:

Topic: my_replicated_topic  PartitionCount: 3   ReplicationFactor: 3    Configs: min.insync.replicas=2
    Topic: my_replicated_topic  Partition: 0    Leader: 0   Replicas: 0,1,2 Isr: 0,1,2
    Topic: my_replicated_topic  Partition: 1    Leader: 1   Replicas: 1,2,0 Isr: 1,2,0
    Topic: my_replicated_topic  Partition: 2    Leader: 2   Replicas: 2,0,1 Isr: 2,0,1

이 출력에서:
* Leader: 해당 파티션의 현재 리더인 브로커 ID입니다.
* Replicas: 이 파티션에 대한 복제본을 호스팅하는 모든 브로커 ID 목록입니다.
* Isr: 현재 동기 복제본 세트에 속한 브로커 ID 목록입니다.

만약 어떤 브로커 ID가 Replicas에는 있지만 Isr에는 없다면, 해당 복제본은 동기화되지 않은 것입니다.

모범 사례 및 문제 해결 팁

  • replication.factor 현명하게 선택: 일반적으로 프로덕션은 3, 중요도가 낮은 데이터는 2, 개발 환경은 1입니다. 숫자가 높을수록 내구성은 증가하지만 리소스 소비도 증가합니다.
  • min.insync.replicas 구성: acks=all을 사용할 때 내구성 보장이 충족되도록 항상 설정하십시오.
  • 복제본 분산: broker.rack을 사용하여 복제본이 서로 다른 물리적 장애 도메인에 분산되도록 하십시오.
  • 적극적인 모니터링: Kafka의 JMX 메트릭 또는 Prometheus/Grafana와 같은 도구를 사용하여 UnderReplicatedPartitions를 확인하십시오.
  • 비동기 리더 선출 피하기: 강력한 내구성 보장을 위해 프로덕션에서는 unclean.leader.election.enablefalse로 유지하십시오.
  • 브로커 재시작 처리: 브로커를 재시작할 때는 한 번에 하나씩 수행하여 팔로워가 재동기화하고 min.insync.replicas를 유지할 수 있도록 하십시오.

결론

Kafka 복제는 데이터 내구성과 고가용성의 초석입니다. replication.factor, min.insync.replicas를 신중하게 구성하고 프로듀서 acks가 이러한 설정과 상호 작용하는 방식을 이해함으로써, 장애에 탄력적이고 스트리밍 데이터에 대한 강력한 보장을 제공하는 Kafka 클러스터를 설계할 수 있습니다.

랙 인식 복제 및 강력한 모니터링과 같은 기능을 활용하면 가장 까다로운 프로덕션 환경에서도 중요한 데이터 파이프라인을 계속 운영하고 데이터를 안전하게 유지할 수 있습니다. 잘 구성된 복제 전략은 선택 사항이 아니라 안정적인 모든 Kafka 배포의 필수 요소입니다.