1. 카프카를 만나보자!


애플리케이션 성능 모니터링을 위해 메트릭을 수집한다면...

그러나, 시간이 지나고 여러 서버에서 다양한 포맷의 데이터를 수집하게 된 플랫폼은 점점 복잡해져간다 ㅠㅠ
이렇게 복잡하게 처리하지 말고 한 곳에서 데이터를 받은 다음 필요한 곳으로 보내줄 수는 없을까?..

Pub/Sub Messaging System을 이용한 구조

  • 메시징 패러다임 중 하나
  • Subscriber가 정해져 있지 않고 대신 Publisher가 발행한 메시지는 정해진 범주에 따라, 각 범주에 대한 구독을 신청한 Subscriber에게 전달됨
  • Subscriber는 Publisher에 대한 지식이 없어도 원하는 메시지만을 수신할 수 있음
  • 이렇게 Publisher와 Subscriber를 분리함으로써 융통성있는 네트워크 토폴로지와 높은 확장성을 가능케 함

이 시스템을 계속 확장해간다면... 여러 서버에서 다양한 포맷의 데이터를 수집하게 된 플랫폼은 점점 복잡해져간다 ㅠㅠ
그렇다면 이 상황에서 Kafka를 쓴다면 ?!?! GOOOD!

Apache Kafka

  • LinkedIn에서 오픈소스로 공개
  • 빠르고 확장 가능하며 고가용성의 분산 메시징 시스템
  • 실시간 데이터 전송을 위한 통합 시스템으로 설계되었음
  • 전통적인 메시징 모델인 “Publish - Subscribe”와 “Queueing”의 장점을 혼합
  • 메시징 모델
    • Publish - Subscribe
      • Publisher가 Subscriber로 데이터를 Broadcast하기 때문에 확장이 어려움
    • Queuing
      • 여러 Consumer가 하나의 Queue에서 데이터를 읽을 수 있으므로 데이터 처리를 쉽게 분산시킬 수 있음
      • Queue는 Multi Subscriber를 지원하지 않기 때문에 한 번에 하나의 프로세스만 데이터를 읽을 수 있음

메세지 ( Message)

  • Kafka의 데이터 처리 단위 ( 데이터베이스로 비유하면 Row나 Record )
  • Kafka는 메시지를 바이트 배열로 처리하며 메시지 포맷은 관심없음
    • 바이트 배열로 처리하는 이유는 성능과 관련이 있다고 함 관련 문서
  • 메시지는 Key라고 불리는 메타데이터를 포함할 수 있음
    • Key 역시 바이트 배열이고 Kafka는 Key에 대해서도 관심갖지 않음
    • Key는 메시지를 어느 파티션에 저장할지 결정할 때 사용

배치 ( Batch )

  • 효율성을 이유로 Kafka에서는 메시지를 배치로 처리
  • 배치는 같은 토픽, 같은 파티션에 저장되는 메시지 묶음
  • 한 번에 처리되는 메시지양을 늘리면 처리량은 향상되는 대신 지연 시간이 늘어남
  • 배치는 네트워크 전송 비용과 저장 비용 감소를 위해 압축할 수 있음

스키마 (Schema)

  • 메시지는 바이트 배열이지만 쉽게 이해할 수 있도록 스키마를 갖는 것을 추천
    • 일관성있는 데이터 형식은 쓰기와 읽기를 분리 가능하게 함
    • 쓰기와 읽기가 강하게 연결되어 있으면 호환성 유지를 위해 한 쪽이 수정되면 다른 한 쪽도 수정이 필요함
  • 많은 Kafka 개발자들은 Apache Avro를 선호함
    • Apache Avro의 장점
    1. 스키마가 메시지 내용과 분리
    2. 스키마 변경에도 코드 수정 불필요
    3. 강한 타입 체크
    4. 스키마 변경에도 호환성 유지 가능

토픽과 파티션

  • 메시지는 토픽으로 분류
    • 데이터베이스에서 테이블이 토픽과 비슷한 역할을 함
  • 토픽은 다시 파티션으로 나누어짐
  • 파티션은 “Append Only”이며 파티션에 저장된 메시지는 들어온 순서대로 읽힘
    • 파티션 내에서는 들어온 시간 순으로 정렬되어 있으나
    • 토픽 내 전체 파티션 내에서는 시간 순으로 정렬되어 있는 것을 보장하지 않음
  • 파티션은 여러 서버에 분산될 수 있기 때문에 Kafka는 파티션을 통해 Redundancy와 Scalability를 제공

Producer

  • Kafka의 데이터를 사용하는 두 개의 클라이언트 중 하나
  • 메시지 (Message)를 만들어내는 생산자
  • 생산한 메시지는 Kafka로 보냄
  • 생산한 메시지는 토픽 (Topic)으로 분류
  • 메시지가 어느 파티션에 저장되는지 관심없음
  • 다만, 메시지에 포함된 Key로 같은 Key를 가진 메시지가 같은 파티션에 저장되도록 할 수 있음

Consumer

  • Kafka에서 데이터를 사용하는 두 개의 클라이언트 중 하나
  • 하나 이상의 토픽을 구독하거나 토픽을 구독하지 않을 수 있음
  • 메시지는 생산된 순서대로 읽음
  • 오프셋 (Offset)
    • Consumers는 파티션에서 읽은 부분까지를 오프셋 (Offset)으로 기억하기 때문에 Conumser가 중단되거나 재시작되더라도 위치를 잃어버리지 않음
    • 메시지가 만들어질 때 부여됨
    • 오프셋은 증가하는 정수값
    • 오프셋은 Kafka 내부나 Zookeeper에 저장됨
  • Consumer Group
    • 하나 이상의 Consumer가 하나의 토픽을 같이 구독
    • Consumer Group은 각 파티션이 그룹 내 오직 하나의 멤버만 접근하도록 보장

브로커 (Broker)

  • Kafka 서버 하나를 브로커라고 부름
  • 브로커는 다음 역할을 수행
    1. Producer에서 생산한 메시지를 수신
    2. 메시지에 오프셋을 붙임
    3. 메시지를 디스크에 저장
    4. Consumer의 요청을 처리
  • 하드웨어와 사용 방식에 따라 한 대의 브로커가 1초에 수백만 개의 메시지를 처리할 수 있음

클러스터 ( Cluster)

  • 브로커는 클러스터로 동작하도록 설계되었음
  • 클러스터의 브로커 중 하나는 “Cluster Controller” 역할을 함
    • Cluster Controller는 살아있는 멤버 중 하나에서 자동으로 선출됨
    • 브로커에 파티션을 할당하거나 장애 상황을 모니터링하는 등의 관리자 역할을 함
  • 복제 (Replication)
    • 같은 파티션을 여러 브로커에 복제하여 저장 가능
    • 그러한 파티션들 중 하나는 그 파티션의 리더가 되고 그 파티션에 읽기나 쓰기 작업을 할 때는 리더 파티션에서만 처리할 수 있음
    • 리더 파티션에 장애가 발생하면 다른 파티션이 리더가 됨

리텐션 (Retention)

  • 메시지를 소비된 이후에도 일정 기간동안 저장하는 기능
  • 메시지 보존은 기간이나 용량으로 설정할 수 있음
  • 토픽 별로 리텐션 설정을 다르게 할 수 있음
  • “log compacted”로 설정되면 Key별로 가장 마지막에 생산된 메시지만 보존함

Kafka를 사용해야 하는 이유

  1. Multiple Producers
    • 여러 Producer가 한 개 또는 여러 개의 토픽을 구독할 수 있음
  2. Multiple Consumers
    • Consumer들이 서로 영향을 끼치지 않고 메시지를 자유롭게 읽을 수 있는데 이러한 점은 다른 메시징 시스템에서는 불가능함
  3. Disk-Based Retention
    • 실시간 처리 뿐만 아니라 다른 요구사항에도 대응 가능
    • 또한 리텐션은 데이터 유실도 방지
  4. Scalable
    • 확장은 장비를 내리지 않고 가능하고 시스템의 가용성에 영향을 주지 않음
  5. High Performance

참고자료

  1. Reference Guide for Deploying and Configuring Apache Kafka
  2. Apache Kafka Documentation
  3. 발행-구독 모델

이 글은 Kafka: The Definitive Guide 원서를 읽고 정리한 내용입니다 :)