Data

Spark 스트림 - 프로젝트에서...

gangmin 2024. 8. 21. 13:48

안녕하세요. 프로젝트와 다양한 일정으로 오랜만에 글을 쓰게 되었습니다. 오늘은 데이터 파이프라인 구축 프로젝트에서 스파크를 사용한 경험을 공유하려고 합니다.

Spark & Stream

  • 2012년 부터 map과 reduce를 지원하면서 스트림 처리할 수 있도록 지원함.
  • DStream API를 통해서 수행했음.
  • 저수준 연산만 사용할 수 있기 때문에 최적화 기법을 활용하는 데 한계가 있었음.
  • 2016년 스파크 개발자들은 DataFrame을 기반으로 새로운 API를 개발함.

Stream 처리란?

스트림 처리는 신규 데이터를 끊임없이 처리해 결과를 만들어내는 행위이다. 입력 데이터는 무한하며 시작과 끝을 사전에 정의하지 않는다.

스트리밍 애플리케이션

이벤트 스트림이 도착한 후 다양한 쿼리 연산을 수행합니다. (예를 들어서, 이벤트의 타입 별 실행 카운트를 추적하거나 시간별로 이벤트의 타입별 실행 카운트를 집계하는 방식)

고정된 입력 데이터셋을 처리하는 배치 처리와 비교할 수 있습니다. 고정된 입력 데이터는 일반적인 애플리케이션에서 발생한 이력성 이벤트를 모두 저장하는 웨어하우스나 데이터셋이 될 수 있다.

스트림 처리와 배치 처리가 다르게 보일 수 있지만, 함께 사용된다. 스트리밍 애플리케이션이 배치작업에서 주기적으로 생성되는 데이터셋과 조인해야 하는 경우가 있다. 또한, 스트리밍 작업의 출력이 배치 작업용 쿼리에 필요한 파일이나 테이블인 경우도 있다.

구조적 스트리밍은 처음부터 배치 애플리케이션 뿐만 아니라 나머지 컴포넌트와 쉽게 연동할 수 있도록 설계되었다.


스트림 처리의 장점

  • 대기 시간이 짧다. → 사용자 애플리케이션이 빠르게 응답해야 한다면 필요
  • 자동으로 연산결과를 증분 생산하기 때문에 배치 작업보다 결과를 수정하는 데 효율적이다.
  • → 배치 작업으로 실행하는 경우에는 모든 데이터를 읽어야 하지만, 이전 연산을 기억하기에 처리하기 용이

스트림 처리의 과제

  • 하나의 입력 데이터가 지연되거나 재전송되면 시간이 뒤섞여서 도착한다는 것이다.
  • 대규모의 상태 정보 유지
  • 높은 데이터 처리량 보장하기
  • 장애 상황에서도 정확히 한번 처리하기
  • 부하 불균형과 뒤처진 서버 다루기
  • 이벤트에 빠르게 응답하기

API 설계 개념

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

레코드 단위 처리는 한 번에 테이블에서 한 레코드만 처리하고 해당 레코드에 대한 모든 작업이나 계산을 수행합니다.

  • 각 이벤트를 애플리케이션에 전달하고 사용자 코드에 반응하도록 하는 것이다.
  • 데이터 처리와 관련된 완벽한 제어권을 가져야 하는 분야에서 중요한 위치를 차지한다.
  • 레코드 단위 처리를 사용하는 스트리밍 애플리케이션 내부에서 여러 처리 파이프라인을 연결하는 기능만 제공
  • 상태 관리와 같은 복잡한 문제가 발생하기 때문에 요즘은 선언형 API를 제공
  • 선언형이란?
    • 쉽게 설명하자면 : 생각나는 대로 코드를 짜는 것
    • 자세히 설명하자면 : 무엇인가(What)를 작업, 제어 흐름을 설명하지 않고 계산 논리에 집중하는 프로그래밍 패러다임이다.
    절차형 프로그래밍(imperative programming)
    • 쉽게 설명하자면 : 순서대로 구조화 해서 코드를 짜는 것
    • 자세히 설명하자면: 어떤 방법(How)으로 할것인지, 알고리즘을 명시하지만 목표는 명시하지 않는다.
  • 선언형 프로그래밍(declarative programming)

이벤트 시간과 처리 시간

  • 이벤트 시간을 처리할 것인지 고민해야 한다.
  • 이벤트 시간 처리는 원천 시스템에서 각 레코드에 기록한 타임스탬프를 기반으로 데이터를 처리하는 방식을 의미한다.
  • 처리 시간 기준 처리는 스트리밍 애플리케이션에 레코드가 도착한 시간을 기반으로 처리하는 방식을 의미한다.

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

연속형 처리

  • 다른 노드에서 전송하는 메시지를 끊임없이 수신하고 새로 갱신된 정보를 자신의 하위 노드로 전송
  • 연속형 처리는 레코드 별로 데이터를 처리한다는 것이다.
  • 연속형 처리는 신규 메시지에 즉시 반응하기 때문에 입력량이 적을 때 가장 빠르게 응답한다.
  • 레코드 단위 부하가 크기 때문에 최대 처리량이 작다.

마이크로 배치 처리

  • 입력 데이터를 작은 배치로 모으기 위해 대기합니다.
  • 배치 잡 실행 방식과 유사하게 다수의 분산 Task를 사용해 각 배치를 병렬로 처리한다.
  • 더 적은 노드로 같은 양의 데이터를 처리할 수 있습니다.
  • 워크로드 변화에 대응할 수 있도록 Task 수를 늘리거나 줄이는 방식인 부하 분산 기술을 동원할 수 있다.
  • 배치를 모으기 위한 시간이 필요하므로 지연 시간이 발생한다.

스파크 스트리밍 API

두가지 스트리밍 API를 제공한다.

  • DStream을 사용하는 방식은 마이크로 배치 방식만 제공함.
  • 구조적 스트리밍은 두가지 방식을 모두 제공한다.

DStream API

  • 2012년 처음 공개된 이후 스트림 처리 분야에서 널리 사용됨
  • 자바나 파이썬의 객체와 함수에 매우 의존적 (DataFrame, DataSet 사용 불가)
  • 처리 시간을 기준으로 동작
  • 마이크로 배치 형태만 제공

구조적 스트리밍

  • 고수준 API를 사용하기 때문에 다양한 언어와 플랫폼에서 사용할 수 있음