카프카 스트림즈 기초개념

2021-06-17

.

Data_Engineering_TIL(20210617)

[학습자료]

youtube ‘데브원영 DVWY’ 채널의 ‘카프카 스트림즈! 대용량, 폭발적인 성능의 실시간 데이터 처리!’ 영상을 공부하고 정리한 내용입니다.

URL : https://www.youtube.com/watch?v=vKxhPUUEDmM

[학습내용]

  • 개요

카프카 스트림즈는 실시간으로 끊임없이 발생하는 데이터 처리할 수 있는 플랫폼이다.

카프카는 분산 이벤트 스트리밍 플랫폼으로써 프류듀서와 컨슈머를 사용해서 데이터를 보내고 가져와서 처리할 수 있다. 자바, 고랭, 파이썬과 같은 언어를 사용해서 커스텀하게 프로듀서와 컨슈머를 개발 할 수 있다.

예를 들어서 컨슈머를 개발해서 대규모 데이터 파이프라인을 만들고 운영할 수 있다. 그런데 컨슈머를 사용해서 데이터를 처리하는 것보다 더 안전하고 빠르면서 다양한 기능을 사용할 수 있는 기술이 있는데 이게 카프카 스트림즈이다.

카프카 스트림즈는 카프카에서 공식적으로 제공하는 자바 라이브러리다. 토픽에 있는 데이터를 낮은 지연과 함께 빠른속도로 데이터를 처리할 수 있다. 카프카 스트림즈는 라이브러리로 제공되기 때문에 사용자는 자바나 스칼라, 코틀린과 같은 JVM 기반 언어중에 하나를 선택해서 개발하면 된다. 그리고 스트링부트에 업로드해도 되고, 순수 자바앱에 라이브러리를 추가시켜서 동작하게 배포할수도 있다.

  • 카프카 스트림즈의 장점

1) 카프카와 완벽 호환

일반적인 케이스로는 카프카를 이벤트 저장소로 사용하고 저장된 데이터를 spark 또는 logstash와 같은 tool로 연동한다. 이런 외부 오픈소스툴의 문제는 빠르게 출시되는 오픈소스 카프카 버전을 따라가지 못한다는 점이다. 반면에 카프카 스트림즈는 매번 카프카 신버전이 릴리즈 될때마다 카프카 클러스터와 완벽하게 호환되면서 최신의 기능들을 가지게 된다. 그래서 카프카의 보안기능이나 ACL(접근제어목록) 같은게 붙어 있더라도 완벽하게 호환되어 처리할 수 있고, 성능개선도 빠르게 이루어지고 있다고 볼 수 있다. 그리고 무엇보다도 유실이나 중복 처리되지 않고, 딱 한번만 처리할 수 있는 아주 강력한 기능을 가지도 있다. 카프카와 연동하는 이벤트 프로세싱 툴중에 거의 유일하다고 할 수 있다. 그래서 카프카를 사용하고 있고, 데이터를 안전하고 빠르게 처리하고 싶다면 스트림즈를 1순위로 고려해야 한다.

2) 스케쥴링 툴이 필요없다.

카프카와 연동하는 스트림 프로세싱 툴로 가장많이 그리고 널리 사용하는 것이 spark stream이다. spark stream 또는 spark structured streaming을 사용하면 카프카와 연동하여 마이크로 배치처리를 하는 이벤트 데이터 app을 만들 수 있다. 그런데 문제는 spark를 운영하기 위해서는 yarn이나 mesos와 같이 cluster manager 또는 resource manager 같은 것이 필요하다. 그리고 클러스터를 운영하기 위해 대규모 장비들도 구축해야 한다. 반면에 스트림즈를 사용하면 스케쥴링 툴은 전혀 필요가 없다. 사용자가 만든 스트림즈 어플리케이션은 컨슈머 어플리케이션이나 WAS 어플리케이션을 배포하는것처럼 원하는 만큼 배포하면 된다. 만약에 적은양의 데이터를 처리해야 한다면 2개정도의 스트림즈 어플리케이션을 띄워서 운영하면 되고, 데이터를 많이 처리해야 한다면 스케일 아웃해서 10개 또는 20개 어플리케이션을 배포하면 된다.

3) 스트림즈 DSL과 프로세서 API를 제공

스트림즈를 구현하는 방법은 두가지가 있다. 대부분의 경우에는 스트림즈 DSL를 이용해서 구현한다. 스트림즈 DSL은 이벤트 기반 데이터를 처리할때 필요한 map, join, window와 같은 다양한 메서드들을 제공하기 때문에 편리하다. 만약에 스트림즈 DSL에 없는 기능이 있다면 프로세서 API를 사용해서 로직을 작성하면 된다. 대부분의 기능은 이미 스트림즈 DSL에 있어서 프로세서 API를 거의 쓸일은 없을 것이다. 그만큼 스트림즈 DSL이 많은 기능을 갖고 있다. 그리고 스트림즈 DSL만이 제공하는 KStream, KTable, GlobalKTable은 독특한 스트림 처리 개념인데 스트림 데이터 처리 뿐만 아니라 대규모 key-value 저장소로도 사용할 수 있는 기능을 갖고 있다.

4) 자체적인 로컬 상태저장소를 사용한다.

실시간으로 들어오는 데이터를 처리하는 방식은 크게 두가지 방식이 있다. 첫번째는 비상태기반 처리, 두번째는 상태기반 처리이다. stateless라고 불리는 비상태기반 처리는 필터링이나 데이터를 변환하는 처리이다. 이런 비상태기반 처리는 데이터가 들어오는 족족 바로 처리하고 프로듀스하면 되기 때문에 유실이나 중복이 발생할 염려가 적고, 쉽게 개발할 수 있다. 반면에 상태기반 처리를 직접 구현하는 것은 매우 어렵다. 왜냐하면 window, join, aggregation과 같은 처리는 이전에 받았던 데이터를 프로세스가 메모리에 저장하고 있으면서 다음 데이터를 참조해서 처리해야 한다. 그래서 이런 상태기반 분산 프로세스를 구현하는 것은 매우 어렵다. 이런 어려움을 극복하기 위해 도와주는 것이 카프카 스트림즈이다. 카프카 스트림즈는 이런 어려운 처리를 돕기 위해 로컬에 rocksdb라는 것을 사용해서 상태를 저장하고, 이 상태에 대한 변환정보는 카프카의 변경로그(changelog) 토픽에 저장한다. 그래서 카프카 스트림즈를 사용하면 프로세스에 장애가 발생하더라도 그 상태는 모두 안전하게 디비에 저장되어 있기 때문에 장애 복구에 용이하다.

  • 예시 코드

아래의 코드는 payment 토픽에 메세지 키가 “unknown” 인 데이터를 필터링해서 “unknown-payment” 토픽으로 보내는 스트림즈 코드이다. 기존에 사용자가 컨슈머로 폴링하거나 프로듀서를 어렵게 구현할 필요가 없다. 이렇게 스트림즈 DSL이 제공하는 이벤트 기반 메서드를 사용하면 쉽게 구현할 수 있다.

KStream<String, String> paymentStream = builder.stream("payment");
KStream<String, String> filteredStream = paymentStream.filter((key,value) -> key.equals("unknown"));
filteredStream.to("unknown-payment");