BackEnd/Kafka

[Kafka] Kafka의 고가용성

연향동큰손 2025. 8. 18. 17:18

 

node란?

  • Kafka가 설치되어 있는 서버 단위
  • 싱글노드 클러스터의 경우, 한 노드의 고장이 서비스 장애로 이어질 수 있기 때문에 최소 3대의 노드를 구성하여 단일점 오류를 방지한다.

 

브로커(broker)와 컨트롤러(controller)

  • Kafka 서버는 크게 브로커와 컨트롤러로 구성되어있다.
  • 브로커 : 메시지를 저장하고 클라이언트의 요청을 처리하는 역할 (9092 포트)
  • 컨트롤러 : 브로커들간의 연동과 전반적인 클러스터의 상태를 총괄한다.(9093 포트)

 

레플리케이션(Replication)이란?

  • Kafka의 가용성과 안정성을 높이기 위해 토픽의 파티션을 여러 노드에 복제하는 것을 의미.
  • 리더 파티션과 팔로워 파티션으로 구분된다.
  • 리더 파티션 : 프로듀서나 컨슈머가 직접 메시지를 읽고 쓰는 파티션
  • 팔로워 파티션 : 리더 파티션의 메시지를 실시간으로 복제하며 유지한다.

팔로워 파티션이 리더 파티션의 메시지를 복제하여 가지고 있기 때문에 리더 파티션의 노드에 장애가 생겨도 메시지를 정상적으로 이어서 처리할 수 있다.

 

 

 

Kafka 서버 3대 셋팅해보기

 

한개의 EC2 인스턴스에 3개의 Kafka 노드를 한번에 실행해봤다.

 

1. Kafka 설정 수정

$ cd kafka_2.13-4.0.0/config
$ vi server.properties

 

 

server.properties 수정

...
# kafka 노드를 식별하는 ID
node.id=1
# 클러스터를 구성할 컨트롤러의 노드 주소 목록을 설정
# (추가적인 노드의 컨트롤러를 19093, 29093번 포트에 실행시킬 예정)
controller.quorum.bootstrap.servers={EC2 Public IP}:9093,{EC2 Public IP}:19093,{EC2 Public IP}:29093
# 브로커, 컨트롤러 프로세스를 실행시킬 포트를 지정
# (브로커를 PLAINTEXT, 컨트롤러를 CONTROLLER라고 지칭)
listeners=PLAINTEXT://:9092,CONTROLLER://:9093
# 외부에서 접근할 수 있는 주소
advertised.listeners=PLAINTEXT://{EC2 Public IP}:9092,CONTROLLER://{EC2 Public IP}:9093
# kafka가 데이터(kafka 설정, 브로커가
log.dirs=/tmp/kafka-logs-1
받은 메시지, 로그 등)를 저장할 디렉터리 경로 설정
...

 

 

2. 설정 파일 복사

$ cp server.properties server2.properties
$ cp server.properties server3.properties

 

 

3. 복사한 설정파일 수정하기

 

server2.properties

...
# kafka 노드를 식별하는 ID
node.id=2
# 클러스터를 구성할 컨트롤러의 노드 주소 목록을 설정
# (추가적인 노드의 컨트롤러를 19093, 29093번 포트에 실행시킬 예정)
controller.quorum.bootstrap.servers={EC2 Public IP}:9093,{EC2 Public IP}:19093,{EC2 Public IP}:29093
# 브로커, 컨트롤러 프로세스를 실행시킬 포트를 지정
# (브로커를 PLAINTEXT, 컨트롤러를 CONTROLLER라고 지칭)
listeners=PLAINTEXT://:19092,CONTROLLER://:19093
# 외부에서 접근할 수 있는 주소
advertised.listeners=PLAINTEXT://{EC2 Public IP}:19092,CONTROLLER://{EC2 Public IP}:19093
# kafka가 데이터(kafka 설정, 브로커가
log.dirs=/tmp/kafka-logs-2
받은 메시지, 로그 등)를 저장할 디렉터리 경로 설정
...

 

server3.properties

...
# kafka 노드를 식별하는 ID
node.id=3
# 클러스터를 구성할 컨트롤러의 노드 주소 목록을 설정
# (추가적인 노드의 컨트롤러를 19093, 29093번 포트에 실행시킬 예정)
controller.quorum.bootstrap.servers={EC2 Public IP}:9093,{EC2 Public IP}:19093,{EC2 Public IP}:29093
# 브로커, 컨트롤러 프로세스를 실행시킬 포트를 지정
# (브로커를 PLAINTEXT, 컨트롤러를 CONTROLLER라고 지칭)
listeners=PLAINTEXT://:29092,CONTROLLER://:29093
# 외부에서 접근할 수 있는 주소
advertised.listeners=PLAINTEXT://{EC2 Public IP}:29092,CONTROLLER://{EC2 Public IP}:29093
# kafka가 데이터(kafka 설정, 브로커가
log.dirs=/tmp/kafka-logs-3
받은 메시지, 로그 등)를 저장할 디렉터리 경로 설정
...

 

 

 

4. 첫 노드는 클러스터 초기화하고,  나머지 노드는 해당 클러스터에 연결하기

cd .. # kafka 디렉터리로 이동
# kafka 종료하기
$ bin/kafka-server-stop.sh
# 처음 실행하는 kafka 노드는 아래 명령어로 실행
$ KAFKA_CLUSTER_ID="$(bin/kafka-storage.sh random-uuid)"
$ KAFKA_CONTROLLER_ID="$(bin/kafka-storage.sh random-uuid)"

$ bin/kafka-storage.sh format \
-t $KAFKA_CLUSTER_ID \
-c config/server.properties \
--initial-controllers "1@localhost:9093:$KAFKA_CONTROLLER_ID"

# 추가로 연동시킬 kafka 노드는 아래 명령어로 실행
# 주의 : server.properties가 아니라 server2.properties를 사용해야 한다.
$ bin/kafka-storage.sh format \
-t $KAFKA_CLUSTER_ID \
-c config/server2.properties \
--no-initial-controllers

# 추가로 연동시킬 kafka 노드는 아래 명령어로 실행
# 주의 : server.properties가 아니라 server3.properties를 사용해야 한다.
$ bin/kafka-storage.sh format \
-t $KAFKA_CLUSTER_ID \
-c config/server3.properties \
--no-initial-controllers

 

 

5. Kafka 노드 3대 전부 실행

# kafka 노드 3대 실행하기
$ bin/kafka-server-start.sh config/server.properties
$ bin/kafka-server-start.sh config/server2.properties
$ bin/kafka-server-start.sh config/server3.properties

 

 

6. 클러스터에 컨트롤러 등록하기

$ bin/kafka-metadata-quorum.sh \
--command-config config/server2.properties \
--bootstrap-server localhost:9092 \
add-controller


$ bin/kafka-metadata-quorum.sh \
--command-config config/server3.properties \
--bootstrap-server localhost:9092 \
add-controller

 

 

7. 토픽 생성

$ bin/kafka-topics.sh \
--bootstrap-server localhost:9092 \
--create \
--topic email.send \
--partitions 1 \
--replication-factor 3

 

 

토픽 세부 정보를 조회 했을때 Replicas와 lsr에 3개의 숫자가 있다면 3개의 Kafka 서버가 정상적으로 잘 연동되고 있다는 뜻이다.

 

  • PartitionCount : 해당 토픽의 파티션 수
  • ReplicationFactor : 해당 토픽의 레플리케이션 수
  • Partition : 파티션 번호
  • Leader : 해당 토픽의 리더 파티션을 가지고 있는 노드 id
  • Replicas : 해당 토픽의 파티션을 복제하기로 설정된 노드들의 id
  • Isr : 리더 파티션과 똑같은 상태로 복제가 완료된 노드들의 id

 

팔로워 파티션에 메시지를 넣을 경우

 

만약 팔로워 파티션에 메시지를 넣어도 모든 노드에서 메시지가 잘 조회되는 것을 확인할 수 있다.

 

왜냐하면 Kafka 프로듀서는 메시지를 보내기 전에 해당 파티션의 리더가 누구인지 확인하고, 자동으로 리더 파티션에 메시지를 전송해주기 때문이다.

 

리더 파티션에 장애가 생길 경우

 

지금까지 1번 노드가 리더 파티션을 가지고 있었는데, 1번 노드를 종료 시켜서 리더 파티션을 가진 노드의 장애가 발생한 것을 가정해보자.

 

  • Ctrl+c로 1번 노드 종료

1번 노드 종료 후 토픽 세부정보를 확인해보면 Leader값이 2로 변경되었고, Isr도 1번 노드가 빠진 것 을 확인할 수 있다.

 

이를 통해 리더 파티션에 장애가 발생하면 팔로워 파티션이 리더 역할을 대신 수행하게끔 리더 파티션으로 승격된다는 것을 알 수 있다.

 

'BackEnd > Kafka' 카테고리의 다른 글

[Kafka] MSA 구조에서의 Kafka 사용  (0) 2025.08.19
[Kafka] Kafka 메시지 처리 성능 향상 (Partition)  (2) 2025.08.15
[Kafka] Dead Letter Topic  (2) 2025.08.14
Spring Boot + Kafka 메시지 테스트  (2) 2025.08.14
Kafka란?  (1) 2025.08.12