카프카 튜닝 방안 정리
카프카는 사용하려는 서비스 목적에 따라 성능 목표를 크게 Throughput, Latency, Durability, Availability 네가지로 분류할 수 있다. 각 목표는 상호 trade-off 관계로 모든 목표를 동시에 모두 최적화 할 수 없다.
Throughtput 최대화 방안
프로듀서
- 파티션 수 증가
- batch.size 증가 : 한번에 보내는 양을 증가시켜 전송 횟수 감소
- Linger.ms 조정 : 프로듀서가 전송전 대기 시간으로 batch.size 가 가득 찰 수 있도록 조정
- 기본 값 0 : 데이터를 수집하는 순간 broker 로 전송 (지연 시간, 처리량 감소)
- compression.type : 메시지 압축
- buffer.memory : 프로듀서가 보내지 못한 메시지를 보관하는 메모리 크기 조정
- 메모리가 full이 되면, 메시지 전송을 막음
- 메모리에 여유가 생기거나, max.block.ms 를 초과하면 전송
- 파티션이 많지 않으면, 조정할 필요 없음.
- 파티션이 많다면, 메모리를 늘려서 블락없이 더 많은 데이터가 전송되도록 설정
컨슈머
- 컨슈머과 파티션을 1 : 1
- fetch.min.bytes : 컨슈머가 가져오는 최소 데이터 사이즈 (기본값 1 byte)
- 이 값보다 적은 데이터가 있으면 브로커에서 보내지 않음
- 값 증가시키면 프로듀서의 batch.size 증가와 동일 효과
- fetch.max.wait.ms : 컨슈머에서 데이터를 가져오는 최소 시간 (기본값 500 ms)
- 새로운 데이터가 입력되어도, 해당 시간 이전에는 가져가지 않는다.
- 내부적으로 컨슈머가 fetch 요청을 해도, 브로커가 보내지 않음
Latency 최소화 방안
브로커
- 파티션 개수 제한
- 너무 많은 파티션은 메시지 지연을 유발, 파티션 복사를 위한 시간만큼 지연 (ACK > 1)
- 브로커 수 증가, 파티션 수 적게
- 하나의 브로커에서 감당하는 파티션서를 감소시켜 복제에 소요되는 시간을 최소화
- Num.replica.fetchers
- Follower broker 의 I/O 병렬 수준을 정의 (기본값 1)
- Leader broker 에서 데이터를 복제하는 thread 의 개수
프로듀서
- Linger.ms : 프로듀서가 전송전에 기다리는 시간
- batch.size 가 꽉 찰 수 있도록 시간 설정
- 기본 값 0 : 데이터를 수집하는 순간 broker 로 전송 (지연 시간, 처리량 감소)
- compression.type :압축이 필요한지 검토
- CPU : 압축을 위한 자원 사용
- NW : 압축된 경우 NW bandwidth 사용량 줄어듬
- 압축 성능에 따라 cpu 사용, NW bandwidth 줄여서 지연 최소화 가능
- Acks
- 언제 broker로부터 메시지 전송 결과를 받을 것인지 정의
- 1 : 데이터 복제 없이, 원본만 저장되면 결과 리턴
컨슈머
- fetch.min.bytes (기본값 1)
- broker 에서 데이터를 가져오는 최소 size
- 1 : 1byte 만 있어도 요청시 바로 전송 (지연 없음)
Durability 보장 방안 (메시지 유실 최소화)
브로커
- replication.factor
- 3 : 높은 수준의 durability 지원
- default.replication.factor
- auto.create.topics.enable 가 true 인 경우, 자동으로 생성되는 topic 의 복제수 설정
- 운영상의 안정성을 위해 false 설정을 권장
- acks = all (acks = -1 동일)
- 모든 replica 에 복제가 완료된 후, producer 에 ack 리턴
- broker.rack
- 하나의 rack 에 brocker 가 동작하지 않도록 설정
- cloud 기반 서비스에서 brocker 가 각각 다른 zone 에 구동되도록 함
- 안정성은 높아지지만 데이터 복제시 NW 부하 증가
- unclean.leader.election.enable
- broker 가 죽었을 때, OSR replica 도 leader 로 선택될 수 있도록 설정 (true)
- OSR (our-of sync replica) : 죽은 broker 의 최신 메세지를 복하지 못한 replica 즉, 데이터 유실 가능
- 유실보다 서비스 가용성을 높이는 경우 (true)
- 유실을 최소화하는 경우 (false)
- log.flush.interval.ms / log.flush.interval.messages
- 입력된 메시지를 메모리(페이지 캐시)에서 디스크로 저장하는 수준
- 값이 클수록 disk i/o 적게 발생 → 메모리 데이터 유실 가능
- 값이 작을수록 disk i/o 많이 발생 → 메모리 데이터 유실 거의 없음
프로듀서
- acks=all (acks = -1 동일)
- 모든 replica 에 복제가 완료된 후, producer 에 ack 리턴
- min.insync.replicas : acks=all 일때 broker 가 ack 를 보내기 위한 최소 복제본의 수
- retries
- 전송 실패 시 자동으로 재전송하는 회수
- 메시지 중복 가능성 증가 : 일시적 오류로 프로듀서가 2번 전송 가능
- 메시지 순서 변경 가능
- 한번에 여러 번의 request 가 nw 에서 대기중인 경우, fail 된 request 다음 메시지가 먼저 전송되는 경우 발생
- max.in.flight.requests.per.connection = 1 로 설정 (한번에 1개 요청)
컨슈머
- 메시지 중복 읽기 또는 유실 가능한 상황
- enable.auto.commit=true
- auto.commit.interval.ms=5000ms
- poll()을 호출할 때마다 commit 할 시간이 되었는지 확인하고 커밋 수행
- 해결 방안
- auto.commit.enable = false 사용, 메뉴얼 커밋
Availability 보장 방안 (장애 복구를 빠르게)
브로커
- 너무 많은 파티션 수 제한
- 파티션 별 리더 선출에 많은 시간 소요
- min.insync.replicas
- 프로듀서가 응답을 받기 위한 최소 복제 수
- 값이 크면, 복제 실패시 프로듀서 장애 유발 → durability 높음
- 값이 1 이면, 원본만 저장되면 프로듀서 정상 동작 → durability 낮음
- unclean.leader.election.enable
- broker 가 죽었을 때, OSR replica 도 leader 로 선택될 수 있도록 설정 (true)
- OSR (our-of sync replica) : 죽은 broker 의 최신 메세지를 복하지 못한 replica 즉, 데이터 유실 가능
- 유실보다 서비스 가용성을 높이는 경우 (true)
- 유실을 최소화하는 경우 (false)
- num.recovery.threads.per.data.dir
- 브로커가 시작/중지할 때, 다른 브로커와 sync 를 맞추기 위해 log data file 을 스캔하는 쓰레드 개수
- 값이 크면 한번에 여러 log file 을 동시 처리 가능 (raid 구성인 경우)
- 즉 브로커 구동 속도가 빠름
컨슈머
- session.timeout.ms (기본 값 10000 ms)
- 컨슈머가 비정상적으로 종료되었을 경우, 브로커가 장애로 인지하는 최소시간
- 장애유형
- Hard failure : SIGKILL (강제종료)
- Soft failure : session time out (대부분의 경우)
- poll 호출 후, 컨슈머의 처리시간이 오래 걸리는 경우
- JVM GC 로 인한 멈춤 현상
- 값이 적을수록 빠르게 장애 감지 (복구 빠름)
- 장애가 더 자주 나타남 (조금만 지연되어도, failure 로 판단)
- 가능한 낮은 값을 설정하여, Hard failure 를 빠르게 감지하도록 설정
- 너무 낮게 설정하면, Soft failure 까지 감지하여 너무 잦은 리밸런싱 발생