Post

카프카 핵심 가이드 - 02 카프카 설치하기

카프카 설치시 설정 값이나, 고려해야하는 부분에 대해 알아보자.

카프카 핵심 가이드 - 02 카프카 설치하기

환경 설정

운영체제 선택하기

아파치 카프카는 다양안 운영체제에서 실행가능한 자바 애플리케이션으로, 다양한 운영체제에서 실행이 가능하지만 대체로 리눅스가 권장된다.

자바 설치하기

카프카와 주키퍼는 모든 OpenJDK 기반 자바 구현체 위에서 원활히 작동된다. 카프카 최신 버전은 java 8과 11을 모두 지원한다.

주피커 설치하기

카프카는 카프카 클러스터의 메타데이터와 컨슈머 클라이언트에 대한 정보를 저장하기 위해 주피커를 사용한다.

Build source

주키퍼
설정 정보 관리, 이름 부여, 분산 동기화, 그룹 서비스를 지공하는 중앙화된 서비스

카프카 브로커 설치하기

이 부분은 실제 설치 관련 글을 따로 작성 하려고 제외함

브로커 설정하기

카프카에는 거의 모든 구성을 제어하고 튜닝할 수 있는 옵션 설정이 있는데, 대부분 특별한 사례가 아니라면 바꿀 일이 없다.

핵심 브로커 매개변수

브로커의 기본적인 설정을 담당하며, 대부분은 다른 브로커와 함께 클러스터 모드로 작동하기 위해서는 값을 변경해야한다.

broker.id
모든 카프카 브로커는 정숫값의 식별자를 갖는다.
클러스터 내의 모든 브로커들은 broker.id를 다르게 가져야한다.
임의로 설정이 가능하다.필요하다면, 브로커 간에 이동도 가능하다.
필요하다면, 브로커 간에 이동도 가능하다?
브로커를 교체하거나 클러스터를 재구성할 때, 기존 브로커의 broker.id를 새로운 브로커에게 할당 가능하다.
listener
리스너는 {프로토콜}://{호스트이름}:{포트}의 형태를 가진다.
여러 개의 리스너를 쉼표,로 구분해 지정할 수 있다.

구버전은 단순한 port 설정을 사용했으나, 지원이 중단되었다.

zookeeper.connect
주키퍼의 위치를 가리킨다.
{호스트이름}:{포트}/{경로}의 형태를 가진다.
세미콜론;으로 구분해 지정할 수 있다.
log.dir / log.dirs
로그 위치를 가리킨다.
카프카는 모든 메시지를 로그 세그먼트 단위로 묶어서 log.dir 설정에 지정된 디스크 디렉토리에 저장한다.
다수의 디렉토리를 지정할 경우, log.dirs를 사용해 지정하면된다.
log.dirs가 지정되어 있지 않은 경우 log.dir를 사용한다.
log.dirs에 1개 이상의 경로가 지정된 경우, 브로커는 가장 적은 수의 파티션이 저장된 디렉토리에 새 파티션을 저장할 것이다.

브로커는 가장 적은 수의 파티션이 저장된 디렉토리에 새 파티션을 저장할 것이다? 만약 현재, 2개의 디렉토리에 파티션이 나눠져 저장되어있다고 가정해보자. A 디렉토리에 5개, B 디렉토리에 3개가 저장되어 있다면, 새로운 파티션을 저장할 때 더 적은 파티션을 가지고 있는 B 디렉토리에 저장될 수 있도록 설정한다. 이 때, 중요한 점은 디렉토리의 용량이 아닌 파티션의 개수로 비교한다는 것이다.

nums.recoery.threads.per.data.dir~~~~
카프카는 스레드 풀을 사용해서 로그 세그먼트를 관리한다.
하나의 로그 디렉토리에 대해 하나의 스레드만이 사용된다. 이 스레드들은 브로커가 시작될 때와 종료될 때만 사용되기 때문에 작업을 병렬화하기 위해서는 많은 스레드를 할당하는 것이 좋다.

스레드 풀이 하는 일

  • 브로커가 정상적으로 시작되었을 때, 각 파티션의 로그 세그먼트 파일을 연다.
  • 브로커가 장애 발생 후 재시작되었을 때, 각 파티션의 로그 세그먼트를 검사하고 잘못된 부분은 삭제한다.
  • 브로커가 종료할 때, 로그 세그먼트를 정상적으로 닫는다.
auto.create.topics.enable
브로커가 토픽을 자동으로 생성하는 몇몇 경우가 있는데, 이는 바람직하지 않은 경우가 많다. 토픽을 생성하지 않고, 토픽의 존재 여부를 확인할 방법이 없다.
이 때, 자동으로 생성할 수 있게 할지에 대한 값이다.

자동으로 토픽이 생성되는 경우

  • 프로듀서가 토픽에 메시지를 쓰기 시작할 때 = 없는 토픽에 쓰려고 함
  • 컨슈머가 토픽으로부터 메시지를 읽기 시작할 때 = 없는 토픽을 읽으려고 함
  • 클라이언트가 토픽에 대한 메타데이터를 요청할 때 = 없는 토픽의 메타데이터를 요청함

토픽을 생성하지 않고, 토픽의 존재 여부를 확인할 방법이 없다? 토픽의 존재 여부를 확인하는 방법

  • kafka-topics.sh --describe --topic my-topic 같은 명령어
  • Kafka AdminClient API (describeTopics()호출)가 있다.

설정에 따른 결과 auto.create.topics.enable=true시, 위의 방법으로 확인한다면 kafka가 토픽을 생성한다. auto.create.topics.enable=false시, 위의 방법으로 정확하게 확인할 수 있다.

auto.leader.rebalance.enable
토픽의 리더가 하나의 브로커에 집중되지 않도록 하는 설정이다.
설정을 켜면, 파티션의 분포 상태를 주기적으로 확인하는 백그라운드 스레드가 시작된다.
delete.topic.enable
클러스터의 토픽을 임의로 삭제하지 못하도록 하는 설정이다.

토픽별 기본값

num.partitions
새로운 토픽이 생성될 때, 몇 개의 파티션을 갖게되는지 결정한다.
자동 토픽 생성 기능이 활성화되어 있을때 사용된다.

파티션 수는 어떻게 결정해야하는가 브로커가 추가될 때, 클러스터 전체에 걸쳐 메시지 부하가 고르게 분산되도록 파티션 개수를 잡아 주는 게 중요하다. 토픽당 파티션 개수클러스터 내 브로커의 수와 맞추거나 배수로 설정하는 경우가 많은데, 이렇게 하면 브로커들 사이에 고르게 분산될 수 있어 메시지 부하 역시 고르게 분산되는 좋은 방법이다.

“토픽당 파티션 개수를 클러스터 내 브로커의 수와 맞추거나 배수로 설정하는 경우”가 좋은 이유? 1. 브로커와 파티션의 관계 각 파티션의 리더는 한 브로커에만 할당된다.

  • 파티션의 수 < 브로커의 수: 일부 브로커는 파티션을 할당 받지 못해 할 일이 없고, 나머지 브로커만 부하를 받게된다.
  • 파티션의 수 = 브로커의 수 (* n): 모든 브로커가 파티션의 할당받아 부하가 비교적 고르게 분산된다.

2. 브로커 추가 시 유연성 확보 브로커가 추가될 때 최소 비용으로 파티션을 재배치(Rebalance)해도 비교적 고르게 분산된다. 만약 배수가 아니라면, 비교적 고르게 분산되도록 하기 위한 재배치에는 많은 비용이 들 수 있다.
이 때 유의해야할 점은, 목표가 완벽한 균등이 아닌 특정 브로커에만 과부하가 몰리진 않게하는 것이라는 점과 리더 파티션을 기준으로 계산한다는 점이다.

파티션 수를 결정할 떄 고려해야할 요소

  • 토픽에 대해 달성하고자 하는 처리량은 어느정도인가?
    100kb vs 1gb
  • 단일 파티션에 대해 달성하고자 하는 최대 읽기 처리량은 어느정도인가?
    컨슈머의 애플리케이션이 데이터를 DB에 쓰는 속도가 스레드 각각이 초당 50mb 이상을 처리할 수 없다면, 하나의 파티션에서 읽어올 수 있는 속도는 초당 50mb로 제한된다.
  • 만약 키 값을 기준으로 선택된 파티션에서 메시지를 전송하고 있을 경우, 현재의 사용량이 아닌 미래의 사용량 예측값을 기준으로 처리량을 계산하라.
  • 각 브로커에 배치할 파티션 수, 브로커별 사용 가능한 디스크 공간, 네트워크 대역폭 역시 고려하라.
  • 데이터를 미러링할 예정인가? 미러링 구성에서 큰 파티션이 병목이 되는 경우가 많다.
  • 클라우드 서비스를 사용하고 있다면, 가상 머신이나 디스크에 초당 입출력(IOPS)제한이 걸려있는가?
    파티션 수가 너무 많으면, 병렬 처리로 인해 IOPS 양이 증가할 수 있다.

경험상 매일 디스크안에 저장되어 있는 파티션의 용량을 6GB미만으로 유지하는 것이 대체로 결과가 좋았다.

default.replication.factor
새로운 토픽이 생성될 때, 생성되는 토픽의 복제 팩터를 결정한다.
자동 토픽 생성 기능이 활성화되어 있을때 사용된다.
복제 팩터 값은 min.insync.replicas 설정값보다 최소한 1 이상 크게 잡아줄 것을 강력히 권장한다.
log.retention.ms
로그 세그먼트의 시간 기준 보존 주기 설정이다.
같은 의미에 단위만 다른 log.retention.hours, log.retention.minutes 도 설정할 수 있지만, 1개 이상 설정시 가장 작은 단위의 설정값이 우선권을 갖는다.
모든 보존 기준은 파티션 단위로 적용된다.

시간 기준 보존과 마지막 수정 시각 시간 기준 보존은 디스크에 저장된 각 로그 세크먼트 파일의 마지막 수정 시간(mtime)을 기준으로 작동한다. 하지만 관리 툴을 이용해 브로커 간에 파티션을 이동시켰을 경우, 이 값은 정확하지 않으며 해당 파티션이 지나치케 오래 보존되는 결과를 초래할 수 있다.

log.retention.bytes
로그 세그먼트의 용량 기준 보존 주기 설정이다.
모든 보존 기준은 파티션 단위로 적용되기 때문에, 1GB로 설정했고 토픽에 8개의 파티션이 있다면 토픽의 최대 용량은 8GB가 되는 것이다.
-1로 설정시, 데이터가 영구히 설정된다.

크기와 시간을 기준으로 보존 설정하기 만약 시간 기준과 크기 기준 둘 다 설정했다면, AND 가 아닌 OR 과 같이 둘 중 하나의 조건만 성립되어도 삭제될 수 있다.

log.segment.bytes
로그 세그먼트의 용량 기준 닫힘 주기 설정이다.
로그 세그먼트는 닫히기 전까지는 만료와 삭제의 대상이 되지 않는다.
토픽에 메시지가 뜸하게 주어지는 상황이라면, 로그 세그먼트가 의도한 것보다 오래 저장될 수 있다. ex) 하루 들어오는 양 100MB 이라면 닫히는데 10일이 소요 + 보존 주기 10일 = 최대 20일 보존
log.roll.ms
로그 세그먼트의 시간 기준 닫힘 주기 설정이다.
로그 세그먼트는 닫히기 전까지는 만료와 삭제의 대상이 되지 않는다.
같은 의미에 단위만 다른 log.roll.hours, log.roll.minutes 도 설정할 수 있지만, 1개 이상 설정시 가장 작은 단위의 설정값이 우선권을 갖는다.

로그 세그먼트의 시간 기준 닫힘 주기 설정 사용시 디스크 성능 다수의 로그 세그먼트가 동시에 닫힐 때 디스크 성능에 대한 영향을 고려할 필요가 있다. 시간 제한은 브로커가 시작되는 시점부터 계산되기 때문에 크기가 작은 파티션을 닫는 작업 역시 한꺼번에 이루어지기 때문이다.

min.insync.replicas
브로커가 최소 몇 개의 복제본(Replica)이 최신 상태로 동기화되어 있어야 데이터를 성공으로 간주할지를 결정한다.
프로듀서의 acks 설정과 함께 동작한다.

acks 설정 프로듀서가 kafka에게 메시지를 보낼 때, kafka가 언제 메시지를 성공으로 간주할지를 결정하는 설정이다. 자세히

  • acks=0: 프로듀서는 브로커의 응답을 기다리지 않고 성공으로 간주한다. 기다리지 않는만큼 빠르지만 데이터가 유실될 위험이 있다.
  • acks=1: 리더 브로커만 메시지를 저장하면 성공으로 처리한다.
  • acks=all: 리더와 동기화된 레플리카 전체가 데이터를 저장했을 때 성공으로 처리한다.

min.insync.replicasacks

  • min.insync.replicas: 브로커가 성공 응답을 주기 위한 최소 레플리카 수를 정의
  • acks: 프로듀서가 성공을 언제 인정할지 결정

=> acks=all설정 없이 min.insync.replicas는 의미 없음

message.max.bytes
쓸 수 있는 메시지의 최대 크기를 제한하는 설정한다.
압축된 메시지의 크기를 기준으로 한다.

잘못 설정하면 컨슈머가 멈출 수 있다? 1개의 메시지 최대 크기인 message.max.bytes는 1MB라고 설정되어있고, 컨슈머가 한번에 읽을 수 있는 최대 메시지 크기인 fetch.message.max.bytes는 512KB 라면 브로커는 1MB짜리의 메시지를 반환하려하지만, 컨슈머는 수용할 수 없는 크기라 무시 -> 컨슈머는 다음 오프셋으로 넘어가지 않고 계속 같은 오프셋을 시도하며 무한 대기 상태에 빠짐 그렇기 때문에 message.max.bytesfetch.message.max.bytes와 맞추어 설정되어야한다.

하드웨어 선택하기

카프카는 특정 하드웨어를 요구하지 않지만, 성능을 고려한다면 디스크와 메모리,네트워크, CPU를 감안해야한다. 사용하고자 하는 환경에 가장 중요한 성능 유형이 무엇인지 결정하고, 예산 내에 하드웨어 설정을 선택하면 된다.

디스크 처리량
프로듀서 클라이언트 성능에 가장 큰 영향을 미친다. 프로듀서 클라이언트는 메시지 전송이 성공했다고 결론 내리기 전에 최소한 1개 이상의 브로커가 메시지를 커밋되었다고 응답을 보낼때까지 대기해야한다. 디스크의 속도가 빠르다면 이 대기 시간이 짧아지게 된다.
대체로 많은 수의 클라이언트 연결을 받아내야하는 경우에는 SSD, 자주 쓸 일이 없는 데이터를 굉장히 많이 저장해야한다면 HDD가 낫다.
디스크 용량
특정한 시점에 얼마나 많은 메시지들이 보존되어야하는지에 따라 결정된다.
카프카 클러스터의 크기를 변경하거나 확장 시점을 결정할 때 고려해야 할 요소 중 하나다.
메모리
컨슈머의 성능을 향상하기 위해, 최근 추가된 메시지를 캐싱처리한다. 컨슈머는 보통 프로듀서가 방금 추가한 메시지를 조회하는데, 이를 캐싱처리하면 캐시에 저장된 내용을 읽어오며 디스크에 저장된 내용을 조회하는 것보다 더 빠르게 읽어 올 수 있다.
다른 애플리케이션과 함께 운영하는 것을 권장하지 않는다. 카프카는 많은 메모리를 사용하지 않지만, 위와같은 캐싱 처리를 하는데 많은 메모리를 쓴다.
네트워크
디스크 용량과 함께 클러스터의 크기를 결정하는 가장 결정적인 요인이다.
카프카 특성상 인입되는 네트워크 사용량과 유출되는 네트워크 사용량 사이에 불균형으로 인해 요구 조건을 증대시킨다.
네트워크 문제가 생기는 것을 방지하기 위해서는 최소 10GB 이상을 처리할 수 있는 네트워크 인터페이스 카드를 사용할 것을 권장한다.
CPU
클러스터의 크기가 매우 크지 않는 한, 처리능력은 많이 중요하지 않다. 처리 능력이 가장 중요한 시점은, 카프카가 각 메시지를 받아 압축해제 후 오프셋 부여를 위해 체크섬을 확인하고 끝난 뒤 저장을 위해 메시지를 다시 압축해야하는 시점이다.

카프카 클러스터 설정하기

Build source

위의 사진처럼 하나의 클러스터를 여러 개의 브로커로 설정하면 여러가지 이점이 있다.

  • 부하를 다수의 서버로 분산할 수 있다.
  • 단일 시스템 장애 발생시 데이터 유실을 방지할 수 있다.
  • 클라이언트 요청을 처리하는 중에(=카프카의 서비스를 중단하지 않고), 유지보수 작업이 가능하다.

브로커 개수

카프카 클러스터의 적절한 크기를 결정하는 요소

  • 디스크 용량
  • 브로커당 레플리카 용량
  • CPU 용량
  • 네트워크 용량
디스크 용량
필요한 메시지를 저장할 용량, 단일 브로커가 사용할 수 있는 저장소 용량을 고려해야한다.
클러스터가 처리 가능한 요청의 양
파티션 레플리카 개수를 브로커당 14,000개, 클러스터당 100만개 이하로 유지할 것을 권장한다.
CPU 용량
대부분 주요한 병목 지점이 되지 않지만, 하나의 브로커에 감당할 수 없는 수준의 연결이나 요청이 쏟아지는 경우에는 병목 지점이 될 수 있다.
네트워크 용량
네트워크 인터페이스의 전체 용량이 얼마인지?
컨슈머가 여럿이거나, 데이터가 보존되는 동안 트래픽이 일정하지 않을 경우에도 클라이언트 트래픽을 받아낼 수 있는지?

브로커 설정

여러개의 브로커가 하나의 클러스터를 이루기 위해서는 2가지를 설정해야한다.

zookeper.connect
모든 브로커들이 하나의 값을 가져야한다.
클러스터가 메타데이터를 저장하는 주키퍼 앙상블과 경로를 지정한다.
broker.id
브로커를 구분하는 id 값이다.
모든 브로커들이 유일한 값을 가져야한다. 자세히

운영체제 튜닝하기

커널 튜닝 매개변수가 미리 잡혀 있지만, 몇 가지를 변경함으로써 카프카 브로커의 성능을 끌어올릴 수 있다.

가상 메모리

목표
스와핑을 막자
이유
스와핑되는 과정에서 발생되는 비용이 높아 카프카의 성능에 영향을 미친다.
카프카는 시스템 페이지 캐시를 매우 많이 사용하기 때문에, 가상 메모리 시스템이 디스크로 페이지를 스와핑할 경우 페이지 캐시에 할당할 메모리가 부족해진다.

방법

  • 스왑 공간 자체를 할당하지 않는다.
    vm.swappiness 값을 매우 작은 값으로 잡아, 스왑 메모리보다 페이지 캐시에 많은 메모리를 할당한다.
  • 커널이 더티 페이지를 다루는 방식을 조정해 유지 가능한 더티 페이지 양을 줄인다.
    vm.dirty_background_ratio 값을 10보다 작게 설정한다.
  • 유지할 수 있는 더티 페이지의 수를 증가시킨다.
    vm.dirty_ratio값을 60~80사이의 값으로 올려 설정한다.
    이 설정은 밀린 디스크 쓰기 작업이 늘어나거나, 동기적으로 더티 페이지를 내보내야할 경우 I/O 멈춤이 길어질 수 있는 위험을 발생시킨다.
    카프카 클러스터의 복제 기능을 활성화해 시스템 장애에 대한 안전장치를 해 놓을 것을 강력히 권장한다.
  • 파일 디스크립터의 수를 증가시킨다.
    로그 세그먼트를 저장하고 연결을 열기 위해 파일 디스크립터를 사용하기 때문에, 파티션이 많다면 증가시켜야한다.
    최소한 필요한 디스크립터의 수를 계산하는 방법은 [파티션 수] * ([파티션 수]/[세그먼트 크기]) + [브로커에 생성된 네트워크 연결 수]`로 계산한다.
    vm.max_map_count값을 위 계산에 근거해 400,000이나 600,000정도로 잡아주면 적절하다.
  • 운영체제가 지나치게 많은 메모리를 차지하지 않도록 설정한다.
    vm.overcommit_memory값을 0으로 잡아준다.

vm.dirty_background_ratio값은 0으로 설정하면 안된다. 더티 페이지를 버퍼링하지 않고 계속 디스크로 내보내려 하기 때문에, 저장 장치 성능이 일시적으로 튀어오르는 사태가 발생하기 떄문이다.

더티 페이지란?

  • 가상 메모리 시스템에서 페이지 상태의 기본적인 흐름
    1. 프로세스가 메모리에서 데이터를 로드한 후, 수정하지 않은 경우 클린 페이지(Clean Page) 상태이다.
    2. 프로세스가 해당 페이지를 수정하면, 더티 페이지(Dirty Page)로 변경된다.
    3. 운영체제(OS)는 일정 시점이 되면 이 페이지를 디스크에 기록(Flush)하여 동기화한다.
  • 더티라고 불리는 이유?
    OS 입장에서 해당 페이지가 디스크에 저장된 기존 데이터와 다르다는 의미로, RAM에 있는 데이터와 디스크에 저장된 데이터가 불일치한 상태를 의미한다.
  • 페이지 교체 시 더티 페이지
    교체 대상이 더티 페이지라면, 디스크에 저장 후 교체해야 한다. (추가적인 I/O 발생)
  • 더티 페이지의 양을 줄이려고 하는 이유는?
    더티 페이지가 많다. = 더티 페이지를 디스크에 기록(Flush)하여 동기화하는 과정에서 디스크의 I/O 부하가 증가시킨다.
    Kafka도 주기적으로 데이터를 파일에 저장(Log Segment Flush)해야 하는데, 더티 페이지가 많다면 디스크 I/O 부하로 인해 kafka의 쓰기 성능이 저하된다.

디스크

성능에 영향을 주는 중요도: 저장장치 하드웨어 > (RAID) > 디스크 파일 시스템

파일 시스템에서

  • Ext4와 XFS 두개를 많이 사용하는데, XFS를 사용하는 것이 비교적 안전하다.
  • 마운트 옵션에 noatime 옵션을 지정한다.
  • 크기가 큰 디스크 쓰기 작업시에는, largeio 옵션을 사용한다.

noatime옵션과 파일 메타데이터 파일 메타데이터는 3개의 타임스템프를 포함한다.

  • 생성 시각(ctime)
  • 마지막 수정 시각(mtime)
  • 마지막 사용 시각(atime)

마지막 사용 시각은 읽힐 때 마다 디스크 쓰기 작업을 발생시는데, noatime옵션을 사용하면 이러한 타임스탬프 값이 업데이트 되는 것을 막는다.

네트워킹

목표
리눅스의 커널 시스템은 대량의 데이터를 빠르게 주고받는데 최적화되어있지 않는데, 최적화 하자.

방법

  • 각 소켓의 송신, 수신 버퍼의 메모리의 양을 증가시킨다.
    net.core.wmem_defaultnet.core.rmem_default를 128KB로 설정한다.
    net.core.wmem_maxnet.core.rmem_max를 2MB로 설정한다.
    큰 전송을 주고 받을 때 성능을 향상 시킨다.
  • TCP 소켓의 송신, 수신 버퍼 크기 증가시킨다.
    net.ipv4.tcp_wmemnet.ipv4.tcp_rmem를 카프카 브로커의 실제 작업 부하에 근거해 최대값을 증가시킨다.
    이때, 최대값은 net.core.wmem_maxnet.core.rmem_max보다 클 수 없다.
  • TCP 윈도우 스케일링 기능을 활성화한다.
    net.ipv4.tcp_window_scaling값을 조절해 활성화 한다.
    클라이언트가 데이터를 더 효율적으로 전달할 수 있도록 할 수 있다.
  • 브로커가 동시에 받을 수 있ㄴ는 연결의 수를 증가시킨다.
    net.ipv4.tcp_max_syn_backlog값을 기본값보다 크게 잡아준다.
  • 트래픽 급증에 대비해 커널이 처리할 패킷을 증가시킨다.
    net.core.netdev_max_backlog값을 기본값보다 크게 잡아준다.

프로덕션 환경에서의 고려사항

신뢰성있는 시스템을 구축하기 위해 몇가지 점을 더 생각해보자.

가비지 수집기 옵션

기본 가비지 수집기로 G1GC 를 사용할 것이 권장된다.

G1GC의 성능 조절 아래의 설정 값들을 낮게 잡아 줘도 괜찮다.

  • MaxGCPauseMillis
    이 값은 가비지 수집기가 호출되는 주기를 최대한 지정한 시간(ms)으로 맞추고, 단위 사이클에 걸리는 시간 역시 지정한 시간(ms)정도로 맞추겠다는 의미다.
  • InitiatingHeapOccupancyPercent
    이 값은 힙(Heap)이 지정한 퍼센트 이하로 사용될 때에는 가비지 수집 사이클을 시작하지 않겠다는 의미다.

데이터센터 레이아웃

카프카 브로커 배치가 중요한 이유
카프카 브로커(데이터 저장소)가 같은 위치(랙, 서버, 네트워크)에 몰려 있으면 한 번의 장애로 전체 시스템이 영향을 받을 수 있다.
안정적인 운영을 위해 물리적인 위치를 분산할 필요가 있다.
broker.rack 설정
카프카의 복제로 데이터를 다른 브로커에 저장할 수 있지만, 브로커들이 같은 랙에 배치되면 같은 네트워크 장애를 공유할 위험이 있다.
broker.rack설정을 통해 카프카가 파티션 복제를 다른 랙에 자동으로 분산할 수 있다.
한 랙이 죽어도 다른 랙에 복제된 데이터가 남아있기 때문에 장애를 최소화할 수 있고, 클라우드 환경에서도 특정 장애 도메인(Failure Zone)을 고려하여 데이터를 분산 가능하다.

주키퍼 공유하기

주키퍼
브로커, 토픽, 파티션에 대한 메타데이터를 저장하기 위해 사용한다.
컨슈머나 클러스터 자체에 변동이 있을 때만 주키퍼의 쓰기가 이루어진다.
다른 애플리케이션과 주키퍼 앙상블을 공유하는 것은 피하는 것이 좋다. 타임아웃과 지연에 민감한 시스템이고, 앙상블과의 통신이 중단된다면 브로커가 예상하지 못한 방식으로 동작할 수 있기 때문이다.
주키퍼와 주키퍼 앙상블
주키퍼(Zookeeper)
분산 시스템을 위한 중앙 조정 서비스로, 브로커 상태 관리, 컨슈머 오프셋 저장, 리더 선출 등의 기능을 담당한다.
주키퍼 앙상블(ZooKeeper Ensemble)
여러 개의 주키퍼 서버가 클러스터를 이루는 형태이다.
주키퍼 단일 노드로 운영하면 장애 발생 시 카프카 전체가 다운될 위험이 있고, 카프카는 분산 시스템이므로 주키퍼도 고가용성(HA) 환경으로 운영하는 것이 필수이다.>
This post is licensed under CC BY 4.0 by the author.