-
3장 - 카프카 스트림즈📕 book/아파치 카프카 2022. 9. 18. 17:57
카프카 스트림즈
💡 토픽에 적재된 데이터를 상태기반(Stateful) 또는 비상태기반(Stateless)으로 실시간 변환하여 다른 토픽에 적재하는 라이브러리이다.
카프카의 스트림 데이터 처리를 위해
- 아파치 스파크
- 아파치 프링크
- 아파치 스톰
- 플루언트디
와 같은 다양항 오픈소스 애플리케이션이 존재하는데
❓ 카프카 스트림즈를 사용해야 하는 이유
❗스트림즈는 카프카에서 공식적으로 지원하는 라이브러리!!
- 카프카 버전이 오를 때 마다 스트림즈 자바 라이브러리도 같이 릴리즈 된다.
- 때문에, 자바 기반 스트림즈 애플리케이션은 카프카 클러스터와 완벽하게 호환되면서 스트림 처리에 필요한 편리한 기능들(신규 토픽 생성, 상태 저장, 데이터 조인 등)을 제공한다.
스트림즈 애플리케이션 또는 카프카 브로커의 장애가 발생하더라도 정확히 한 번 할 수 있도록 장애 허용 시스템을 가지고 있어서 데이터 처리 안정성이 매우 뛰어나다.
→ 실시간 스트림 처리를 해야하는 필요성이 있다면 카프카 스트림즈 애플리케이션으로 개발하는 것을 1순위로 고려!!!
자바 라이브러리로 구현하는 스트림즈 애플리케이션은 JVM위에서 하나의 프로세스로 실행된다.
보충 내용 : 프로듀서와 컨슈머를 조합해서 사용하지 않고 스트림즈를 사용해야 하는 이유
- 스트림 데이터 처리에 있어 필요한 다양한 기능을 스트림즈 DSL로 제공하며 필요하다면 프로세스 API를 사용하여 기능을 확장할 수 있기 때문
- 프로듀서와 컨슈머를 조합하면 스트림즈 라이브러리에서 제공하는 기능과 유사하게 만들 수 있지만, 완벽하게 구현하기는 어렵다.
- 하지만, 스트림즈가 제공하지 못하는 기능을 구현할 때는 조합하여 구현하면 좋다.
스트림즈 애플리케이션은 내부적으로 스레드를 1개 이상 생성할 수 있다.
스레드는 1개 이상의 태스크를 가진다.
스트림즈의 태스크 : 스트림즈 애플리케이션을 실행하면 생기는 데이터 처리 최소 단위
- 카프카 스트림즈는 병렬처리를 위해 파티션과 스트림즈 스레드(또는 프로세스)개수를 늘림으로써 처리량을 늘릴 수 있다.
카프카 스트림즈 구조
토폴로지
카프카 스트림즈의 구조와 사용방법을 알기 위해서는 우선 토폴로지(topology)와 관련된 개념을 익혀야 한다.
토폴로지란 2개 이상의 노드들과 선으로 이루어진 집합을 말한다.
종류
- 링형(ring)
- 트리형(tree)
- 성형(star)
스트림즈에서 사용하늩 토폴로지는 트리 형태와 유사하다.
프로세서, 스트림
카프카 스트림즈에서는 토폴로지를 이루는 노드를 하나의 프로세서 라고 부르고
노드와 노드를 이은 선을 스트림 이라고 부른다.
스트림은 토픽의 데이터를 뜻하는데 프로듀서와 컨슈머에서 활용했던 레코드와 동일하다.
프로세서에는 소스 프로세서, 스트림 프로세서, 싱크 프로세서 3가지가 있다.
- 소스 프로세서
- 데이터를 처리하기 위해 최초로 선언해야 하는 노드
- 하나 이상의 토픽에서 데이터를 가져오는 역할
- 스트림 프로세서
- 다른 프로세서가 반환한 데이터를 처리하는 역할
- 변환, 분기 처리와 같은 로직이 데이터 처리의 일종
- 싱크 프로세서
- 데이터를 특정 카프카 토픽으로 저장하는 역할
- 스트림즈로 처리된 데이터의 최종 종착지
스트림즈을 구현하는 2가지 방법
1. 스트림즈 DSL (Domain Specific Language)
스트림즈 DSL로 구현하는 데이터 처리 예시
- 메시지 값을 기반으로 토픽 분기처리
- 지난 10분간 들어온 데이터의 개수 집계
- 토픽과 다른 토픽의 결합으로 새로운 데이터 생성
스트림즈 DSL에서 다루는 개념들
레코드의 흐름을 추상화한 3가지 개념
- KStream
- KTable
- GlobalKTable
상대적으로 이해하기 쉬운 데이터의 흐름인 KStream, KTable의 경우를 개략적으로 표현하면 아래 그림과 같습니다.
- KStreamKStream으로 데이터를 조회하면 토픽에 존재하는 (또는 KStream에 존재하는) 모든 레코드가 출력된다.
- KStream은 컨슈머로 토픽을 구독하는 것과 동일한 선상에서 사용하는 것.
- 레코드의 흐름을 표현한 것으로 메시지 키와 메시지 값으로 구성되어 있다.
- KTableKStream은 토픽의 모든 레코드를 조회할 수 있지만 KTable은 유니크한 메시지 키를 기준으로 가장 최신 레코드를 사용한다.
- 새로 데이터를 적재할 때 동일한 메시지 키가 있는경우 데이터는 최신 데이터로 업데이트 된다.
- KStream과 다르게 메시지 키를 기준으로 묶어서 사용
GlobalKTable
- 그러나, KTable로 선언된 토픽은 1개 파티션이 1개 태스크에 할당되어 사용.
- GlobalKTable로 선언된 토픽은 모든 파티션 데이터가 각 태스크에 할당되어 사용
이를 설명하는 가장 좋은 예 : KStream, KTable 데이터를 조인
코파티셔닝 ❓
- 조인을 하는 2개의 데이터의 파티션 개수가 동일하고 파티셔닝 전략을 동일하게 맞추는 작업
- 문제는 조인을 하려는 토픽들이 코파티셔닝이 되어 있음을 보장할 수 없다.
- TopologyException 발생
- 파티션 개수가 동일하고 파티셔닝 전략이 같은 경우 동일한 메시지 키를 가진 데이터가 동일한 태스크에 들어가는 것을 보장한다.
- KStream과 KTable을 조인하려면 반드시 코파티셔닝(co-partitioning) 되어 있어야 한다.
- KTable과 동일하게 메시지 키를 기준으로 묶어서 사용
코파티셔닝이 되어 있지 않으면 KStream 또는 KTable을 리파티셔닝(repartitioning)하는 과정을 거쳐야 한다.
리파티셔닝 ❓
- 새로운 토픽에 새로운 메시지 키를 가지도록 재배열하는 과정
- 리파티셔닝을 하는 과정은 토픽에 기존 데이터를 중복해서 생성할 뿐 아니라 파티션을 재배열하기 위해 프로세싱하는 과정도 거쳐야 한다.
이렇게 KStream과 KTable이 코파티셔닝 되지 않았을 때 조인해서 사용하고자 한다면 KTable을 GlobalKTable로 선언하여 사용하면 된다.
- GlobalKTable은 코파티셔닝 되지 않은 KStream과 데이터 조인을 할 수 있다.
이유
- KTable과 다르게 GlobalKTable로 정의된 데이터는 스트림즈 애플리케이션의 모든 태스크에 동일하게 공유되어 사용되기 때문
단점
- GlobalKTable을 사용하면 각 태스크마다 GlobalKTable로 정의된 모든 데이터를 저장하고 사용하기 때문에
- 스트림즈 애플리케이션의 로컬 스토리지의 사용량이 증가
- 네트워크, 브로커에 부하가 생김
따라서, 되도록 작은 용량의 데이터일 경우에만 사용하는 것이 좋다.
많은 양의 데이터를 가진 토픽으로 조인할 경우에는 리파티셔닝을 통해 KTable을 사용하는것이 더 좋다.
2. 프로세서 API
프로세서 API로 구현하는 데이터 처리 예시
- 메시지 값의 종류에 따라 토픽을 가변적으로 전송
- 일정한 시간 간격으로 데이터 처리
💡 프로세서 API는 스트림즈 DSL보다 투박한 코드를 가지지만 토폴로지를 기준으로 데이터를 처리한다는 관점에서는 동일한 역할을 한다.
스트림즈DSL은 데이터 처리, 분기, 조인을 위한 다양한 메서드들을 제공하지만 추가적인 상세 로직의 구현이 필요하다면 프로세서 API를 활용할 수 있다.
프로세서 API에는 KStream, KTable, GlobalKTable 개념이 없다.
Kafka 스트림즈 구현
2022.09.18 - [분류 전체보기] - Kafka 스트림즈 구현
참고
'📕 book > 아파치 카프카' 카테고리의 다른 글
4장. 카프카 상세 개념 - 토픽과 파티션 (0) 2023.01.17 2장 - 카프카 빠르게 시작해보기 (0) 2023.01.12 Kafka 스트림즈 구현 (0) 2022.09.18 3장 - 카프카 기본 개념 (0) 2022.09.18 1장 - 들어가며 (0) 2022.09.18