기본적인 내용들
- Pub-sub 모델
- zookeeper = 카프카 브로커들 사이의 메시지 전달을 위한 메시지큐
- broker = 카프카 인스턴스들
- producer = 메시지의 생산자
- topic = 의미 단위의 메시지 저장소
- partition = topic 내의 메시지 분산저장(분산처리를 위함)
- replication = partition의 복제본
- leader = replication들 중, read, write 모두를 수행하는 유일한 partition
- follower = replication들 중, write만 수행하는 나머지 partition들
- consumer-group = consumer들의 묶음
- 하나의 partition은 하나의 consumer에만 배정될 수 있음
- consumer는 여러개의 partition을 배정받을 수 있음
- 파티션 마다 존재하는 오프셋을 관리함
- 즉 하나의 컨슈머 그룹은, 각 컨슈머에서 메시지를 분산해서 읽게 됨
- 여러개의 컨슈머 그룹이 존재할 경우, 오프셋이 각각 저장되므로 하나의 메시지를 각각 읽게됨.
순서에 관해서
- Producer가 여러개일 경우 생기는 동시성 문제는 논외
- 순서는 파티션 단위로만 보장 될 수 있음
max.in.flight.requests.per.connection = 1
이면 생산자가 한번에 한 요청만 보냄- 한번에 한 요청이면 단일 파티션 내 순서 보정
max.in.flight.requests.per.connection = 5
이면 생산자가 한번에 5개 요청을 보냄- 한반에 여러개 요청이면, 첫번째 요청이 지연되는동안 뒤쪽 요청이 먼저 기록될 수 있음
- 하나의 Consumer가 여러개의 파티션에서 받아오면
- 순서가 보장 안됨, 필요하면 앱 단에서 정렬하던지 해서 순서 보장해야면
멱등성에 관해서
- acks: Producer가 기록 후 파티션의 승인을 받음
acks = 0
: 아예 승인을 받지 않음, 높은 성능, 높은 가능성으로 메시지 유실acks = 1
: leader 파티션의 승인만 받음, 중간 성능, leader의 장애시 메시지 유실acks = -1
: 모든 파티션의 승인을 받음
- 의미론적 관점의 메시징
- at most once: 대부분은 한번 전달됨, acks = 0 or 1
- at least once: 최소한 한번은 전달됨, acks = -1
- exact-once: 무조건 한번만 전달, 성능상 포기해야할게 많음
- exact-once를 위한 조건들
- acks가 1이어야 함
- Producer는
enable.idempotence = true
이어야함 - Producer는 transaction을 사용해 써야함, 시작 -> 기록 -> 커밋
- Consumer는
isolation.level = read_committed
enable.idempotence = true
- 각 메시지에 Producer ID와 Seq값을 부여
- Producer가 죽지 않는 한, 브로커는 같은 PID를 가지는 중복된 Seq을 버릴 수 있음
- Producer가 죽어서 재생성되면, PID가 바뀌어서 중복 Seq 발생할수도 있음
- transaction
- Produce에
transactional.id
를 적당한 고유값으로 설정 beginTransaction()
과commitTransaction()
사이에 send를 보낸다.- Broker 내에서는 같은 id를 가지는 여러 transaction이 존재할 수 없음, 원자성 보장
- commit되지 않았던 transaction은 새 transaction이 시작되면 좀비 취급되어 삭제
- Produce에
isolation.level
read_committed
는 커밋된 메시지만 읽음read_uncommiteed
는 커밋여부와 상관없이 읽음(기본값)