카프카 주키퍼 연결 문제 심층 분석

브로커 불안정 및 서비스 중단을 야기하는 지속적인 카프카 주키퍼 연결 실패를 진단하고 해결합니다. 이 가이드는 `server.properties` 및 `zoo.cfg`에 대한 중요한 구성 검사, 네트워크 문제 해결 단계(방화벽 및 지연 시간), 그리고 세션 시간 초과 메커니즘 분석을 상세히 다룹니다. 메타데이터 및 조정을 위해 ZooKeeper에 의존하는 카프카 클러스터를 안정화하기 위한 실행 가능한 단계를 알아보세요.

48 조회수

Kafka ZooKeeper 연결 문제 심층 분석

Apache Kafka는 클러스터 조정, 메타데이터 관리, 리더 선출, 구성 저장 등을 위해 Apache ZooKeeper에 크게 의존합니다. Kafka 브로커가 ZooKeeper와의 연결을 잃으면, 브로커는 제대로 작동하지 않게 됩니다. 즉, 스스로를 등록하거나, 리더 선출 요청에 응답하거나, 트래픽을 처리할 수 없게 됩니다. 이러한 불안정성은 종종 NoControllerEpoch 오류, 잦은 브로커 재시작 또는 파티션 사용 불가 등의 형태로 나타납니다.

이 가이드는 Kafka 브로커와 ZooKeeper 앙상블 간의 지속적인 연결 문제를 진단하고 해결하기 위한 포괄적인 문제 해결 설명서 역할을 합니다. 안정적이고 높은 처리량의 분산 이벤트 스트리밍 플랫폼을 유지하려면 이 두 시스템 간의 상호 의존성을 이해하는 것이 중요합니다.


Kafka-ZooKeeper 관계 이해

연결 문제를 해결하기 전에 Kafka가 ZooKeeper를 필요로 하는 이유를 이해하는 것이 필수적입니다. ZooKeeper는 클러스터 메타데이터의 단일 진실 공급원 역할을 합니다. 구체적으로 Kafka는 ZooKeeper를 다음과 같은 용도로 사용합니다.

  1. 브로커 등록: 브로커는 시작 시 ZooKeeper에 자신을 등록합니다.
  2. 토픽 구성: 파티션 할당, 복제본 배치 및 구성 재정의를 저장합니다.
  3. 컨트롤러 선출: 파티션 및 브로커 상태를 관리하는 Kafka 컨트롤러를 선택하고 유지 관리합니다.

브로커가 너무 오랫동안 (세션 타임아웃 설정을 초과하여) ZooKeeper와의 연결을 잃으면, 결국 종료되거나 격리되어 클러스터 성능 저하 또는 완전한 실패로 이어집니다.

1단계: 구성 확인

대부분의 ZooKeeper 연결 문제는 Kafka 클라이언트 설정 또는 ZooKeeper 서비스 구성 자체의 잘못된 설정에서 비롯됩니다. 항상 이곳부터 시작하십시오.

1. Kafka 브로커 구성 (server.properties) 검토

ZooKeeper 앙상블을 가리키는 연결 문자열이 올바르고 모든 브로커에서 접근 가능한지 확인하십시오.

zookeeper.connect 매개변수

이 속성은 앙상블의 모든 ZooKeeper 서버의 호스트 이름/IP 및 포트를 쉼표로 구분하여 나열해야 합니다. 사용자 지정 루트 경로를 사용하는 경우가 아니면 Znode 경로는 포함하면 안 됩니다.

구성 예시:

# 모든 앙상블 구성원 나열
zookeeper.connect=zk01.example.com:2181,zk02.example.com:2181,zk03.example.com:2181

# 선택 사항: 연결 타임아웃 설정 (기본값 6초)
zookeeper.connection.timeout.ms=6000

Znode 경로 지정

Kafka를 특정 Znode 경로(예: /kafka)를 사용하도록 구성한 경우, 이 경로가 ZooKeeper에 존재하고 Kafka 구성에 올바르게 설정되었는지 확인하십시오.

# 특정 경로를 사용하는 경우 여기에 나열되었는지 확인
zookeeper.connect=zk01:2181,zk02:2181/kafka

2. ZooKeeper 서버 구성 (zoo.cfg) 검토

ZooKeeper 자체에서 사용하는 포트를 확인하십시오. 기본 수신 포트는 2181입니다.

ZooKeeper 앙상블이 표준이 아닌 포트에서 실행되는 경우, Kafka 브로커가 server.properties에서 이러한 포트와 일치하도록 구성되었는지 확인하십시오.

2단계: 네트워크 및 방화벽 진단

Kafka 브로커와 ZooKeeper 노드 간의 연결 문제는 종종 네트워크 중단 또는 엄격한 방화벽 규칙으로 인해 발생합니다.

1. 기본 연결 테스트

표준 도구를 사용하여 Kafka 브로커와 ZooKeeper 앙상블의 각 구성원 간에 포트가 열려 있고 도달 가능한지 확인하십시오.

nc (Netcat) 또는 telnet 사용:

Kafka 브로커에서 ZooKeeper 노드를 대상으로 이 명령을 실행하십시오.

# 포트 2181에서 zk01에 대한 연결 테스트
telnet zk01.example.com 2181
# 또는
nc -zv zk01.example.com 2181

연결이 성공하면 포트가 열려 있음을 나타냅니다. 실패하면 방화벽 규칙(iptables, 보안 그룹 등)을 조사하십시오.

2. 지연 시간 및 지터 분석

높은 네트워크 지연 시간이나 패킷 손실은 포트가 열려 있더라도 연결 타임아웃을 유발할 수 있습니다. ZooKeeper는 지연 시간에 매우 민감합니다.

팁: ping을 사용하여 왕복 시간(RTT)을 확인하십시오. RTT가 지속적으로 50ms를 초과하면 Kafka 브로커를 ZooKeeper 앙상블에 더 가깝게 이동시키거나, 근본적인 네트워크 혼잡을 조사해야 할 수 있습니다.

3단계: 서비스 및 세션 타임아웃 문제 해결

ZooKeeper는 세션을 관리하기 위해 시간 기반 메커니즘을 사용합니다. 클라이언트(Kafka 브로커)가 세션 타임아웃 기간 내에 하트비트를 보내지 못하면 ZooKeeper는 세션을 만료시켜 브로커가 재연결을 시도하거나 종료하도록 강제합니다.

1. ZooKeeper 세션 타임아웃 구성

세션 안정성을 제어하는 주요 매개변수는 다음과 같습니다.

  • zookeeper.session.timeout.ms (Kafka): Kafka가 ZooKeeper 연결이 끊어졌다고 판단하고 복구/종료를 시작하기 전에 기다리는 시간입니다. 기본값은 일반적으로 6000ms(6초)입니다.
  • tickTime (ZooKeeper zoo.cfg): 하트비트 및 타임아웃에 사용되는 시간의 기본 단위입니다. 기본값은 보통 2000ms(2초)입니다.

Kafka의 세션 타임아웃은 ZooKeeper의 tickTime을 기반으로 계산됩니다. Kafka 클라이언트의 최대 세션 타임아웃은 일반적으로 $2 \times \text{tickTime}$입니다 (Kafka의 기본 세션 타임아웃은 종종 내부적으로 또는 구성을 통해 명시적으로 더 높게 설정됩니다).

높은 부하 기간 동안 잦은 연결 끊김이 관찰되면 Kafka의 server.properties에서 zookeeper.session.timeout.ms를 늘리거나 ZooKeeper의 zoo.cfg에서 tickTime을 늘려야 할 수 있으며, Kafka 설정이 호환되는지 확인해야 합니다.

경고: ZooKeeper tickTime의 변경은 모든 ZooKeeper 앙상블 구성원을 순차적으로 다시 시작해야 하므로, 피크 시간 외에 주의해서 수행해야 합니다.

2. 오류에 대한 브로커 로그 분석

Kafka 서버 로그는 연결 손실을 진단하는 최종 출처입니다. ZooKeeper 상호 작용과 관련된 패턴을 찾으십시오.

로그 메시지 패턴 의미
[Controller node: ... ] Lost connection to ZooKeeper. 세션이 만료되었거나 네트워크 오류가 발생했습니다.
[Controller node: ... ] Reconnecting to ZooKeeper... 임시 연결 끊김; 지연 시간이 낮으면 복구 가능성이 있습니다.
[Controller node: ... ] Could not connect to ZooKeeper 초기 연결 실패, 종종 잘못된 호스트 이름/포트 또는 방화벽 때문입니다.
[SessionExpiredError] ZooKeeper가 하트비트 부족으로 인해 적극적으로 연결을 종료했습니다.

잦은 Lost connection 메시지가 보이면 타임스탬프 차이를 확인하십시오. 정기적으로 (예: 6초마다) 발생하는 경우, 네트워크 지터 또는 브로커의 리소스 부족으로 인한 하트비트 실패를 직접적으로 나타냅니다.

3. 브로커 리소스 경합

Kafka 브로커가 극심한 부하(CPU 포화 또는 높은 I/O 대기) 상태에 있으면, 네트워크 경로가 깨끗하더라도 프로세스가 제시간에 ZooKeeper에 하트비트를 보내지 못하여 세션 만료가 발생할 수 있습니다.

실행 가능한 점검: 연결이 끊어질 때 Kafka 브로커의 CPU 사용량 및 가비지 컬렉션(GC) 중단을 모니터링하십시오. 긴 GC 중단은 하트비트 스레드가 마감 시간을 놓치게 만들기 쉽습니다.

4단계: 클러스터 복구 및 모범 사례

재시작 전략

연결 문제가 식별되고 해결된 경우(예: 방화벽 규칙 업데이트), 브로커는 다시 연결해야 합니다. Kafka 서비스를 단순히 다시 시작하는 것이 깨끗한 재연결 시도를 강제하는 가장 빠른 방법인 경우가 많습니다.

# systemd를 사용하는 시스템의 예시
sudo systemctl restart kafka

안정성을 위한 모범 사례

  1. 쿼럼 관리: 항상 홀수 개수(3개 또는 5개)의 ZooKeeper 노드를 실행하여 쿼럼 기능을 유지하고 분할 브레인 시나리오를 방지하십시오.
  2. 전용 네트워크: 가능하다면 Kafka 브로커와 ZooKeeper 노드를 저지연 전용 네트워크 세그먼트에 배치하십시오.
  3. 구성 일관성: 모든 Kafka 브로커가 정확히 동일한 zookeeper.connect 문자열을 사용하도록 하십시오. 일관되지 않은 문자열은 브로커가 잘못된 서버에 연결을 시도하게 만듭니다.
  4. 모니터링: ZooKeeper 지연 시간 및 Kafka 브로커 [Lost connection] 로그에 대한 사전 예방적 모니터링을 구현하십시오. 사용자 불만이 발생하기 전에 이러한 문제를 발견하지 마십시오.

구성을 체계적으로 확인하고, 네트워크 경로를 테스트하고, ZooKeeper의 하트비트 설정과 관련하여 세션 타임아웃을 조정함으로써, 지속적인 Kafka ZooKeeper 연결 문제의 대부분을 해결하고 안정적인 클러스터 운영을 보장할 수 있습니다.