Kafka 고가용성 확보하기 (node, broker, controller, cluster, replication) (+실습)

2025. 12. 5. 14:41·개발 공부/kafka

서론

  • 이번 시간에는 kafka 장애 시 대처하기 위해 여러 개의 kafka 서버를 띄우고 장애시 대처하는 과정을 볼 것이다. 

노드, 브로커, 컨트롤러, 클러스터, 레플리케이션이란?

  • kafka의 기본 개념들로 고가용성 설정을 위해서는 필요한 지식이다.

노드 (node)

  • kafka에 설치 되어 있는 서버 단위를 말한다.

  • 노드가 고장이 나면 서비스 장애가 일어나기에 실무에서는 노드를 최소 3대 이상 두는 편이다.

클러스터(cluster)

  • 여러 대의 서버가 연결되어 하나의 서버 처럼 동작하는 서버들의 집합을 의미한다.

  • 위 그림처럼 3개의 서버가 유기적으로 연결되어 하나의 서버가 고장이 나더라도 다른 노드에서 대신 받아주는 등 유기적으로 사용이 되는 서버의 집합을 클러스터라고 한다.

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

  • kafka 서버는 크게 브로커와 컨트롤러로 나뉜다
    • 브로커는 메시지를 저장하고 클라이언트의 요청을 처리하는 역할을 한다.
    • 컨트롤러는 브로커 간의 연동과 전반적인 클러스터의 상태를 총괄한다.

  • 위와 같이 설치 될 수도 있고 컨트롤러와 브로커를 다른 서버에 설치할 수도 있다.
  • 기본적으로 컨트롤러는 9093, 브로커는 9092 포트에서 실행이 된다
    • 다른 프로세스에서 실행이 된다는 뜻이다.

레플리케이션(replication)

  • 토픽의 파티션을 여러 노드에 복제하는 것을 의미한다.

  • 레플리케이션 설정을 하면 해당 토픽을 다른 노드에도 복사해놓고 동기화를 시킨다.
  • 리더 파티션과 팔로우 파티션으로 나뉘며 리더 파티션은 직접 메시지를 읽고 쓰이는 역할을 하고 팔로우 파티션은 리더 파티션에 메시지가 들어오면 자동으로 메시지를 복사해 놓았다가 리더 파티션에서 장애가 일어나면 팔로우 중 하나가 리더를 맡아 서비스 장애가 일어나지 않도록 한다
  • 레플리케이션 수는 kafka 서버 수만큼 설정할 수 있지만, 실무에서는 레플리케이션 수를 2나 3으로 설정해서 사용하는 편이다.

 

[실습] Kafka 서버 3대 띄워 레플리케이션으로 만들기

  • 실습 전 EC2에 kafka가 설치되어 있어야 한다. 필요하다면 아래 글을 참고하자
 

2. Kafka 간단히 설치해보기 (feat. EC2) (+실습)

환경 세팅 전 갖추어야할 것AWS 계정적당한 성능의 EC2이번 실습은 AWS 프리티어에서 진행하기 위해 EC2 t2.micro (메모리 1GB)에서 진행함EC2에 Kafka 설치 / 실행하기1. JDK 17 설치하기Kafka를 실행시키려

student-developer-story.tistory.com

 

실습 시작

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-metadata-quorum.sh \
	--bootstrap-server localhost:9092 describe \
	--status

  • currentVoters가 3개이면 잘 된 것 이다.

토픽 세부 정보 출력값 정보 해석하기 (Isr, Leader, Replicas 등)

bin/kafka-topics.sh \
  --bootstrap-server localhost:9092 \
  --describe \
  --topic email.send

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

 

팔로워 파티션에 메시지를 넣으면 어떻게 될까?

  • Kafka 프로듀서는 메시지를 보내기 전에 해당 파티션의 리더가 누구인지 확인하고, 자동으로 리더 파티션에 메시지를 전송해준다. 이게 가능한 이유는 kafka 노드들끼리 서로 연동되어 있어서, 리더 파티션을 가진 Kafka 노드가 누군지에 대한 정보를 주고 받을 수 있기 때문이다.
    • 요약하자면 팔로우 파티션으로 메시지가 들어가더라도 자동으로 리더 파티션으로 리다이렉트되어 메시지가 들어간다는 말이다.

 

리더 파티션에 장애가 발생하면 어떻게 될까?

리더 파티션 장애시 상태 (원래 리더는 3이었고 Isr 3,1,2 였다.)
장애 복구 후의 상태

  • 리더 파티션이 장애가 나면 팔로우 파티션 중 하나가 리더로 선출되어 기존 리더의 일을 하게 된다. (리더 파티션 장애시 상태 참고)
  • 이후 리더 파티션이 돌아오면 해당 리더 파티션은 팔로우 파티션이 되며 Isr에 동기화 된다 (장애 복구 후의 상태 참고)

 

Kafka 서버는 몇 대를 운용하는 게 좋을까?

  • kafka 서버를 많이 운용할 수록 중단될 확률이 줄어듦 → 좋긴하나 서버 비용이 많이 나옴
  • 또한 한 대를 운영한다고 해서 서버에 심각한 장애가 발생하는 것은 아님
  1. 초기 스타트업, 초기 단계 서비스, 개발/테스트 단계
    • 추천 kafka 서버 수 : 1대
    • 비용 절감이 중요하므로, 나중에 트래픽이 늘어난다면 그때 늘리는 것을 추천
  2. 서비스의 안정성이 중요한 중견 기업 또는 대기업
    • 추천 kafka 서버 수 : 최소 3대 이상
    • 서비스에 장애가 나는게 더 큰 손해가 발생하는 상태, 서버 비용이 크게 부담이 나지 않기에 서비스 장애가 최대한 발생하지 않도록 더 신경을 써야한다.

 

Spring Boot 서버에 여러 대의 kafka를 연결하는 방법

  • yaml 파일에 kafka의 브로커 주소를 모두 적어주면 된다.
    • producer와 consumer 모두 설정해주어야한다.
    • 모두 설정해야 중간에 장애가 나더라도 정상 작동하게 만들 수 있다.
spring:
  kafka:
    # Kafka 서버 주소 (EC2에 카프카를 설치했기 때문에 EC2 주소를 입력해야 한다.)
    bootstrap-servers:
      - {ip}:{port}
      - {ip}:{port}
      - {ip}:{port}

 

출처: https://inf.run/qzJua

저작자표시 (새창열림)

'개발 공부 > kafka' 카테고리의 다른 글

6. Kafka 파티션 이용해서 성능 향상 시키기 (+실습)  (0) 2025.12.01
5. Kafka 메시지 처리 실패 시 대처 방법 (feat. Spring) (DLT, 재시도) (+실습)  (0) 2025.11.24
4. Kafka의 Producer, Consumer 서버 만들기 (feat. Spring) (+실습)  (0) 2025.11.23
3-2. Kafka 토픽 네이밍 규칙  (0) 2025.11.21
3-1. Kafka의 핵심 요소와 작동 (Topic, Consumer, Producer, Consumer Group, OffSet, CURRENT OFFSET) (+ 실습)  (0) 2025.11.21
'개발 공부/kafka' 카테고리의 다른 글
  • 6. Kafka 파티션 이용해서 성능 향상 시키기 (+실습)
  • 5. Kafka 메시지 처리 실패 시 대처 방법 (feat. Spring) (DLT, 재시도) (+실습)
  • 4. Kafka의 Producer, Consumer 서버 만들기 (feat. Spring) (+실습)
  • 3-2. Kafka 토픽 네이밍 규칙
Jamey
Jamey
  • Jamey
    컴공 대학생의 이야기
    Jamey
  • 전체
    오늘
    어제
    • 분류 전체보기 (36)
      • 개발 공부 (33)
        • k8s (24)
        • kafka (8)
        • AI (1)
      • 개발기 (2)
      • 프로젝트 홍보 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • 깃허브
  • 공지사항

  • 인기 글

  • 태그

    K8S
    토픽
    serialDB
    current offset
    Jenkins
    cloudflare workers
    llm최적화
    Graphana
    Kubernetes
    카프카
    Producer
    langchain
    AI
    sql자동화
    Kafka
    topic
    Rag
    Linux
    조인 쿼리
    consumer
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
Jamey
Kafka 고가용성 확보하기 (node, broker, controller, cluster, replication) (+실습)
상단으로

티스토리툴바