🔥 Kinesis란 무엇인가 — 스트림 데이터의 시간 축

1034자
13분

끝없이 도착하는 click·log·sensor 이벤트가 시간 축을 따라 Amazon Kinesis 박스로 들어가고, 거기서 Amazon Data Firehose, Managed Service for Apache Flink, KCL 직접 소비라는 세 갈래로 갈라져 나오는 도식

SQS와 SNS를 먼저 보고 나니 비동기 도구는 거의 다 봤다고 생각했다. 그런데 클릭 로그나 센서 이벤트를 붙잡는 순간부터는 질문을 바꿔야 했다. 메시지 하나를 처리하고 끝내면 되는지, 시간 순서대로 쌓이는 기록을 계속 읽어야 하는지부터 나눠서 봐야 했다.

Kinesis는 뒤쪽 질문에 답하는 제품군이다. 큐는 누가 언제 일을 가져갈지에 초점이 있고, 스트림은 같은 데이터를 얼마나 오래 보관하고 여러 소비자가 각자 어디까지 읽었는지에 초점이 있다. 이 차이를 먼저 잡아야 Kinesis 안의 서비스가 왜 여러 개로 나뉘는지 설명할 수 있다.

스트림 데이터와 시간 축

AWS는 Kinesis Data Streams를 실시간으로 쓰고 읽는 순서 있는 데이터 레코드의 흐름으로 설명한다(Kinesis Data Streams 개요, 용어와 개념).

중요한 점은 데이터가 들어오자마자 바로 사라지지 않는다는 데 있다. 기본 보존 기간은 24시간이고 더 길게 늘릴 수도 있어서, 소비자는 같은 이벤트를 나중에 다시 읽을 수 있다(retention period 문서). Kinesis Data Streams는 처리 대상인 이벤트를 일정 시간 그대로 보관한다.

SQS는 다른 질문에 답한다. 메시지를 받으면 그 메시지는 다른 소비자에게 잠시 보이지 않고, 처리가 끝나면 삭제한다. 삭제하지 못하면 visibility timeout 뒤에 다시 보인다(SQS visibility timeout 문서). 큐의 기본 단위는 작업이다. 반면 Kinesis Data Streams의 기본 단위는 시간 순서대로 도착하는 이벤트다. 같은 클릭 이벤트라도 큐에서는 누가 처리할지 먼저 묻고, 스트림에서는 누가 어느 시점부터 읽을지 먼저 묻는다.

이 차이는 소비 방식에서도 드러난다. Kinesis Data Streams에는 한 스트림을 여러 애플리케이션이 독립적으로 동시에 읽을 수 있다는 설명이 문서에 바로 나온다(consumer 문서). 어디까지 읽었는지를 따라가는 책임은 소비자 쪽으로 넘어온다. AWS가 권장하는 Kinesis Client Library는 진행 위치를 DynamoDB 테이블에 체크포인트로 기록한다(KCL 문서). 또 순서 보장의 단위는 스트림 전체가 아니라 샤드 하나다. Kinesis는 같은 파티션 키를 가진 레코드를 같은 샤드로 라우팅하므로, 같은 키끼리만 시간 순서를 가져간다고 보면 된다(용어와 개념). 그래서 스트림은 한 번 꺼내고 지우는 큐보다, 같은 이벤트를 여러 소비자가 각자 속도로 읽는 구조에 가깝다.

Consumer A·B·C 세 명이 같은 shard 위 event 시퀀스의 서로 다른 위치를 가리키고, 각자의 sequence number(124·089·156)가 오른쪽 DynamoDB lease & checkpoint 테이블 세 행에 기록되는 KCL 체크포인트 구조 도식

왼쪽 SQS 큐 패널은 메시지 다섯 개가 위에서 아래로 쌓여 있고 첫 메시지가 점선으로 지워지면서 consumer 한 명에게 전달되는 모습으로 소비 후 삭제 모델을 보여주고, 오른쪽 KDS 패널은 시간 축 위에 일곱 개 event 가 한 shard 띠 안에 줄지어 있고 consumer A·B·C 세 명이 각자 다른 위치를 가리키며 독립 read position 을 보여주는 비교 도식

Kinesis라는 이름의 제품군

Kinesis는 단일 서비스 이름이 아니라 묶음 이름이다. AWS 문서는 Kinesis Data Streams를 Kinesis 플랫폼의 한 축으로 설명하고, 같은 계열에 Amazon Data Firehose, Managed Service for Apache Flink, Kinesis Video Streams를 함께 둔다(Kinesis Data Streams 개요). 먼저 셋의 역할 경계를 정리해 둔다. Data Streams는 원본 이벤트를 받아 보존하는 스트림이고, Amazon Data Firehose는 그 데이터를 저장소로 밀어 넣는 전달 파이프이며, Managed Service for Apache Flink는 스트림 위에서 집계와 변환을 돌리는 처리 계층이다.

최근 몇 년 사이에 AWS는 이름을 정리했다. Amazon Data Firehose는 2024년 2월 9일에 Amazon Kinesis Data Firehose에서 지금 이름으로 바뀌었다(문서 이력). Amazon Managed Service for Apache Flink는 2023년 8월 30일에 Amazon Kinesis Data Analytics에서 이름이 바뀌었고, AWS는 이 변경을 콘솔과 문서, 서비스 웹 페이지에 반영했다고 공지했다(AWS What's New).

이름이 바뀌었다고 역할까지 바뀐 것은 아니다. Data Firehose는 여전히 S3, Redshift, OpenSearch, HTTP 엔드포인트 같은 목적지로 보내는 서비스다(Amazon Data Firehose 소개). Managed Service for Apache Flink는 SQL이나 Java, Python, Scala로 스트림을 처리하는 서비스다(Managed Service for Apache Flink 소개).

Kinesis Video Streams는 같은 이름 아래 있지만 이번 범위는 아니다. 이 서비스는 라이브 비디오와 미디어 데이터를 클라우드로 보내고 처리하는 용도다(Kinesis Video Streams 소개). 지금은 텍스트와 이벤트 스트림을 다루는 앞의 셋만 붙들면 충분하다.

Producer 가 Kinesis Data Streams 로 이벤트를 보내고, KDS 박스에서 Amazon Data Firehose(2024 리브랜딩, S3·Redshift·OpenSearch 적재) / Managed Service for Apache Flink(2023 리브랜딩, SQL·Java·Python·Scala) / Direct consumer(KCL on EC2·Lambda) 세 갈래로 나뉘고, Kinesis Video Streams 가 별도의 out-of-scope 박스로 따로 떨어진 4단계 파이프라인 도식

셋이 한 파이프에서 어떻게 이어지는가

세 서비스는 한 이벤트를 두고 서로 다른 역할을 맡는다. 모바일 앱 클릭 이벤트를 예로 들면 경계가 분명하다. 앱은 이벤트를 Kinesis Data Streams로 보낸다. 여기서는 원본 이벤트를 시간 순서대로 받아 두고, 샤드 단위로 읽기와 쓰기 한도를 관리한다. 이 단계의 관심사는 저장소 포맷이 아니라 이벤트를 잃지 않고 여러 소비자가 다시 읽을 수 있게 두는 일이다.

Amazon Data Firehose는 같은 스트림을 읽어 S3에 적재한다. Firehose 문서는 버퍼링 뒤에 S3 객체로 전달하고, 목적지에 따라 Redshift 적재나 OpenSearch 색인 같은 다음 동작을 이어 간다고 설명한다(data delivery 문서). 이 갈래는 분석 전에 원본을 그대로 쌓아 두는 단계에 적합하다. 나중에 Athena로 다시 보거나 배치 파이프를 따로 붙일 수 있기 때문이다.

Managed Service for Apache Flink는 같은 스트림을 읽어 실시간 집계를 만든다. AWS 문서도 Flink 애플리케이션이 Kinesis 스트림을 입력으로 받아 집계나 이상 탐지 같은 처리를 하고, 결과를 다른 Kinesis 스트림이나 Firehose, Lambda로 보낼 수 있다고 설명한다(Kinesis와 Flink 연동 문서). 같은 클릭 이벤트라도 하나는 원본 보관으로 가고, 다른 하나는 1분 단위 클릭 수 집계로 간다. Data Streams는 원본 스트림을 맡고, Firehose는 적재를 맡고, Flink는 실시간 처리를 맡는다.

Mobile app 의 click event 가 Kinesis Data Streams 로 들어간 다음 위쪽으로는 Amazon Data Firehose 를 거쳐 S3 raw events archive 로 적재되고 Athena 배치 쿼리로 이어지며, 아래쪽으로는 Managed Service for Apache Flink 가 1분 단위 집계로 real-time clicks per minute 대시보드를 만드는 두 갈래 파이프라인 sequence 도식

언제 Kinesis를 쓰지 말아야 하는가

처리량이 작고 메시지 하나가 작업 하나인 경우에는 SQS가 더 단순하다. 재생과 다중 소비보다 작업 완료와 재시도가 더 중요하다면 큐 모델이 맞다. 반대로 같은 사실을 여러 구독자에게 알려야 할 뿐이라면 SNS가 더 짧은 경로를 준다. 이런 경우에는 스트림 보존까지 같이 가져올 필요가 없다.

보존과 재생이 필요 없고, 목적지가 사실상 하나뿐인 적재 경로라면 Amazon Data Firehose만으로 끝낼 수도 있다. 예를 들어 애플리케이션 로그를 거의 바로 S3에 쌓고 싶다면 Kinesis Data Streams를 앞에 두지 않아도 된다. KDS를 넣는 순간 읽기 위치, 샤드 운영, 소비자 수 같은 판단이 늘어난다. 그 비용을 감수할 이유가 없다면 더 단순한 구성을 택하는 편이 낫다.

최상위 질문 "이벤트 보존 + 다중 독립 소비자가 필요한가?" 에서 Yes 면 Kinesis Data Streams, No 면 다음 질문 "한 메시지 = 한 작업이고 재생 불필요?" 로 내려가 Yes 면 SQS, No 면 다시 "같은 사실을 broadcast?" 로 분기해 Yes 면 SNS, No 면 Amazon Data Firehose 단독으로 분기되는 결정 트리 + 오른쪽 4행 legend

이제 남는 질문은 하나다. 같은 스트림 안에서 어떤 이벤트가 어느 샤드로 들어가고, 그 선택이 순서와 처리량을 어떻게 바꾸는지다. 그 부분까지 따져야 Kinesis Data Streams가 어떻게 동작하는지 설명할 수 있다.

YouTube 영상

채널 보기
AI는 왜 수백 차원의 벡터를 사용할까? 고차원 공간과 행렬 | 선형대수학
AI 추천 시스템의 원리, 벡터 사이의 각도와 코사인 유사도 | 선형대수학
마지막편, 트라이 노드를 50% 이상 줄이는 방법? 압축 트라이 성능 분석 | Trie 자료구조 이야기
트라이(Trie)에서 단어를 삭제하는 방법 | Trie 자료구조 이야기
스칼라 곱셈과 내적의 기하학적 의미 | 선형대수학
숫자 하나가 AI 모델의 운명을 바꾼다? | 선형대수학
내적의 기하학적 의미와 코사인 유사도 원리 | 선형대수학
우리가 매일 쓰는 맞춤법 검사기와 라우터 속에 숨겨진 알고리즘은? | Trie 자료구조 이야기