카프카 찍먹하기 1부

카프카를 알아보기전에 메시지 브로커와 이벤트 브로커의 차이점을 간단히 살펴보자

메시지 브로커 vs 이벤트 브로커

메시지 브로커

  • 메시지는 서로 다른 서비스 혹은 시스템간의 메시지를 중계하는 역할을 한다

  • 메시지 브로커는 메시지를 검증, 저장, 라우팅하고 이를 적절한 대상에 전달할 수 있다

  • 메시지를 처리하고 나면 즉시 또는 짧은 시간 내에 삭제된다

  • 대표적인 메시지 브로커로는 rabbitMQ나 Redis Queue가 있다

  • rabbitMQ 같은 경우, 브로커에서 exchange나 메시지 표식을 사용하는 등 브로커에 많은 책임이 주어진다

  • 메시지는 exchange를 통해 컨슈머에게 제공되어, 컨슈머는 메시지를 큐를 통해서 읽어들이게 된다

  • 이와 같은 구조는 소비자와 메시지 브로커의 결합력이 높아지게 되어 앱의 트래픽이 증가하여도 수평적으로 확장하는 데에 어려움이 있다

이벤트 브로커

  • 이벤트 브로커는 기본적으로 메시지 브로커의 역할도 할 수 있다

  • 이벤트 브로커의 pub/sub 모델은 메시지를 특정 수신자에게 직접적으로 보내주는 방식이 아닌 subscriber가 특정 토픽의 메시지를 읽어오는 방식으로 트래픽에 따라 확장하기 용이한 구조이다

  • 이벤트 브로커의 가장 큰 차이점은 이벤트를 소비해도 이벤트가 즉시에 삭제되지 않는다는 점이다

  • 이벤트를 보관하기 때문에 장애가 일어난 시점부터 재처리 할 수 있다

  • 대표적으로 Kafka나 AWS Kinesis가 있다

카프카는 이벤트를 얼마나 오래 보관하는가?

보관주기 옵션은 사이즈나 시간으로 제한을 둘 수 있다

  • log.retention.bytes : byte 단위 기준으로 데이터 보관

  • log.retention.ms : 초 단위 기준으로 데이터 보관

  • log.retention.minutes : 분 단위 기준으로 데이터 보관

  • log.retention.hours : 시간 단위 기준으로 데이터 보관(기본값 168시간 = 7일)

카프카 구성 요소

카프카 구성 요소

  • 카프카 클러스터 : 브로커들이 위치해 있다. 저장소 용도

  • 주키퍼 : 클러스터를 관리하기 위한 용도, 클러스터 관리

  • 프로듀서 : 카프카 클러스터에 메시지를 보내는 용도

  • 컨슈머 : 카프카 클러스터에 적제된 메시지를 소비하는 용도

토픽과 파티션

  • 토픽 : 메시지를 구분하는 단위

파티션

  • 메시지를 저장하는 물리적인 파일이다

  • 프로듀서는 파티션을 지정하지 않을 경우 라운드 로빈 방식으로 저장된다

  • 특정 파티션으로 저장하고 싶을 경우에는 파티션 키를 지정하여 동일한 파티션으로 저장하면 된다

  • 컨슈머는 하나의 컨슈머 그룹에 속해야 한다. 그리고 한개의 파티션은 하나의 컨슈머 그룹의 특정 컨슈머에 연결 되어 있다

  • 파티션은 추가만 가능하고 삭제는 불가능 하니, 주의해서 추가해야 한다 (append-only)

카프카를 이용하면서 순서를 보장하기 위해서는 어떻게 해야 할까? 특정 토픽에 대해 단일 파티션일 경우, 단일 컨슈머가 메시지를 소비할 것이다. 그러면 순서는 보장이 된다. 만약 이미 파티션을 확장하였다면 하나의 토픽에 대해서 여러개의 컨슈머가 동시에 소비하고 있을 것이다. 동시에 소비한다는 것은 순서보장이 되지 않는다는 것을 의미한다. 만일 파티션을 확장한 상태에서 순서 보장을 하고 싶을 경우에는 특정 파티션에만 메시지를 전달하면 단일 컨슈머만 소비하게 되니 순서를 보장할 수 있다. 특정 파티션으로 전달하는 방법은 파티션 키를 추가적으로 전달하면 된다. 프로듀서는 파티션 키를 지정하게 되면 내부적으로 해시함수를 통해서 특정 파티션을 지정하게 된다

카프카 성능

  • 카프카의 성능을 향상시키는 몇 가지 특징이 있다

  • 파티션 파일은 OS 페이지 캐시를 사용한다

OS 페이지 캐시란?

  • 페이지 캐시 기능은 OS에서 사용하는 페이지 캐시와 동일하며, 메모리 영역(RAM)에 애플리케이션이 사용하는 부분을 할당하고, 남은 잔여 메모리를 캐시로 전환하여 디스크 접근을 최소화해 I/O 성능을 향상시키는 메모리 영역이다

  • 카프카는 페이지 캐시를 적극적으로 사용하고 있기 때문에 서버에 디스크를 SSD로 구성하지 않아도 되며, 페이지 캐시를 사용하기 위해서 잔여 메모리를 쓰기 때문에 카프카 서버에 다른 애플리케이션을 함께 실행하는 것을 권장하지 않는다

  • 제로 카피를 사용하면 디스크에서 네트워크 버퍼로 직접 데이터 복사하기 때문에 메시지를 빠르게 송신할 수 있다

  • 프로듀서, 컨슈머 양쪽 모두 배치로 전송하는게 가능하다

리플리카(복제)

  • 카프카는 브로커에 대한 장애를 대비해서 레플리케이션 기능을 제공한다

  • 레플리케이션에 대한 갯수는 토픽 단위로 지정할 수 있다

  • 원본 데이터가 저장되는 브로커를 리더라고 하며, 복제되는 데이터가 저장되는 브로커를 팔로워라 명명한다

  • 리더가 장애시 다른 팔로워가 리더로 승격하게 된다

오프셋

  • 메시지 저장 위치를 오프셋이라고 한다

  • 메시지는 삭제 되지 않고 설정에 따라 일정 시간이 지난 뒤 삭제된다 (retention 설정 확인 필요)

확장은 어떻게 하면 좋을까?

만약 이벤트 저장 용량이 한계라면?

  • 브로커를 추가해서 저장 공간을 확장할 수 있다

  • 브로커를 추가했으면 파티션도 함께 추가해서 데이터를 더 많은 공간에 분산 처리할 수 있도록 하면 된다

만약 컨슈머가 느리다면?

  • 컨슈머를 추가하면 된다

  • 그러나 파티션당 컨슈머는 하나씩 매핑되므로 파티션도 증가시켜야 성능 향상을 기대할 수 있다

참고

Last updated