본문 바로가기

Kafka

Apache Kafka 옵션

728x90

파티션 개수

  • 토픽을 운영함에 있어 적절한 파티션 개수를 설정하는것은 성능과 관련이 있기에 중요하다.
  • 토픽 생성시 파티션의 개수를 고려할 3가지 ( 데이터 처리량 , 메시지 키 사용 여부 , 브로커 영향도 ) 가 있다.

데이터 처리량

  • 전체 컨슈머 데이터 처리량이 프로듀서가 보내는 데이터보다 적다면 컨슈머 랙이 생기고 데이터 처리 지연이 발생한다.
    때문에 컨슈머 전체 데이터 처리량이 프로듀서 데이터 처리량 보다 많아야 한다.
    프로듀서 전송 데이터량 < ( 컨슈머 데이터 처리량 * 파티션 개수 )

메시지 키 사용 여부

  • 메시지의 키를 사용하면 키에 따른 컨슈머에서의 메시지 처리순서가 보장된다.
    그러나 운영중 파티션의 개수가 달라지면 이미 매칭된 파티선과 메시지 키의 매칭이 깨지고 전혀 다른 파티션에 다시 할당되기에 메시지 키별로 처리 순서를 보장하기 위해서는 파티션 개수를 프로듀서가 전송하는 데이터양보다 넉넉하게 잡고 생성하는 것이 좋다.

브로커 영향도

  • 파티션은 각 브로커의 파일 시스템을 사용한다.
  • 파티션이 늘어나는 만큼 브로커에서 접근하는 파일 개수가 많아지는데, 운영체제는 프로세스당 열 수 있는 파일 최대 개수를 제한하고 있다.
  • 브로커가 관리하는 파티션 개수가 너무 많다면 파티션 개수를 분산하기 위해 브로커 개수를 늘리는 방안도 같이 고려해야한다.

토픽 정리 정책 ( cleanup.policy )

  • 토픽의 데이터를 삭제하지 않으면 과거의 데이터를 다시 가져올 수 있다. 그러나 오랫동안 삭제하지 않으면 저장소 사용량이 지속적으로 늘어나게된다.
  • 데이터를 더이상 사용하지 않을 경우에는 cleanup.policy 옵션을 사용하여 데이터를 삭제할 수 있다.
    2가지 삭제 정책( delete policy , compact policy )이 있다.

delete policy

  • 일반적으로 대부분의 토픽의 cleanup.policy 를 delete 로 설정한다.
  • 명시적으로 토픽의 데이터를 삭제하는 것을 뜻한다.
  • 삭제시 세그먼트 단위로 삭제를 진행하는데, 세그먼트는 파티션마다 별개로 생성되며 세그먼트의 파일 이름은 기록하고있는 오프셋 중 가장 작은 값이 된다.
  • segment.bytes 옵션으로 1개의 세그먼트 크기를 설정할 수 있다. segment.bytes 크기보다 커질 경우에는 기존에 적재하던 세그먼트 파일을 닫고 새로운 세그먼트를 열어서 데이터를 저장한다. 사용중인 세그먼트를 액티브 세그먼트라고 한다.
  • 삭제가 실행되는 시점은 시간 또는 용량이 기준이 된다.
    retention.ms (토픽의 데이터를 유지하는 시간) :
    카프카는 일정 주기마다 세그먼트 파일의 마지막 수정 시간과 retention.ms 를 비교해 넘어가는 세그먼트는 삭제한다.
    retention.bytes (토픽의 최대 데이터 크기) :
    최대 크기를 넘어간 세그먼트 파일들은 삭제된다.
  • 삭제된 데이터는 복구 할 수 없다.

compact policy

  • 여기서 compact (압축) 이란 키별로 해당 메시지 키의 레코드 중 오래된 데이터를 삭제하는 정책이다.
  • 메시지 키를 기반으로 데이터를 처리할 경우 유용하다.
  • compact policy 는 액티브 세그먼트 를 제외한 나머지 세그먼트들에 한해서만 데이터를 처리한다.
  • 데이터의 압축 시작 시점은 min.cleanable.dirty.ratio 옵션 값을 따른다.

min.cleanable.dirty.ratio

  • min.cleanable.dirty ratio 를 0.1 과 같이 작게 설정하면 압축이 더 자주 일어나고 그만큼 브로커에 부담을 줄 수 있다. 반면에 0.9 와 같이 크게 설정하면 한번 압축을 할 때 많은 데이터가 줄어들므로 압축효과가 좋지만, 0.9 비율이 될 때까지 용량을 차지하므로 용량 효율이 좋지 않다. 그러므로 토픽별로 데이터 특성에 맞는 적절한 min.cleanable.dirty.ratio 값을 설정하는 것이 좋다.

kafka 로그 설정

카프카 빠르게


ISR ( In-Sync-Replicas )

  • ISR 은 리더 파티션과 팔로워 파티션이 모두 싱크(동기화)가 된 상태를 말한다.
  • ISR 이라는 용어가 나온 이유는 팔로워 파티션이 리더 파티션으로부터 데이터를 복제하는 데에 시간이 걸리기 때문이다.
  • 리더 파티션과 팔로워 파티션간에 오프셋 동기화 차이를 모니터링 하기 위해 리더 파티션은 replica.lag.time.max.ms 값만큼의 주기를 가지고 팔로워 파티션이 데이터를 복제하는지 확인한다. replica.lag.time.max.ms 값보다 더 긴 시간 동안 데이터를 가져가지 않는다면 해당 팔로워 파티션에 문제가 생긴 것으로 판단하고 ISR 그룹에서 제외한다.
  • 만약 리더 파티션에 문제가 생긴다면 ISR 그룹에 묶인 팔로워 파티션에서 리더를 선출한다.
  • 만약 리더 파티션의 데이터를 복제한 팔로워 파티션이 아직 없을때 리더 파티션이 장애가 난다면, 카프카는 리더 파티션이 존재하는 브로커가 다시 시작되기까지 기다리고 서비스는 중단된다. 때문에 unclean.leader.election.enable=true 로 설정한다면 ISR 이 아닌 팔로워 파티션, 즉 동기화가 되지 않은 팔로워 파티션도 리더가 될 수 있고, 데이터가 유실되더라도 서비스를 중단하지않고 지속적으로 토픽을 사용할 수 있게된다.
  • unclean.leader.election.enable 를 true 로 할지 false 로 할지는 서비스 운영 정책에 따라 달라진다.

카프카 프로듀서

  • 프로듀서는 카프카의 데이터를 저장하는 첫 단계이다. 카프카 클러스터는 3대 이상의 브로커로 이루어져야 브로커에 이슈가 생기더라도 데이터의 유실을 막을 수 있다. 그런데 이런 데이터의 유실을 막기 위해서는 프로듀서의 옵션을 함께 사용해야 한다.

acks 옵션

  • 카프카 프로듀서의 acks 옵션은 0, 1, all(또는 -1) 을 가질 수 있다.
  • acks 옵션을 통해 프로듀서가 전송한 데이터가 카프카 클러스터에 얼마나 신뢰성 높게 저장할지 지정할 수 있다.
  • 쉽게 말해 프로듀서가 리더 파티션으로 데이터를 전송했을 때 리더 파티션으로 데이터가 잘 저장되었는지 확인하는 것이다.

acks=0

  • acks 가 0 으로 설정되어 있다면 프로듀서는 리더 파티션에 데이터가 저장되었는지 여부에 대한 응답값을 받지 않는다.
  • 프로듀서의 전송이 실패했을 때 재시도하는 retries 옵션이 있는데, acks=0 인 경우 실패 여부를 상관없이 성공으로 가정하고 다음을 수행하기에 retries 값이 무의미하다.
  • 데이터가 유실되더라도 전송 속도가 중요할 경우 이 옵션을 사용하면 좋다.

acks=1

  • acks=1 로 설정할 경우 리더 파티션에 적재될 때까지 재시도할 수 있다. 그러나 리더 파티션에 적재되었음을 보장하더라도 데이터는 유실될 수 있다. 팔로워 파티션이 데이터를 복제하기 직전에 리더 파티션이 있는 브로커에 장애가 발생하면 동기화되지 못한 일부 데이터가 유실될 수 있기 때문이다.
  • 적재될 때까지 기다린 뒤 응답 값을 받기 때문에 acks=0 으로 설정하는 것에 비해 전송 속도가 느리다.

acks=all 또는 acks=-1

  • acks 를 all 또는 -1 로 설정할 경우 프로듀서는 보낸 데이터가 리더 파티션과, 팔로워 파티션에 모두 정상적으로 적재되었는지 확인한다.
  • acks=0 , acks=1 보다 속도가 느리다.
  • 일부 브로커에 장애가 발생하더라도 프로듀서는 안전하게 데이터를 전송하고 저장할 수 있음을 보장한다.
  • 추가적으로 acks=all 또는 acks=-1 옵션은 min.insync.replicas 옵션 값에 따라 달라진다.

min.insync.replicas

  • min.insync.replicas 옵션값이 1 이라면, ISR 중 최소 1 개 이상의 파티션에 데이터가 적재되었음을 확인하는 것이다.이 경우 acks=1 로 했을 때와 동일한 동작을 한다. ISR 중 가장 처음 적재가 완료되는 파티션은 리더 파티션이기 때문이다.
  • min.insync.replicas 옵션값이 2 로 설정했을 떄부터 acks 로 설정하는 의미가 있다.
  • ISR 의 2개 이상의 파티션에 데이터가 정상 적재되었음을 확인한다.
  • 실제 카프카 클러스터를 운영하면서 브로커가 동시에 2개가 중단되는 일은 극히 드물기 때문에 데이터는 유실되지 않는다고 볼 수 있다.
  • min.insync.replicas 를 설정할 때는 복제 개수(replication factor)를 고려해야 한다.
    복제 개수를 3 으로 설정하고 min.insync.replicas 를 3 으로 설정했고, 브로커가 3대일 때를 예로 들면, 브로커 3대 중 1대가 장애가나면 프로듀서는 데이터를 더 이상 해당 토픽에 전송할 수 없다. 왜냐하면 최소한으로 복제되어야 하는 파티션의 개수가 3인데 브로커의 개수가 부족하기 때문이다. 이 경우 NotEnoughReplicasException 또는 NotEnoughReplicasAfterAppendException 이 발생하여 더는 토픽으로 데이터를 전송할 수 없다.
  • min.insync.replicas 를 브로커 개수와 동일한 숫자로 설정하면 안된다. 복제 개수를 조정한다고 하더라도, 카프카는 버전 업그레이드와 같은 상황이 발생하면 브로커는 롤링 다운 타임이 생기는데, 브로커가 1대라도 중단되면 프로듀서가 데이터를 추가할 수 없다. 그러므로 토픽별 min.insync.replicas 옵션값을 브로커 개수 미만으로 설정해서 운영해야한다.
  • 일반적으로 브로커가 3대 이상이라고 가정했을 때 토픽의 복제 개수는 3, min.insync.replicas 를 2 로 설정하고 프로듀서는 acks=all 로 설정하는 것이 프로듀서가 데이터를 가장 안정적으로 보내는 설정이다.

min.insync.replicas 설정방법

멱등성(Idempotence) 프로듀서

  • 프로듀서가 데이터를 여러 번 전송하더라도 , 카프카 클러스터에 단 한번만 저장됨을 의미한다.
  • 기본 프로듀서의 동작 방식은 적어도 한번 전달 (at least once delivery)을 지원한다. 다만 두번 이상 적재할 가능성이 있으므로 데이터의 중복이 발생할 수 있다.
  • 프로듀서가 보내는 데이터의 중복 적재를 막기 위해 enable.idempotence 옵션을 사용하여 정확히 한번 전달 ( Exactly Once Delivery ) 를 지원한다.
  • enable.idempotence 기본값은 false 이며 정확히 한번 전달을 위해서는 true 로 사용해야한다.
  • enable.idempotence 값을 true 로 설정하면 정확히 한번 적재하는 로직이 성립되기 위해 프로듀서의 옵션이 강제로 설정된다. retries 는 기본값으로 Integer.MAX_VALUE 로 설정되고, acks 옵션은 all로 설정된다. 멱등성 프로듀서는 정확히 한번 브로커에 데이터를 적재하기 위해 정말로 한번 전송하는 것이 아니라, 상황에 따라 프로듀서가 여러 번 전송하되 브로커가 여러 번 전송된 데이터를 확인하고 중복된 데이터는 적재하지 않는 것이다.

트랜젝션 프로듀서

  • 다수의 데이터를 동일 트랜젝션으로 묶음으로써 전체 데이터를 처리하거나 전체 데이터를 처리하지 않도록 하는 것을 의미한다.
  • 트랜젝션 프로듀서를 사용하려면 enable.idempotence 를 true 로 설정하고, transactional.id 를 임의의 String 값으로 정의한다. 그리고 isolation.level 을 read_committed 로 설정하면 프로듀서와 컨슈머는 트랜젝션으로 처리 완료된 데이터만 쓰고 읽게 된다.
  • 트랜젝션은 파티션의 레코드로 구분한다. 트랜젝션의 시작과 끝을 표현하기 위해 트랜젝션 레코드를 한개 더 보내는 것이다. 컨슈머는 파티션에 저장된 트랜젝션 레코드를 보고 트랜젝션이 완료(commit) 되었음을 확인하고 데이터를 가져간다. 이러한 트랜젝션 레코드는 실질적인 데이터는 가지고 있지 않으며 트랜젝션이 끝난 상태를 표시하는 정보만 가지고 있다. 대신 레코드의 특성은 그대로 가지고 있기에 파티션에 저장되어 오프셋을 한 개 차지한다.

 

spring-kafka-transactional0

spring-kafka-transactional1

spring-kafka-transactional2

 


카프카 옵션들 보러가기

아파치 카프카

아파치 카프카 번역

참고서 : 아파치 카프카 애플리케이션 프로그래밍 with 자바

728x90

'Kafka' 카테고리의 다른 글

Apache Kafka java Custom Producer, Consumer  (0) 2022.03.29
Apache Kafka 실습  (0) 2022.03.27
Apache Kafka 개념  (0) 2022.03.26