개발 학습 실습실

이 사이트의 실습은 자바스크립트를 켜야 움직입니다. 아래는 같은 내용을 글로 적은 것입니다.

공부 › 아키텍처와 운영 › 메시지와 비동기

Kafka 파티션과 컨슈머

컨슈머를 늘렸는데 왜 처리량이 그대로인가

토픽은 여러 파티션으로 나뉘고, 같은 그룹의 컨슈머들이 파티션을 나눠 맡습니다. 파티션 하나는 그룹 안에서 한 컨슈머만 읽을 수 있습니다.

문서·표준 대조 · Kafka 공식 문서

이 실습에 나오는 개념

Kafka의 토픽, 파티션, 오프셋
토픽은 메시지를 종류별로 구분하는 이름이다. 토픽은 하나 이상의 파티션으로 나뉘며, 파티션은 메시지가 도착한 순서대로 뒤에 덧붙여지는 기록(로그)이다. 오프셋은 파티션 안에서 각 메시지의 위치를 나타내는 번호로, 소비자는 자신이 어디까지 읽었는지를 오프셋으로 기록한다. 순서는 같은 파티션 안에서만 보장된다.
컨슈머 그룹과 리밸런싱
컨슈머 그룹은 하나의 토픽을 나눠서 처리하는 소비자들의 묶음이다. 그룹 안에서 각 파티션은 한 소비자에게만 배정되어 메시지를 분담한다. 리밸런싱은 소비자가 추가되거나 종료되었을 때 파티션 배정을 다시 나누는 과정으로, 진행되는 동안 처리가 잠시 지연될 수 있다.
Consumer Lag
생산자가 넣은 마지막 메시지의 위치와 소비자가 처리한 위치의 차이, 즉 아직 처리되지 않고 쌓여 있는 메시지의 양이다. 값이 계속 커지면 소비 속도가 생산 속도를 따라가지 못하고 있다는 뜻이다.
메시지 전달 보장
메시지가 몇 번 전달되는지에 대한 보장 수준이다. at-most-once는 최대 한 번 전달되어 중복은 없지만 유실될 수 있다. at-least-once는 최소 한 번 전달되어 유실은 없지만 중복될 수 있다. exactly-once는 정확히 한 번 전달된다. 실무에서는 at-least-once로 두고 소비자가 중복을 처리(멱등)하도록 만드는 경우가 많다.
메시지 큐
보내는 쪽(생산자)과 받는 쪽(소비자) 사이에서 메시지를 보관했다가 전달하는 중간 저장소다. 생산자는 메시지를 넣고 바로 다음 일을 하며, 소비자는 자신의 속도로 꺼내 처리한다. 두 시스템이 서로를 직접 호출하지 않아 결합이 낮아지고, 순간적으로 몰린 요청을 쌓아 두었다가 처리할 수 있다.
멱등성과 멱등키
멱등성은 같은 요청을 여러 번 수행해도 결과가 한 번 수행한 것과 같은 성질이다. 네트워크 문제로 같은 요청이 다시 전송될 수 있으므로, 결제처럼 중복되면 안 되는 작업은 멱등하게 만들어야 한다. 멱등키는 클라이언트가 요청마다 붙이는 고유한 값으로, 서버는 이미 처리한 키의 요청이 다시 오면 다시 처리하지 않고 이전 결과를 돌려준다.

이렇게 바꿔 보세요

처음 설정으로 실행하면

  1. 컨슈머 2개가 같은 그룹으로 토픽을 구독합니다. 파티션 3개를 컨슈머들이 나눠 맡습니다(배정은 그룹 코디네이터가 조율합니다). 파티션 하나는 그룹 안에서 한 컨슈머만 맡습니다.
  2. 메시지가 초당 120건 들어와 파티션마다 40건씩 쌓입니다(키가 고르게 퍼진다고 가정). 컨슈머는 하나당 초당 50건을 처리하고, 여러 파티션을 맡은 컨슈머는 그 능력을 나눠 씁니다. 그룹 전체의 처리량은 초당 90건입니다.
  3. 10초가 지났습니다. 처리가 유입을 따라가지 못해 메시지 300건이 읽히지 않은 채 밀려 있습니다(컨슈머 랙). 이 상태가 계속되면 랙은 끝없이 늘어납니다.

실행 결과

코드

// 토픽 orders: 파티션 3개
// 컨슈머 그룹 order-service: 컨슈머 2개

while (true) {
    ConsumerRecords<String, Order> records = consumer.poll(Duration.ofMillis(500));
    for (var r : records) {
        handle(r.value());               // 먼저 처리
    }
    consumer.commitSync();               // 그다음 "여기까지 읽었다"고 기록
}

이 모형의 전제

메시지 키가 고르게 퍼져 파티션마다 같은 양이 들어온다고 가정했고, 파티션은 컨슈머에게 차례로 하나씩 돌아가며 배정된다고 단순화했습니다(실제 배정 전략은 설정에 따라 다릅니다). 리밸런싱에 걸리는 시간과 그동안의 지연은 수치로 넣지 않았습니다. 죽은 컨슈머의 예(다섯 건 중 세 건 처리)는 커밋 시점에 따른 차이를 보이기 위한 고정된 상황입니다. 파티션 하나를 그룹 안에서 한 컨슈머만 읽는다는 규칙과 전달 보장의 정의는 Kafka 공식 문서를 따랐습니다.

앞 실습: 메시지 큐 기본 · 다음 실습: 서킷 브레이커

이 실습에 나오는 개념

이 실습에서 보는 것

설정

코드


      
    

그림

실행 비교

이렇게 바꿔 보세요