이 편에서는 브로커가 데이터를 받는 순간부터 디스크에 기록되고, 리플리카가 맞춰지고, 컨슈머가 읽어가기까지의 흐름을 자세하게 살펴볼 예정이다.

기술적인 내용은 실제로 데이터가 움직이는 모습을 상상하면서 읽을 수 있게 작성해서 이해를 꼭하고 넘어간다.

브로커에 기록 요청이 도착하면 벌어지는 일

프로듀서가 send를 호출하면 브로커는 그 요청을 받아들인다.

그 순간부터 브로커가 하는 일은 크게 네 단계의 감각으로 이해할 수 있다.

데이터의 목적지 확인

받은 레코드가 어느 토픽의 어떤 파티션으로 향해야 하는지를 판단한다. 파티션 키가 있다면 해시 함수를 이용해 목적지를 계산하는 과정도 포함된다.

페이지 캐시 활용

Kafka는 디스크에 바로 쓰기보다는 운영체제의 페이지 캐시를 적극적으로 사용한다. 덕분에 디스크 입출력 병목을 피하고, 초당 수십만 건의 쓰기 요청도 밀리지 않고 흘려보낼 수 있다.

Commit Log Append

Kafka가 세상에서 가장 빠른 이유 중 하나가 바로 여기 있다.

파티션은 동적인 파일이 아니라 단순한 append-only 로그라는 점이 중요하다. 기존 데이터를 수정하지 않고 뒤에만 추가하기 때문에 디스크 단편화와 복잡한 연산이 필요 없다.

리플리카 동기화

리더 파티션에 기록된 내용은 팔로워가 끊임없이 따라붙으며 복제한다. 이 과정에서 ISR(In-Sync Replica) 그룹이 유지되는지 확인하면서 고가용성을 만들어낸다.

이 흐름을 시각적으로 풀어낸 다이어그램

아래 다이어그램은 브로커가 레코드를 받아서 로그에 기록하고, 리플리카로 퍼뜨리고, 준비된 데이터를 컨슈머에게 제공하는 흐름을 한눈에 볼 수 있도록 정리한 그림이다.

flowchart LR
    subgraph ProducerSide
        A(Record 생성) --> B(브로커로 전송)
    end

    subgraph BrokerInternal
        B --> C(파티션 결정)
        C --> D(OS Page Cache)
        D --> E(Commit Log Append)
    end

    subgraph Replication
        E --> F(리더 파티션)
        F --> G(팔로워 복제)
    end

    subgraph ConsumerSide
        E --> H(Offset 기반 읽기)
        G --> H
    end

왜 Kafka는 이렇게 설계되었을까

Kafka는 단순히 “빠르다”라는 수식어로는 설명하기 어려운 시스템이다.