스트림 처리란 무엇인가?#
- 데이터 스트림(이벤트 스트림, 스트리밍 데이터)이란 무한히 늘어나는 데이터세트를 추상한 것이다.
- 무한이라 함은 끝없이 계속해서 늘어난다는 의미이다. 시간이 흐름에 따라 새로운 레코드가계속해서 추가되기 때문에 데이터세트가 무한해지는 것이다.
- 데이터 스트림의 또 다른 특성
- 이벤트 스트림에는 순서가 있다.
- 데이터 레코드는 불변이다.
- 이벤트 스트림은 재생이 가능하다.
- 스트림 처리: 하나 이상의 이벤트 스트림을 계속해서 처리하는 것
- 스트림 처리는 요청-응답과 배치 처리와 마찬가지로 프로그래밍 패러다임 중 하나다.
- 요청-응답:
- 응답 시간이 1밀리초 미만~몇 밀리초 수준인 패러다임으로, 가장 지연이 적은 패러다임이다.
- 다만 처리 방식이 보통 블로킹 방식이라 애플리케이션이 요청을 보낸 뒤 처리 시스템이 응답을 보내 줄 때까지 대기하는 것이 보통이다.
- 배치 처리:
- 하루에 한 번 대량의 배치 단위로 적재되고, 리포트가 생성되고, 사용자들은 다음 번 데이터 적재가 일어날 때까지 똑같은 리포트를 보게 된다.
- 이 패러다임은 많은 경우 효율성이 높고 규모의 경제를 달성할 수 있다는 장점이 있지만, 최근의 비즈니스는보다 시기적절하고 효율적인 의사 결정을 위해 더 짧은 시간 간격 안에 사용가능한 데이터를 필요로 한다.
- 스트림 처리:
- 연속적이고 논블로킹하게 방식하는 방식이다.
- 스트림 처리는 이벤츠 처리에 2 밀리초 정도 기다리는 응답-요청 방식과 하루 한 번 작업이 실행되고 완료하는 데 8시간이 걸리는 배치 처리 사이의 격차를 메워준다.
스트림 처리 개념#
토폴로지#
- 스트림 처리애플리케이션은 하나 이상의 처리 토폴로지를 포함한다.
- 하나의 처리 토폴로지는 하나 이상의 소스 스트림, 스트림 프로세서의 그래프, 하나 이상의 싱크 스트림이 서로 연결된 것이다.
- 하나 이상의 소스 스트림에서 시작된 이벤트 스트림은 연결된 스트림 프로세서들을 거쳐가면서 처리되다가 마지막에는 하나의 싱스 스트림에 결과를 쓰는 것으로 끝나게 된다.
- 각각의 스트림 프로세서는 이벤트를 변환하기 위해 이벤트 스트림에 가해지는 연산단계라고 할 수 있다.
- 스트림 프로세서의 예:
filter
, count
, group by
, left join
- 스트림 처리의 맥락에서, 대부분의 스트림 애플리케이션이 시간 윈도우에 대해 작업을 수행하는 만큼 시간에 대해 공통적인 개념을 가지는 것이 중요하다.
- 스트림 처리 시스템은 보통 다음과 같으 개념들을 사용한다.
- 이벤트 시간: 다루고자 하는 이벤트가 발생하여 레코드가 생성된 시점
- 로그 추가 시간: 이벤트가 브로커에 전달되어 저장된 시점이며, 접수 시간이라고도 불린다.
- 스트림 처리에서는 이벤트가 발생한 시간이 관심사이기 때문에, 이 시간 개념은 덜중요하다.
- 처리 시간: 스트림 처리 애플리케이션이 뭔가 연산을 수행하기 위해 이벤트를 받은 시간
- 이벤트가 발생한 뒤 몇 밀리초, 몇 시간, 며칠 뒤일 수도 있다.
- 동일한 이벤트라고 하더라도 정확히 언제 스트림 처리 애플리케이션이 이벤트를 읽었느냐에 따라서 전혀 다른 타임스탬프가 주어질 수 있다.
- 카프카 스트림즈는
TimestampExtractor
인터페이스를 사용해서 각각의 이벤트에 시간을 부여한다. - 카프카 스트림즈가 결과물을 카프카 토픽을 쓸때, 다음과 같은 규칙에 따라서 이벤트에 타임스탬프를 부여한다.
- 결과 레코드가 입력으로 주어진 레코드에 직접 대응될 경우, 결과 레코드는 입력 레코드와 동일한 타임스탬프를 사용한다.
- 결과 레코드가 집계 연산의 결과물일 경우 ,집계에 사용된 레코드 타임스탬프의 최대값을 결과 레코드의 타임스탬프로 사용한다.
- 결과 레코드가 두 스트림을 조인한 결과물일 경우, 조인된 두 레코드 타임스탬프 중 큰 쪽의 결과 레코드의 타임스탬프로 사용한다. 스트림과 테이블을 조인한 경우, 스트림 레코드 쪽의 타임스탬프가 사용된다.
- 마지막으로,
punctuate()
와 같이 입력과 상관없이 특정한 스케줄에 따라 데이터를 생성하는 카프카 스트림즈 함수에 의해 생성된 결과 레코드의 경우, 타임스탬프 값은 스트림 처리 애플리케이션의 현재 내부 시각에 따라 결정된다.
- 지금 한 시간 동안 발생한 타입별 이벤트 수나 조인, 합계 평균을 계산해야 하는 모든 이벤트 등 더 많은 정보를 추적 관리해야 하는 것이다. 우리는 이러한 정보를 상태라 부른다.
- 스트림 처리 애플리케이션의 로컬 변수에 상태를 저장하면, 스트림 처리 애플리케이션이 저장하거나 크래시 날 경우 상태가 유실되고 결과가 달라지기 때문에 스트림 처리에서 상태를 관리하는 방법으로서는 신뢰성이 떨어진다.
- 로컬 혹은 내부 상태
- 스트림 처리 애플리케이션의 특정 인스턴스에서만 사용할 수 있는 상태.
- 이 상태는 대개 애플리케이션에 포함되어 구동되는 인메모리 데이터베이스를 사용해서 유지 관리된다.
- 장점: 엄청나게 빠르다.
- 단점: 사용 가능한 메모리 크기의 제한을 받는다.
- 스트림 처리의 많은 디자인 패턴들은 데이터를 분할해서 한정된 크기의 로컬 상태를 처리 가능한 서브스트림으로 만드는데 초점을 둔다.
- 외부 상태
- 카산드라와 같은 NoSQL 시스템을 사용해서 저장된다.
- 장점: 사실상 크기에 제한이 없을 뿐더러 여러 애플리케이션 인스턴스, 심지어 다른 애플리케잇녀에서도 접근이 가능하다.
- 단점: 다른 시스템을 추가하는 데 따른 지연 증가, 복잡도 증가, 가용성 문제가 발생할 수 있다.
- 많은 스트림 처리 애플리케이션은 외부 저장소를 사용하는 피하거나 내용물을 로컬 상태에 캐싱함으로써 외부 저장소와 가능한한 통신하지 않게 함으로써 지연 부담을 최소화한다.
스트림-테이블 이원성#
- 스트림은 변경을 유발하는 이벤트의 연속이다. 테이블은 여러 상태 변경의 결과물인 현재 상태를 저장한다.
- 데이터를 바라보는 두 가지 관점을 오갈 수 있는 시스템은 한쪽으로만 가능한 시스템보다 더 강력하다.
- 테이블을 스트림으로 변환하기 위해서는 테이블을 수정한 변경 내역을 잡아내야 한다.
- 모든 추가, 변경, 삭제 이벤트를 가져와서 스트림에 저장하면 된다.
- 많은 데이터베이스에서는 이러한 변경점을 잡아내기 위한 CDC 솔루션을 제공하며, 이러한 변경점을 스트림 처리에서 활용할수 있도록 카프카로 전달해 줄 수 있는 카프카 커넥터가 많이 있다.
- 스트림을 테이블로 변환하기 위해서는 스트림에 포함된 모든 변경 사항을 테이블에 적용해야 한다.
- 이러한 작업을 두고 “스트림을 구체화(materilize)한다.“고도 한다.
- 메모리든 내부 상태 저장소든 외부 데이터베이스든 테이블을 생성한 뒤 스트림에 포함된 이벤트를 처음부터 끝까지 모두 읽어서 상태를 변경한다. 이 작업이 끝나면 특정 시점의 상태를 나타내는 테이블을 얻을 수 있다.
시간 윈도우#
- 대부분의 스트림 작업은 시간을 윈도우라 불리는 구간 단위로 잘라서 처리한다.
- 예시: 이동 평균을 계산하거나, 이번 주 가장 많이 팔린 상품을 계산하거나, 시스템의 99분위 부하를 찾아내는 식이다.
- 시간 윈도우 고려사항
- 윈도우 크기: 윈도우 크기가 커질수록 랙이 커진다.
- 시간 윈도우의 진행 간격:
- 호핑 윈도우: 윈도우의 크기와 윈도우 사이의 고정된 시각 간격이 같은 경우
- 텀블링 윈도우: 진행 간격과 윈도우 크기가 같은 경우

- 윈도우를 업데이트할 수 있는 시간
- 이벤트가 이벤트에 해당하는 윈도우에 추가될 수 있는 시간을 정의할 수 있다는 것이 이상적일 것이다.
- 예시: 이벤트가 최대 4시간까지 지연될 수 있다면 겨로가는 다시 계산되고 업데이트해줘야 할 것이다.
- 만약 이벤트가 그 이상으로 지연된다면, 무시하면 된다.
처리 보장#
- 스트림 처리 애플리케이션에 있어서 핵심적인 요구 조건 중 하나는 장애가 발생했을 경우에도 각각의 레코드를 한 번만 처리할 수 있는 능력이다.
- ‘정확히 한 번’ 보장이 없는 경우 스트림 처리는 정확한 결과가 요구되는 상황에서 사용될 수 없다.
- 카프카 스트림즈 라이브러리를 사용하는 모든 애플리케이션은
processing.guarantee
설정을 extactly_once
로 잡으줌으로써 정확히 한 번 보장 기능을 활성화시킬 수 있다.- 카프카 스트림즈 2.5 버전 이후에는 좀 더 효율적인 정확히 한 번 구현체를 포함되어서
exactly_once_beta
로 활서오하 시킬 수 있다. - 카프카 스트림즈 3.0 버전 이후에는 다시 한 번 개선되면서
exactly_once_v2
를 사용할 것을 권장한다.
comments powered by