스파크 완벽 가이드 - Chapter20. 스트림 처리의 기초

  • 구조적 스트리밍이란? DataFrame이나 Dataset 코드와 쉽게 통합할 수 있는 신규 스트리밍 API
  • 구조적 스트리밍 API는 스트리밍 애플리케이션을 개발할 때 선택할 수 있는 프레임워크이다.
  • 구조적 스트리밍은 DStream의 주요 기능에 대한 상위 기능을 제공한다.

1. 스트림 처리란?

  • 스트림 처리는 신규 데이터를 끊임없이 처리해 결과를 만들어내는 행위이다.
  • 입력 데이터는 무한하며 시작과 끝을 정의하지 않는다. 입력 데이터는 스트림 처리 시스템의 도착한 일련의 이벤트이다.
  • 스트리밍 애플리케이션은 이벤트 스트림이 도착한 후 다양한 쿼리 연산을 수행한다.
  • 구조적 스트리밍은 배치 애플리케이션과 나머지 컴포넌트와 쉽게 연동할 수 있도록 설계되었다.
  • 구조적 스트리밍은 스트림 처리를 넘어 연속형 애플리케이션을 쉽게 구현하기 위해 설계 되었다.

연속형 애플리케이션이란?

  • 스트리밍, 배치 그리고 대화형 작업으로 구성된 통합 애플리케이션을 말한다.

1.1 스트림 처리 사례

  • 통보와 알림 : 연속적인 이벤트에서 특정 이벤트나 이벤트의 패턴을 탐지했을 때 발생
  • 실시간 리포트
  • 증분형 ETL
    • 스파크 배치 잡은 원시 데이터를 ETL 처리해 파케이 같은 구조적 포맷으로 변환
    • 구조적 스트리밍을 이용하면 신규 데이터를 수 초 내에 반영할 수 있음 => 데이터를 받는 시점이 더 빨라진다.
    • exactly-once 처리를 해야한다.
  • 실시간 제공용 데이터 갱신 : 다른 애플리케이션의 서비스용 데이터를 만들기 위해 사용함
    • 스트리밍 시스템은 다른 저장소 시스템에 대한 동기식 증분 업데이트와 데이터 변형 방지를 위한 트랜잭션을 지원해야함
  • 실시간 의사결정
    • 신규 입력을 분석하고 자동으로 비즈니스 로직에 따라 처리한다.

1.2 스트림 처리의 장점

  • 대기 시간이 짧다.
  • 자동으로 연산 결과의 증분을 생성하므로 반복적인 배치 작업보다 결과를 수정하는 데 더 효율적이다.

참고 > 배치 처리의 장점

  • 유지보수와 개발이 비교적 단순하며 높은 처리량을 얻을 수 있다.

1.3 스트림 처리의 과제

  • 이벤트의 순서가 보장되지 않을 수 있다. (이벤트 순서가 뒤섞일수 있다.)
  • 입력값과 출력값에 트랜잭션을 보장
  • 대규모의 상태 정보 유지하기
  • 높은 데이터 처리량 보장하기
  • 장애 상황에서도 정확히 한 번 처리하기
  • 부하 불균형과 뒤처진 서버 다루기
  • 이벤트에 빠르게 응답하기
  • 다른 저장소 시스템의 외부 데이터와 조인하기
  • 신규 이벤트 도착 시 출력 싱크의 갱신 방법 결정하기
  • 출력 시스템에 데이터 저장 시 트랜잭션 보장하기
  • 런타임에 비즈니스 로직 변경하기

2. 스트림 처리의 핵심 설계 개념

2.1 레코드 단위 처리와 선언형 API

  • 각 이벤트를 애플리케이션에 전달하고 사용자 코드에 반응하도록 만든다.
  • 레코드 단위 처리 API를 사용하는 스트리밍 시스템은 애플리케이션 내부에서 여러 처리 파이프라인을 연결하는 기능만 제공
    • 직접 상태 관리를 해야함
    • 중복 처리 방지 등의 기능을 직접 개발해야함
  • 최신 스트리밍 시스템에서는 선언형 API를 제공함
    • 선언형 API를 사용하는 시스템에서는 애플리케이션을 정의할 때 “어떻게(how)” 신규 데이터를 처리하고 장애 상황에서 복구할지 지정하는 대신 “무엇(what)”을 처리할지 지정한다.
    • DStream API는 선언형 API의 대표적인 예로 맵, 리듀스, 필터 같은 연산을 제공
    • DStream API는 각 연산자의 데이터 처리량과 연산 관련 관련 상태 정보를 자동으로 추적하고 관련 상태를 신뢰도 있게 저장한다. 필요한 경우 장애 지점부터 연산을 복구한다.
    • 스파크의 구조적 스트림밍은 별도의 프로그래밍 없이 함수형 연산을 훨씬 효율적으로 처리할 수 있는 SQL 형태의 관계형 연산으로 변환해 이런 개념을 한 단계 발전시킴

2.2 이벤트 시간과 처리 시간

  • 이벤트 시간 처리는 원천 시스템에서 각 레코드에 기록한 타임스탬프를 기반으로 데이터를 처리하는 방식을 의미한다.
  • 처리 시간 기준 처리는 스트리밍 애플리케이션에 레코드가 도착한 시간을 기반으로 처리하는 방식을 의미한다.
  • 스트리밍 레코드는 순서가 뒤섞여 들어오거나 여러 원천 시스템 사이의 순서가 뒤 섞일 수 있다. 이런 경우엔 이벤트 시간 처리가 매우 중요하다.
  • 이벤트 시간을 사용하는 애플리케이션을 개발하는 경우 고려해야 할 점
    • 늦게 도착한 이벤트를 처리할 수 있도록 상태를 추적해야한다.
    • 시스템이 해당 시점까지의 모든 입력 데이터를 수신했을 가능성이 높은 시기가 언제인지 결정해야한다.
    • 대부분의 선언형 시스템은 위 문제들을 자동으로 해결한다.

2.3 연속형 처리와 마이크로 배치 처리

  • 연속형 처리 : 레코드별로 데이터를 처리
    • 가장 빠르게 응답한다.
    • 최대 처리량이 적다.
  • 마이크로 배치 : 입력 데이터를 작은 배치로 모으기 위해 대기한다.
    • 다수의 분산 태스크를 이용해 각 배치를 병렬로 처리한다.
    • 높은 처리량을 얻을 수 있다.
    • 배치를 모으기 위한 시간이 필요하다.
  • 2가리 처리 방식 중 하나를 선택할 떄는 지연 시간 요건과 총 운영비용(TCO)을 고려해야 한다.
    • 마이크로 배치 시스템은 노드 장애가 덜 발생하기 떄문에 운영비용이 낮다.
    • 빠른 응답 시간을 원하는 경우 연속형 처리 시스템을 사용하거나 빠른 응답성을 제공하는 고속 서빙 계층을 마이크로 배치 시스템과 함께 사용할 수 있다.

3. 스파크의 스트리밍 API

  • 스파크는 2가지 스트리밍 API를 제공한다.
    • DStream API : 마이크로 배치 방식으로만 동작
    • 구조적 스트리밍 API : 최적화 기술, 이벤트 시간, 연속성 처리를 지원

3.1 DStream API

  • 스파크 스트리밍은 기본적으로 RDD 코드를 함께 사용해 정적 데이터와 조인하는 등의 기능을 지원
  • 제약사항
    • 자바나 파이썬 객체와 함수에 매우 의존적이다. => 최적화 기법을 적용하지 못함
    • 처리 시간을 기준으로 동작 => 이벤트 처리 시간 지원 안함
    • 마이크로 배치 형태로만 동작

3.2 구조적 API

  • 스파크의 구조적 API를 기반으로 하는 고수준 스트리밍 API
  • 선언형 API를 제공하며 구조적 데이터 모델을 기반으로 만들어짐
  • 더 많은 종류의 최적화 기술을 자동으로 수행
  • 이벤트 시간 데이터 처리를 지원
  • 연속형 처리 기능이 추가됌 (2.3 버전)
  • 단순한 스트림 처리를 넘어 스트리밍, 배치, 대화형 쿼리를 하나로 통합한 연속형 애플리케이션을 쉽게 만들 수 있도록 설계됌
  • DataFrame과 같은 API를 사용함 => 배치와 스트리밍용 코드를 별도로 관리할 필요가 없음
  • 데이터가 도착할 때마다 자동으로 증분 형태의 연산 결과를 만들어낸다.