Kafka 브로커
카프카 클라이언트와 데이터를 주고받기 위해 사용하는 주체인 애플리케이션이다.
브로커는 프로세스 단위이고 각각 별도의 서버에서 카프카 브로커 프로세스가 실행된다.
카프카 클러스터로 묶인 브로커들은 프로듀서가 보낸 데이터를 안전하게 분장 저장하고 복제하는 역할을 수행한다.
브로커의 역할
- 컨트롤러 역할
- 클러스터의 다수 브로커 중 한 대가 컨트롤러의 역할을 한다.
- 컨트롤러는 다른 브로커들의 상태를 체크하고 브로커가 클러스터에서 빠지는 경우 해당 브로커에 존재하는 리더 파티션을 재분배한다.
- 만약 컨트롤러 역할을 하는 브로커에 장애가 생기면 다른 브로커가 컨트롤러 역할을 한다.
- 데이터 삭제 역할
- 카프카는 컨슈머가 데이터를 가져가더라고 토픽의 데이터는 삭제되지 않는다.
- 또한, 컨슈머나 프로듀서가 데이터 삭제를 요청할 수도 없다. 오직 브로커만이 데이터를 삭제할 수 있다.
- 데이터 삭제는 파일 단위로 이루어지는데 이 단위를 ‘로그 세그먼트’라고 부른다. (세그먼트에는 다수의 데이터가 존재하기 때문에 데이터베이스처럼 특정 데이터를 선별해서 삭제할 수 없다.
- 컨슈머 오프셋 저장 역할
- 컨슈머 그룹은 토픽이 특정 파티션으로부터 데이터를 가져가서 처리하고 이 파티션의 어느 레코드까지 가져갔는지 확인하기 위해 오프셋을 커밋한다. (커밋 : 컨슈머가 처리한 오프셋을 알리는것 )
- 커밋한 오프셋은 __consumer_offsets 토픽에 저장한다. 여기에 저장된 오프셋을 토대로 컨슈머 그룹은 다음 레코드를 가져가서 처리한다. ( internal topic )
- 코디네이터 역할
- 컨슈머 그룹의 상태를 체크하고 파티션을 컨슈머와 매칭되도록 분배하는 역할을 한다.
- 컨슈머가 컨슈머 그룹에서 빠지면 매칭되지 않은 파티션을 정상 동작하는 컨슈머로 할당하여 끊임없이 데이터가 처리되도록 도와준다. 이렇게 파티션을 컨슈머로 재할당하는 과정을 ‘리밸런싱’ 이라고 부른다.
- 데이터 저장 역할
- 저장위치
- config/server.properties 의 log.dir 옵션에 정의한 디렉토리에 데이터를 저장한다.
- 토픽이름과 파티션 번호의 조합으로 하위 디렉토리를 생성하여 데이터를 저장한다.
- hello.kafka
$ ls /tmp/kafka-logs __consumer-offsets-0 __consumer-offsets-1 … $ ls /tmp/kafka-logs/hello.kafka-0 (topic + partition number) 00000000000000000000.index 00000000000000000000.log 00000000000000000000.timeindex leader-epoch-checkpoint
- hello.kafka 토픽의 0번 파티션에 존재하는 데이터를 확인할 수 있다.
- log 에는 메세지와 메타데이터를 저장한다.
- index 는 메세지의 오프셋을 인덱싱한 정보를 담은 파일이다.
- timeindex 파일에는 메세지에 포함된 timestamp 값을 기준으로 인덱싱한 정보가 담겨있다.
- 로그와 세그먼트
$ ls /tmp/kafka-logs/hello.kafka-0 00000000000000000000.log 00000000000000000010.log 00000000000000000020.log(active)
- 각 세그먼트 파일의 이름은 시작 오프셋으로 만들어진다.
- 쓰기가 일어나고 있는(가장 최근) 세그먼트를 active 세그먼트라고 한다.
- 카프카의 보관 주기(retention) 설정에 따라 세그먼트 파일이 삭제될때 active 세그먼트는 제외된다. (00000000000000000020.log)
- 세그먼트 설정
- log.segment.bytes : 바이트 단위의 최대 세그먼트 크기 지정. 기본 값은 1GB.
- log.roll.ms(hours) : 세그먼트가 신규 생성된 이후 다음 파일로 넘어가는 시간 주기. 기본 값은 7일.
- 세그먼트와 삭제주기 (cleanup.policy=delete)
- retention.ms(hours) : 세그먼트를 보유할 최대 기간. 기본 값은 7일 (일반적으로 3일로 많이 지정한다)
- retention.bytes : 파티션당 로그 적재 바이트 값. 기본 값은 -1 (지정하지 않음)
- log.retention.check.interval.ms : 세그먼트가 삭제 영역에 들어왔는지 확인하는 간격. 기본값은 5분
- 세그먼트의 삭제 (cleanup.policy=delete)
- 카프카에서 데이터는 세그먼트 단위로 삭제가 발생하기 때문에 로그단위(레코드 단위)로 개별 삭제는 불가능하다.
- 또한, 로그(레코드)의 메세지 키, 메세지 값, 오프셋, 헤더 등 이미 적재된 데이터에 대해서 수정 또한 불가능하기 때문에 데이터를 적재할 때(프로듀서) 또는 데이터를 사용할 때(컨슈머) 데이터를 검증하는 것이 좋다.
- 세그먼트의 압축 (cleanip.policy=compact)
- 토픽 압축 정책은 일반적으로 생각하는 zip 과 같은 압축(compression) 과는 다른 개념이다. 여기서 압축이란 메세지 키 별로 해당 메세지 키의 레코드 중 오래된 데이터를 삭제하는 정책을 뜻한다.
- 그렇기 때문에 삭제(delete) 정책과 다르게 일부 레코드만 삭제가 될 수 있다.
- 압축은 액티브 세그먼트를 제외한 데이터가 대상이다.
- 테일/헤드 영역, 클린/더티 로그
- 테일 영역 : 압축 정책에 의해 압축이 완료된 레코드들. 클린(clean) 로그 라고도 부른다. 중복 메세지 키가 없다.
- 헤드 영역 : 압축 정책이 되기 전 레코드들. 더티(dirty)로그 라고도 부른다. 중복된 메세지 키가 있다.
- 데이터의 압축 시작 지점 설정 (min.cleanable.dirty.ratio)
- 데이터의 압축 시작 지점은 min.cleanable.dirty.ratio 옵션값을 따른다.
- cleanable.dirty.ratio 옵션 값은 액티브 세그먼트를 제외한 세그먼트에 남아 있는 테일 영역의 레코드 갯수가 헤드 영역의 레코드 갯수의 비율을 뜻한다.
- 예를 들어 0.5로 설정한다면 테일 영역의 레코드 갯수가 헤드 영역의 레코드 갯수와 동일할 경우 압축이 실행된다. 0.9와 같이 크게 설정하면 한번 압축을 할 때 많은 데이터가 줄어들므로 압축 효과가 좋다. 그러나 0.9 비율이 될 때 까지 용량을 차지하므로 용량 효율이 좋지 않다. 반면 0.1과 같이 작게 설정하면 압축이 자주 일어나서 가장 최신 데이터만 유지할 수 있지만 압축이 자주 발생하기 때문에 브로커에 부담을 줄 수 있다.
- 복제
- 개요
- 데이터의 복제(replication)는 카프카를 장애 허용 시스템(fault tolerant system)으로 동작하도록 하는 원동력이다.
- 복제의 이유는 클러스터로 묶인 브로커 중 일부에 장애가 발생하더라도 데이터를 유실하지 않고 안전하게 사용하기 위함이다.
- 카프카의 데이터 복제는 파티션 단위로 이루어진다. 토픽을 생성할 때 파티션의 복제 갯수(replication factor)도 같이 설정되는 데 직접 옵션을 설정하지 않으면 브로커에 설정된 옵션 값을 따라간다.
- 복제 갯수의 최솟값은 1(없음)이고 최댓값은 브로커 갯수만큼 설정하여 사용할 수 있다.
- 파티션
- 복제는 파티션 단위로 이루어진다.
- 파티션은 리더와 팔로워로 구성된다. 프로듀서 또는 컨슈머와 직접 통신하는 파티션을 리더, 나머지 복제 데이터를 가지고 있는 파티션을 팔로워라고 한다.
- 팔로워 파티션은 리더 파티션의 오프셋을 확인하여 현재 자신이 가지고 있는 오프셋과 차이가 나는 경우 리더 파티션으로부터 데이터를 가져와서 자신의 파티션에 저장하는데, 이 과정을 ‘복제’라고 부른다.
- 트레이드 오프
- 파티션 복제로 인해 나머지 브로커에도 파티션의 데이터가 복제되므로 복제 갯수 만큼 저장 용량이 증가한다는 단점이 있다. 그러나 복제를 통해 데이터를 안전하게 사용할 수 있다는 강력한 장점때문에 카프카를 운영할 때 2 이상의 복제 갯수를 정하는 것이 중요하다.
- 서버는 디스크 오류, 네트워크 연결 장애등의 이유로 언제든 장애가 발생할 수 있다.
- 장애가 발생한 경우
- 브로커가 다운되면 해당 브로커에 있는 리더 파티션은 사용할 수 없기 때문에 팔로워 파티션중 하나가 리더 파티션 지위를 넘겨 받는다. 이를 통해 데이터가 유실되지 않고 컨슈머나 프로듀서와 데이터를 주고 받도록 동작할 수 있다.
- 운영 시에는 데이터의 종류마다 다른 복제 갯수를 설정하고 상황에 따라서는 토픽마다 복제 갯수를 다르게 설정하여 운영하기도 한다. 데이터가 일부 유실되어도 무관하고 데이터 처리 속도가 중요하다면 1 또는 2로 설정한다.
- 금융 정보과 같이 유실이 일어나면 안되는 데이터의 경우 복제 갯수를 3으로 설정하기도 한다.
- metric 과 같은 성격의 데이터는 1로 설정하기도 한다.
- ISR (In-Sync-Replicas)
- ISR은 리더 파티션과 팔로워 파티션이 모두 싱크가 된 상태를 뜻한다.
- ISR인 상태가 아닌 시점에 싱크가 되지 않은 팔로워 파티션이 리더 파티션으로 선출되면 데이터가 유실될 수 있다. 유실이 발생하더라도 서비스를 중단하지 않고 지속적으로 토픽을 사용하고 싶다면 ISR이 아닌 팔로워 파티션을 리더로 선출하도록 설정할 수 있다.
- unclean.leader.electron.enable true : 유실을 감수함. 복제가 안된 팔로워 파티션을 리더로 승급. false : 유실을 감수하지 않음. 해당 브로커가 복구될 때 까지 중단.
- 개요
- 저장위치
Comments