Apache Kafka는 빠르고 확장 가능한 작업을 위해 데이터 피드의 분산 스트리밍, 파이프 라이닝 및 재생을 위한 실시간 스트리밍 데이터를 처리하기 위한 목적으로 설계된 오픈 소스 분산형 게시-구독 메시징 플랫폼이다.
Kafka는 서버 클러스터 내에서 데이터 스트림을 레코드로 유지하는 방식으로 작동하는 브로커 기반 솔루션이다. Kafka 서버는 여러 데이터 센터에 분산되어 있을 수 있으며 여러 서버 인스턴스에 걸쳐 레코드 스트림(메시지)을 토픽으로 저장하여 데이터 지속성을 제공할 수 있다.
Apache Kafka의 구성요소
- 토픽
- 지정된 데이터 스트림(일련의 레코드, 메시지)에 대한 관심을 표시하는데 사용되는 주소 지정가능한 추상화
- 게시 및 구독할 수 있으며 애플리케이션에서 주어진 데이터 스프림에 대한 관심을 표시하는데 사용되는 추상화 계층
- kafka 데이터 스트림이 어디에 publish 될지 정하는데 쓰임.
- 파티션을 모아두는 곳이라고 이해해도 좋다
- 파티션
- 요청하는 메시지들의 모임
- 파티션마다 커밋로그가 따로 쌓인다.
- kafka 시스템에서 각 레코드/메시지에는 지정된 파티션의 메시지/레코드를 식별하는데 사용되는 오프셋이라는 순차 ID가 할당된다
메세지/레코드
- byte 배열로 주로 String, json avro를 사용한다
- 메시지 크기에는 제한이 없지만 kb에서 해결하기를 권장
- 데이터는 사용자가 지정한 시간만큼 저장된다.
- 파티션에 들어가는 최소단위
- 영속성
- kafka는 레코드/메시지가 게시될 때 지속적으로 유지되는 서버 클러스터를 유지/관리하여 작동한다.
- kafka 클러스터는 보존 시간 제한을 사용하여 소비에 관계없이 주어진 레코드가 지속되는 기간을 결정한다.
- 레코드/메시지가 보존 시간 제한 내에 있는 동안 레코드/메시지를 사용할 수 있고, 보존 시간을 초과할 시 레코드/메시지는 삭제되는 공간이 확보된다.
- 프로듀서
- 주어진 레코드/메시지가 게시되어야하는 토픽을 정의하고, 파티션도 정의할 수 있다.
- 파티션을 지정하지 않을 시엔 메시지는 파티션에 라운드 로빈 방식으로 분배된다 (로드 밸런싱)
- 컨슈머
- 레코드/메시지를 처리하는 엔티티이다.
- 컨슈머는 개별 워크로드에서 독립적으로 작업하거나, 지정된 워크로드에서 다른 컨슈머와 협력하여 작업하도록 구성할 수 있다.(로드밸런싱)
- 컨슈머는 컨슈머 그룹 이름을 기반으로 워크로드를 처리하는 방법을 관리한다.
- 컨슈머 그룹 이름을 사용하면 컨슈머를 단일 프로세스 내, 여러 프로세스, 심지어 여러 시스템에 분산시킬 수 있다.
Broker Cluster
임의 개수의 노드로 구성되는 클러스터로 토픽을 임의 개수만큼 호스팅할 수 있다
- 브로커는 Replication Factor를 조절할 수 있다. Replication Factor를 2로 지정하면 토픽에 나눠서 한번 씩 담기게 되는 구조를 가진다. 이중 한 브로커가 없어지더라도 완전히 서빙이 될 수 있게 하기 위함이다.
- Replication Factor를 설정하면 리더를 가진다. 그 리더를 중심으로 쓰기 읽기가 가능 하다. 리더가 사라지면 다음 Broker가 받아서 리더가 된다.
토픽/파티션 확장
- kafka는 서버 클러스터로 작동하기 때문에 주어진 토픽/파티션에서 각 서버에 부하를 공유하여 토픽/파티션을 확장할 수 있다.
- 이 부하 공유를 통해 kafka 클러스터의 각 서버는 주어진 토픽/파티션에 대한 레코드/메시지의 배포 및 영속성을 처리할 수 있다.
- 개별 서버가 모든 배포 및 영속성을 처리하는 동안 모든 서버는 서버가 실패할 경우 내결함성과 고가용성을 제공하는 데이터를 복제한다
- 파티션은 파티션 리더로 선택된 한개 서버와 팔로워 역할을 하는 다른 모든 서버들로 분할된다.
- 파티션 리더인 서버는 데이터의 모든 배포 및 영속성 (읽기/쓰기)을 처리하고 팔로워 서버는 내결함성을 위한 복제 서비스를 제공한다.
Apache Kafka 사용 사례
- 서로 다른 구성 요소 간의 안정적인 데이터 교환
- 분산 큐잉 시스템
- 어떤 서비스의 웹 애플리케이션 서버에서 처리하는데 자원을 많이 소비해야할 때, 내부에서 처리하지 않고 백그라운드의 다른 태스크 프로세서에 요청하기 위한 규로 사용
- 분산 큐잉 시스템
- 데이터 처리를 위한 실시간 스트리밍
- 실시간 데이터 업데이트 ex) 통계
- 채팅
- 데이터 메시지 재생에 대한 기본 지원
Kafka vs Socket
실시간으로 통신하고, Pub-Sub 구조로 통신을 하는 방법이 필요하다면 소켓으로도 충분히 해결 가능하다. 소켓이 훨씬 가볍기에 이와 같은 상황에선 소켓이 가장 잘 맞는다. 그럼 kafka는 언제 쓰일까? 먼저 소켓의 단점부터 알아보자.
소켓의 단점
- producer와 consumer가 동시에 온라인 상태여야한다. 둘 중 하나가 오프라인이면 어떤 메세지도 보내지지 않고, 받아지지도 않는다.
- consumer는 producer만큼 스케일 업 되어야한다. producer가 10배의 메세지를 보내면, consumer도 10배 더 받을 수 있어야한다.
- consumer와 producer가 서로를 알아야한다.
- 또다른 consumer가 생기면 producer도 적절한 처리를 해줘야한다.
- 한번 보내진 메세지는 특수한 처리를 하지 않는한 저장되지 않는다.
kafka 등 메세징 시스템에서는
- consumer와 producer가 동시에 online일 필요가 없다.
- consumer와 producer가 서로를 몰라도 된다. 브로커만 알면 되고, 따라서 consumer와 producer 시스템 간 조정을 하지 않아도 된다.
- 메시징 시스템이 consumer와 producer 사이에서 버퍼로 작동한다. 메세지 볼륨이 커지면, 그 메세지들은 카프카에서 버퍼로 관리된되고, consumer는 하나씩 가져오면 된다. 따라서 매번 보내는 메세지의 볼륨 사이즈가 자주 변동되면, kafka는 좋은 선택지이다. 물론 계속 많은 메세지가 오면 consumer는 스케일 업 할 필요가 있지만, 가끔만 많이 오면 kafka가 적절하다
- 브로커를 사용하면, consumer와 producer는 새로운 누군가가 보내고 받는지를 신경쓰지 않아도 된다. 브로커만 신경 쓰면 된다.
- 메세지를 저장하고, offset으로 접근할 수 있다.
이와 같이 kafka는 socket의 단점을 해결해줄 수 있는 방법이며, 따라서 socket의 단점이 문제가 될 때 사용하는 방법이다. 단순히 클라이언트와 실시간 통신을 하는 정도는 socket으로 해결할 수 있지만, 좀 더 복잡한 상황에서는 kafka가 필요하다. 그렇기에 kafka는 주로 백엔드 서비스들 사이의 통신을 하기 위해 사용한다.
예를들어 128대의 서버간 망형태로 연결이 필요한 경우 128^2개의 소켓이 필요하다. 하지만 kafka를 사용하면 128개의 연결만으로도 해결이 가능하다.
출처
- https://www.tibco.com/ko/reference-center/what-is-apache-kafka
- https://engineering.linecorp.com/ko/blog/how-to-use-kafka-in-line-1/
- https://magpienote.tistory.com/212
- https://www.reddit.com/r/learnprogramming/comments/l0vqao/should_i_use_websockets_or_kafk
- https://ence2.github.io/2020/11/kafka%EC%B9%B4%ED%94%84%EC%B9%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80/