주요 컨텐츠로 이동

Apache Spark Structured Streaming에서 상태 유지 파이프라인(Stateful pipeline)의 성능 개선

Mojgan Mazouchi
Mrityunjay Kumar
Anish Shrigondekar
Karthikeyan Ramasamy
이 포스트 공유하기

(번역: Youngkyong Ko) Original Post

소개 

Apache Spark™ Structured Streaming 은 확장성과 내결함성을 제공하는 인기 있는 오픈 소스 스트림 처리 플랫폼으로, Spark SQL 엔진 위에 구축되어 있습니다. 데이터브릭스 레이크하우스 플랫폼의 대부분의 증분 및 스트리밍 워크로드는 Structured Streaming으로 구동되며, 여기에는 Delta Live Tables와 Auto Loader가 포함됩니다. 지난 몇 년 동안 모든 산업에 걸쳐 다양한 사용 사례에서 Structured Streaming 사용량과 채택이 기하급수적으로 증가했습니다. 매주 1,400만 건 이상의 Structured Streaming 작업이 데이터브릭스에서 실행되며, 그 수는 매년 2배 이상의 속도로 증가하고 있습니다.

대부분의 Structured Streaming 워크로드는 크게 분석 워크로드와 운영 워크로드의 두 가지 범주로 나눌 수 있습니다. 운영 워크로드는 비즈니스의 중요한 부분을 실시간으로 실행합니다. 분석 프로세싱과 달리 운영 프로세싱은 데이터의 적시 변환과 조치를 강조합니다. 운영 처리 아키텍처를 통해 조직은 들어오는 데이터를 신속하게 처리하고, 운영상의 의사 결정을 내리고, 데이터에서 도출된 실시간 인사이트를 기반으로 즉각적인 조치를 취할 수 있습니다.

이러한 운영 워크로드의 경우 일관된 짧은 지연 시간이 핵심 요구 사항입니다. 이 블로그에서는 Structured Streaming을 사용하는 상태 유지 파이프라인에서 이 요구 사항을 충족하기 위해, 데이터브릭스가 Lightspeed 프로젝트의 일환으로 구현한 성능 개선을 중점적으로 살펴 보겠습니다.

우리의 성능 평가에 따르면 이러한 개선 사항을 통해 Databricks Runtime 13.3 LTS 이상에서 초당 10만 개 이상의 이벤트를 처리하는 워크로드의 경우 상태 유지 파이프라인 지연 시간을 최대 3~4배까지 개선할 수 있는 것으로 나타났습니다. 이러한 개선으로 지연 시간 SLA가 매우 엄격한 다양한 워크로드를 지원할 수 있는 길이 열렸습니다.

이 블로그는 2부로 구성되어 있으며, 1부에서는 성능 개선과 이득에 대해 자세히 살펴보고 2부에서는 이러한 성능 개선을 달성한 방법에 대한 포괄적인 심층 분석과 심화 인사이트를 제공합니다.

이 블로그에서는 독자가 Apache Spark Structured Streaming에 대한 기본적인 이해가 있다고 가정합니다.

배경

스트림 처리는 크게 상태 없음(stateless)와 상태 유지(stateful) 범주로 분류할 수 있습니다:

  • 상태 없음 (Stateless) 파이프라인은 일반적으로 마이크로 배치 간의 컨텍스트를 기억하지 않고 각 마이크로 배치를 독립적으로 처리합니다. 예를 들어 레코드별로 데이터를 변환(예: 필터링, 분기, 매핑 또는 반복)하는 스트리밍 ETL 파이프라인이 있습니다.
  • 상태 유지(Stateful) 파이프라인에는 종종 여러 마이크로 배치에 나타나는 레코드 간의 정보를 집계하는 작업을 포함합니다 (예: 기간 윈도우를 기준으로 평균 계산). 이 같은 작업을 완료하려면 파이프라인은 마이크로 배치에서 본 데이터를 기억해야 하며, 이 상태는 파이프라인이 다시 시작될 때 복원력이 있어야 합니다. 

상태 유지 스트리밍 파이프라인은 주로 제품 및 콘텐츠 추천, 사기 탐지, 서비스 상태 모니터링 등과 같은 실시간 사용 사례에 사용됩니다.

상태와 상태 관리란?

아파치 스파크 쿼리에서 상태는 스트리밍 파이프라인의 마이크로 배치 간에 유지되는 중간 지속적 컨텍스트로서 키가 있는 상태 저장소의 모음입니다. 상태 저장소는 버전이 관리되는 키-값 저장소로서, 읽기와 쓰기 오퍼레이션을 제공합니다. Structured Streaming에서는 상태 저장소 공급자 추상화를 사용하여 상태 저장소 연산을 구현합니다. 두 가지 기본 제공 상태 저장소 공급자가 있습니다:

  • HDFS 기반 상태 저장소 공급자는 모든 상태 데이터를 executor의 JVM 메모리에 저장하며, HDFS 호환 파일시스템에 영구 저장된 파일로 상태 데이터가 백업됩니다. 저장소에 대한 모든 업데이트는 트랜잭션 단위로 세트로 수행되며, 각 업데이트 세트는 저장소의 버전을 증가시킵니다. 이러한 버전은 올바른 버전의 저장소에서 업데이트를 다시 실행하고 필요한 경우 저장소 버전을 다시 생성하는 데 사용할 수 있습니다. 모든 업데이트가 메모리에 저장되므로 이 공급자는 주기적으로 메모리 부족 문제와 가비지 컬렉션 일시 중지가 발생할 수 있습니다.
  • RocksDB 상태 저장소 공급자는 각 excutor 노드의 Spark 파티션당 하나씩 RocksDB 인스턴스 내에서 상태를 유지 관리합니다. 이 경우 상태는 주기적으로 분산 파일 시스템에 백업되며 특정 상태 버전을 로드하는 데 사용할 수 있습니다.

데이터브릭스는 프로덕션 워크로드에 RocksDB 상태 저장소 공급자를 사용할 것을 권장합니다. 시간이 지남에 따라 상태 크기가 수백만 개의 키를 초과할 정도로 커지는 것이 일반적이기 때문입니다, 이 공급자를 사용하면 HDFS 상태 저장소 공급자에서 흔히 나타나는 이슈, 즉 가비지 컬렉션으로 인해 JVM 힙 관련 메모리 문제나 속도 저하가 발생할 위험을 피할 수 있습니다.

벤치마크

우리는 상태 유지 스트리밍 파이프라인의 성능과 개선 효과를 더 잘 이해하기 위해 일련의 벤치마크를 만들었습니다. 테스트를 위해 일정한 처리량으로 소스에서 데이터를 생성했습니다. 생성된 레코드에는 레코드가 생성된 시점에 대한 정보가 포함되어 있었습니다. 모든 상태 유지 스트리밍 벤치마크에서는 레코드별로 종단간 지연 시간을 추적했습니다. 싱크 측에서는 Apache DataSketches 라이브러리를 사용하여 각 레코드가 싱크에 기록된 시간과 소스에서 생성된 타임스탬프 사이의 차이를 수집했습니다. 이 데이터는 지연 시간을 밀리초 단위로 계산하는 데 사용되었습니다.

Kafka 벤치마크의 경우, Kafka를 실행하고 Kafka에 공급할 데이터를 생성하기 위해 일부 클러스터 노드를 따로 설정했습니다. 레코드가 (싱크에 있는) Kafka에 성공적으로 게시된 후에만 레코드의 지연 시간을 계산했습니다. 모든 테스트는 상태유지 스트리밍 쿼리를 위한 상태 저장소 공급자로 RocksDB를 사용하여 실행되었습니다.

아래의 모든 테스트는 8개의 코어와 61GB RAM을 갖춘 AWS의 i3.2xlarge 인스턴스에서 실행되었습니다. 테스트는 드라이버 1개와 워커 노드 5개로 실행되었으며, DBR 12.2(개선 사항 없음)를 기본 이미지로, DBR 13.3 LTS(모든 개선 사항 포함)를 테스트 이미지로 사용했습니다.

Streaming Aggregation with Kafka Source/Sink
Streaming Aggregation with Kafka Source/Sink: This benchmark reads from a Kafka source, writes to a Kafka sink, and performs stateful aggregation operations. We see up to 76% (p95) and 87% (p99) end-to-end latency reduction with an optimized number of shuffle partitions and improvements enabled.

Stream-Stream Join Benchmark
Stream-Stream Join Benchmark: This benchmark reads from an in-memory rate source, writes to an in-memory stats sink, and performs stream-stream join operations. We see up to 78% (p95) and 83% (p99) end-to-end latency reduction with an optimized number of shuffle partitions and improvements enabled.

Streaming Drop Duplicates Benchmark
Streaming Drop Duplicates Benchmark: This benchmark reads from an in-memory rate source, writes to an in-memory stats sink, and performs dropDuplicate operations. We see up to 77% (p95) and 93% (p99) end-to-end latency reduction with an optimized number of shuffle partitions and improvements enabled.

Streaming flatMapGroupsWithState Benchmark
Streaming flatMapGroupsWithState Benchmark: This benchmark reads from an in-memory rate source, writes to an in-memory stats sink, and performs arbitrary stateful operations using flatMapGroupsWithState. We see up to 65% (p95) and 66% (p99) end-to-end latency reduction with an optimized number of shuffle partitions and improvements enabled.

결론

이 블로그에서는 프로젝트 Lightspeed 업데이트 블로그에서 언급한 성능 개선 사항을 보여드리기 위해 수행한 벤치마크의 개괄적인 개요를 소개 드렸습니다. 벤치마크에서 알 수 있듯이, 우리가 추가한 성능 개선은 데이터브릭스에서 Spark Structured Streaming을 사용해 상태유지 파이프라인을 실행하는 고객들에게 많은 속도와 가치를 제공합니다. 상태 유지 파이프라인에 추가된 성능 향상에 대해서는 다음 블로그 게시물 "Apache Spark Structured Streaming의 최신 성능 향상에 대한 심층 분석"에서 보다 심도 있게 논의할 수 있습니다.

가용성

위에 언급된 모든 기능은 DBR 13.3 LTS 릴리스부터 사용할 수 있습니다.

Databricks 무료로 시작하기

관련 포스트

Project Lightspeed Update - Advancing Apache Spark Structured Streaming

In this blog post, we will review the advancements in Spark Structured Streaming since we announced Project Lightspeed a year ago, from performance...

Latency goes subsecond in Apache Spark Structured Streaming

Apache Spark Structured Streaming is the leading open source stream processing platform. It is also the core technology that powers streaming on the...

Apache Spark Structured Streaming에서 상태 유지(stateful) 파이프라인의 최신 성능 향상에 대한 심층 분석

(번역: Youngkyong Ko) Original Post 이 글은 상태 유지(stateful) 파이프라인의 최신 성능 개선에 대해 2부로 구성된 시리즈 중 두 번째 파트입니다. 이 글을...
모든 엔지니어링 블로그 포스트 보기