1. 스파크 스트리밍
•
스파크 코어 엔진의 분산처리 기능 위에 구축된 최초의 스트림 처리 프레임워크
•
스파크 스트리밍을 통해 실시간으로 데이터 소스(Kafka, HDFS 등)로부터 스트리밍 데이터를 받아 처리할 수 있음
•
연속적인 데이터 스트림을 스파크가 작동할 수 있는 개별 데이터 컬렉션으로 변환
1.1 스파크 스트림 특징
1.
Event Driven
→ 특정 이벤트 기준으로 범위를 설정하여, 해당 구간의 데이터를 분석하고 도출함
2.
짧은 대기 시간(Low Latency)
→ 분, 초, ms 단위로 빠르게 응답해야 할 경우에 유용함. (결과를 수정할 때 배치 처리보다 효율적)
예) 지난 24시간의 웹 트래픽 통계 계산한다고 가정해보자.
•
단순히 구현된 배치 처리를 사용하면 → 실행할 때마다 전체 데이터 계산해야 함 (효율성 Bad)
•
스트리밍 API 활용 → 지난 번 Window의 연산 결과를 기억하며, 현재 Window의 연산 결과만 따로 추가하여 간단하게 계산 가능 (효율성 Good)
1.2 스트림 처리 vs 배치 처리
1.
스트림 처리란? : 무한 데이터(unbounded data)로부터 정보를 추출하는데 사용하는 규율 및 관련 기술의 집합
→ 데이터가 생성되는 즉시 연속 스트림을 처리하는 것
→ 데이터의 크기를 알 수 없으며, 그 범위가 무한하고 연속적일 때 사용
ex) 모바일 디바이스에서 로그, sns 타임 피드, 증권 거래 주문 같이 실시간으로 계속
들어와서 쌓이는 데이터
→ 실시간이란 상대적인 개념이기 때문에 요건에 따라 실시간의 범위가 다르게 정의됨
2.
배치 처리란? : 특정 시간 범위 내에서 대량의 데이터를 일괄 처리하는 것
→ 데이터 크기가 알려져 있는 유한 데이터를 처리 할 때 사용
→ 시간이 지남에 따라 데이터가 수집되고 유사한 데이터가 일괄 처리/그룹화 되면 처리
스트림 처리 | 배치 처리 | |
데이터 범위 | 롤링 타임 윈도우 내 데이터 또는 가장 최신 데이터 레코드의 데이터를 처리 | 데이터 세트의 모든 또는 대부분의 데이터를 처리 |
데이터 크기 | 일부 레코드로 구성된 마이크로 배치 또는 개별 레코드 | 대규모 데이터 배치 |
성능 | 몇 초 또는 몇 밀리 초 지연 시간 소요 | 지연 시간 몇 분에서 몇 시간 |
분석 | 간단한 응답 가능, 수집 및 롤링 지표 | 복잡한 분석 |
장점 | - 이상징후와 문제를 신속하게 감지
- 데이터를 실시간으로 처리하여 빠른 의사 결정을 가능하게 함 | - 직관적, 유지보수와 개발이 비교적 단순
- 대용량 데이터를 효율적으로 처리 |
1.3 스파크 스트림 아키텍쳐
스파크는 배치 처리를 지향하는 프레임워크로, 스트리밍 데이터를 처리하기 위해 배치 처리 기능을 스트리밍 데이터에 적용하는 마이크로 배치 아키텍쳐를 사용
스파크 스트리밍 연속형 처리 vs 마이크로 배치 처리
1.
연속형 처리란?
: 시스템을 구성하는 각 노드는 다른 노드에서 전송하는 메시지를 끊임없이 수신하고 새로 갱신된 정보를 자신의 하위 노드로 전송하여 처리
•
각 노드가 신규 메시지에 즉시 반응하며, 전체 입력량이 비교적 적을 때 가장 빠르게 응답.
•
레코드 단위 부하가 매우 크기 때문에, 최대 처리량이 적음.
•
고정형 연산 토폴로지(컴퓨터 네트워크 요소를 물리적으로 연결하는 방식)를 사용하므로, 전체 시스템을 중지해야 애플리케이션을 변경할 수 있다.
2.
마이크로 배치 처리란? : 입력 데이터를 작은 배치로 모으고 다수의 분산 태스크를 이용해 각 배치를 병렬로 처리
•
입력 데이터를 작은 배치로 모으기 위해 대기시간을 가진 뒤, 각 시간대 별 배치를 일반적인 배치처리 형태로 병렬 처리하여 결과를 출력
•
특정 시간 간격 내에 유입된 데이터 블록을 끊어 RDD로 구성하고 아주 짧은 주기로 배치처리를 진행
RDD(Resilient Distributed Dataset) 스파크의 기본 데이터셋 추상화 객체로 메모리 내부에서 데이터가 손실 되었을 때 유실된 파티션을 재연산해 복구할 수 있는 형태로 구성되어 있음. 또한, 스파크 클러스터를 통해 메모리에 데이터를 분산 저장
•
노드당 처리량이 연속형 처리보다 높음
•
마이크로 배치를 모으기 위한 기본적인 지연 시간 발생
지연 시간 요건과 총 운영 비용 고려하여 처리 방식 선택
연속형 처리 방식 | 마이크로 배치 처리 방식 |
더 빠른 응답시간을 원하는 경우 | 운영비용을 줄이려고 하는 경우
(더 적은 노드 수로 동일한 처리량을 원하는 경우) |
2. Spark Streaming API
•
스파크 스트리밍은 실시간 데이터 분석을 위한 스파크 컴포넌트로, 데이터는 카프카, 키네시스, TCP 소켓 등 다양한 경로를 통해서 입력받고, map, reduce, window 등의 연산을 통해 데이터를 분석한 결과를 최종 파일 시스템, 데이터베이스에 적재하는 시스템
•
스파크는 두 가지 스트리밍 API를 제공
1.
DStream API(Spark Streaming)
2.
구조적 스트리밍 API(Spark Structured Streaming)
2.1 DStream (1)
•
DStream API는 실시간으로 데이터 스트림에서 발생하는 데이터를 디스트림(Dstream, discretized steam)이라고 불리는 추상화 개념의 작은 배치 단위로 나누고, 스파크 엔진으로 분석
→ 짧은 주기의 마이크로 배치 처리를 통해 실시간 처리를 수행
•
스파크에 레코드가 도착한 타임 스탬프 기반 데이터 처리를 진행
2.1.1 DStream (2)
Dstream은 플럼(Flume), 카프카(Kafka), HDFS등의 다양한 소스로부터 시간대 별로 도착한 데이터들의 연속적인 모임으로, 각 Dstream은 SparkContext에 의해 시간대 별 RDD들의 집합으로 구성됨
•
Dstream은 내부적으로 RDD의 연속적인 시퀀스로 표현
•
각 RDD는 배치 처리 간격 동안 수집된 이벤트를 나타냄
•
일반적으로 많이 사용됨(안정적), RDD 코드를 활용하여 정적 데이터와 조인 등의 기능 사용
예) Word Count : 0~ 1초까지의 시간에 들어온 라인의 개수를 Dstream의 데이터 추상화 객체에 담을 수 있고, 배정된 라인 하나하나를 각각의 RDD로 할당할 수 있음
•
많은 장점을 제공하는 구조적 테이블 개념의 DataFrame, Dataset과 달리 Java, Scala, Python 등의 객체와 함수에 매우 의존적 → 스트림 처리 엔진의 최적화 기법 적용하기 힘듬
•
처리 시간을 기준으로 동작함 → 이벤트 시간을 기준으로 처리하고 싶은 경우 자체 구현 필요
2.2 Structured Streaming (1)
•
Dstream API의 단점을 보완하기 위해 등장한 스파크 SQL 엔진 기반의 스트림 처리 프레임워크
•
DataFrame, Dataset, SQL과 같은 스파크의 구조적 API를 사용하는 고수준의 스트리밍
•
중복 데이터를 관리하기 위해 데이터 소스에서 레코드에 기록한 타임 스탬프 기반의 데이터 처리 방식
•
Dstream보다 최근에 도입 - Dstream과 달리 DataFrame 형태로 결과값이 도출되기 때문에 데이터 처리에 더 유용함
•
구조적 처리를 할 수 있는 모든 환경에서 Scala, Java, Python, R, SQL 등을 통해 사용 가능
2.2.1 Structured Streaming (2)
1.
스트림 데이터를 ‘데이터가 연속적으로 추가되는 테이블’처럼 다룸
•
데이터 스트림이 input 값으로 새로 추가될 때마다 Input Table의 하나의 row로 입력되고, 이러한 rows가 무한히 많이 추가될 수 있는 구조
•
미리 설정한 Trigger 조건이 충족 될 때 마다 Input Table을 정적인 Table로 간주하여 처리하고, 결과를 외부 싱크(외부 저장 장치)에 업데이트하는 방식
•
전체 테이블을 구체화하지 않고 사용 가능한 최신 데이터를 입력 받아 처리를 하며, 결과를 업데이트하는 데 필요한 최소 상태의 데이터만 유지
2.
사용자가 스트림 처리용 코드와 경로를 설정하면, 구조적 스트리밍 엔진에서 신규 데이터에 대한 증분 및 연속형 쿼리를 실행
→ 내부적으로 사용자의 쿼리를 어떻게 증분할 지 자동으로 파악하여 신규 데이터가 유입될 때 마다 효율적으로 처리 결과 갱신 및 내고장성 보장
※ 증분이란? → 연속되는 데이터 사본들 이전의 백업 복사본이 만들어진 이래로 변경된 부분만을 담은 것
※ 내고장성(Fault Tolerance)이란? → 시스템의 일부가 고장이 나도 전체에는 영향을 주지 않고, 항상 시스템의 정상 작동을 유지하는 능력 (SQL의 경우 쿼리 처리 중 발생하는 오류를 처리해 쿼리를 완료하는 기능)
3.
쿼리 실행 유형을 미리 지정하면, 배치 처리나 스트림 처리와 관련된 쿼리 구문을 변경하지 않아도 됨
2.2.2 입력 소스/싱크/출력 모드
1.
입력 소스: 입력 받는 소스 데이터의 정보
•
Apache Kafka
•
HDFS나 S3 등 분산 파일 시스템의 파일 (스파크는 디렉토리의 신규 파일을 계속 읽음)
•
테스트용 소켓 소스
•
테스트용 증분형 입력 소스(Rate Source)
2.
싱크: 스트림의 결과를 저장할 목적지 명시
•
파일 포맷
•
출력 레코드에 임의 연산 수행: foreach 싱크
•
테스트용 콘솔 싱크
•
디버깅용 메모리 싱크
3.
출력 모드: 데이터를 출력하는 방법 정의 (외부 스토리지에 기입 되는 것)
•
마지막 트리거 이후 신규 정보만 추가하려는 경우 - append(싱크에 신규 레코드만 추가)
•
바뀐 정보로 기존 row를 갱신 - update(변경 대상 레코드 자체를 갱신)
◦
예) 특정 웹페이지의 클릭 수 갱신
•
매번 전체 결과 덮어씀 - complete(전체 출력 내용 재작성)
◦
예) 모든 페이지의 전체 클릭 수 매번 파일로 기록
•
특정 쿼리와 싱크는 일부 출력 모드만 지원
2.2.3 트리거
•
스트리밍 데이터 처리 타이밍
•
데이터 출력 시점 정의(언제 신규 데이터를 확인하고 결과를 갱신할지 정의)
•
마지막 입력 데이터 처리한 후 신규 입력 데이터를 조회해 최단 시간 내에 새로운 처리 결과 생성
•
파일 싱크를 사용하는 경우 작은 크기의 파일이 여러 개 생성됨
3. 이벤트 시간 처리
•
이벤트가 생성된 시간을 기준으로 정보를 분석해 늦게 도착한 이벤트까지 처리
이벤트 시간 처리가 필요한 이유??
→ 컴퓨터 네트워크의 신뢰도는 낮으므로, 이벤트 전송은 성공하거나 실패할 수 있다. 원천 시스템에서 스트림 처리 시스템으로 전송되는 과정에서 어떤 상황도 벌어질 수 있다. 즉, 처리 시스템의 이벤트 순서는 이벤트 시간 순으로 정렬되어 있다고 보장할 수 없다.
3.1
이벤트 시간 vs 처리 시간
•
이벤트 시간(Event time): 현실 세계에서 이벤트가 실제로 발생한 시간
◦
데이터에 기록된 시간 필드
◦
데이터마다 이벤트 시간을 비교할 때, 지연되거나 무작위로 도착한 이벤트가 있으므로, 스트리밍 처리 시 이를 제어할 수 있어야 함
예) 웹 사이트에서 사용자 활동을 추적하는 시스템
•
처리 시간(Processing time): 시스템에서 이벤트 또는 레코드를 처리하는 시간
◦
시스템이 데이터를 수신하고 처리를 시작하는 시간 기준
◦
이벤트 시간처럼 외부 시스템에서 제공하는 것이 아니라, 스트리밍 시스템이 제공하는 속성이므로 순서가 뒤섞이지 않음
예) 일괄 처리 시스템에서 레코드의 처리 시간은 디스크에서 읽고 시스템에서 처리한 시간
•
◦
정확성: 이벤트 시간은 이벤트가 발생한 실제 시간을 반영하므로 ,데이터를 보다 정확하게 볼 수 있음. 반면에, 처리 시간은 데이터 처리가 지연되어 분석의 정확성에 영향을 줄 수 있음
◦
반복성: 이벤트 시간은 반복이 가능. 즉, 동일한 이벤트는 처리 시점에 관계없이 항상 동일한 타임스탬프를 가짐. 반면에, 처리 시간은 데이터가 실제로 시스템에서 처리되는 시기에 따라 달라지므로 반복할 수 없습니다.
◦
지연 데이터: 이벤트 시간은 순서가 맞지 않거나 지연되어 도착하는 데이터를 처리할 수 있음. 반면에, 처리 시간은 처리 시점에 사용 가능한 데이터에 의존하기 때문에 지연된 데이터를 처리할 수 없음
3.2 윈도우 연산
윈도우란?
→ 스트림 처리를 위해 데이터를 더 작고 유한한 집합으로 그룹화하는 방법. 윈도우는 정의된 시간 또는 이벤트 범위에 속하는 데이터의 특정 부분만 포함하는 전체 데이터 스트림의 하위 집합으로 생각할 수 있다.
•
텀블링 윈도우: 크기가 고정되고 겹치지 않는 윈도우. 데이터를 고정 기간의 겹치지 않는 동일한 크기의 창으로 분할합니다. 시작 및 종료 시간이 잘 정의되어 있고, 각 데이터 레코드가 다른 레코드와 독립적인 데이터를 분석하는 데 유용함
예) 5분의 텀블링 기간을 사용하는 경우, 데이터 스트림은 겹치지 않는 5분 기간으로 나누어짐
•
슬라이딩 윈도우: 고정된 크기의 겹치는 윈도우. 데이터를 동일한 크기의 고정 기간 동안 겹치는 창으로 분할합니다. 슬라이딩 윈도우는 연속 흐름이 있고, 각 데이터 레코드가 이전 및 미래 레코드에 의존하는 데이터를 분석하는 데 유용
예) 10분의 슬라이딩 윈도우와 5분의 슬라이드 간격을 사용하는 경우, 데이터 스트림은 5분이 겹치는 10분 기간으로 분할.
•
세션 윈도우: 특정 시간 간격 내에 발생하는 이벤트를 기반으로 데이터를 그룹화하는 동적 윈도우. 특정 비활성 기간 내에 발생하는 모든 데이터 레코드를 함께 그룹화하며 기간은 사용자가 지정합니다.
예) 시간 제한이 10초인 세션 윈도우를 사용하는 경우, 마지막 데이터 레코드로부터 10초 이내에 도착하는 모든 데이터 레코드는 동일한 창에 함께 그룹화됩니다. 세션 윈도우는 활성 기간 사이에 비활성 기간이 있는 데이터를 분석하는 데 유용합니다.
3.3 워터 마킹
워터마킹이란?
→ 이벤트 시간 처리에서의 시간 제한 설정. 워터마크는 일반적으로 확장 가능하고 내결함성이 있는 스트리밍 애플리케이션을 구축하기 위한 고급 API인 Spark Structured Streaming에서 사용
•
메모리 부족 오류 및 성능 저하로 이어질 수 있는 시간이 지남에 따라 데이터가 누적되는 것을 방지하는 데 유용함
•
시간 윈도우에 따른 집계와 같이 이벤트 순서에 따라 달라지는 작업을 수행해야 할 때 유용함
•
오래된 데이터를 삭제하여 기간이 지정된 집계를 효율적으로 처리
•
워터마크 임계값 이후에 데이터가 삭제되기 전에 도착하는 지연 이벤트 처리
예) 시간당 매출 합계를 계산하거나 10분 간격으로 평균 온도를 계산하는 경우에 사용. 워터마크를 사용하여 이전 데이터를 무시할 수 있는 지연 임계값을 지정
•
만약, 12:11에 12:04에 생성된 데이터가 늦게 수신된다고 하면, 해당 윈도우 시간(12:00~ 12:10)에 집계되도록 해야 함
•
지연 데이터가 이전 윈도우의 집계를 정확히 업데이트 할 수 있게, 오랜 기간동안 이전의 부분 집계에 대한 중간 상태를 유지해야 함
•
그러나, 해당 쿼리가 며칠 동안 걸쳐 장기간 실행된다면, 시스템에 누적되는 메모리가 과
부하가 올 수 있음
•
시스템 메모리의 과부하를 방지하기 위해 워터마크를 지정하여, 지연되는 데이터를 허용하는 시간 임계값을 조정