[데이터 플랫폼 운영 / 개발] - Spark 4 (Pull based backpressure)

Chan hae OH·2023년 8월 6일
0

Spark

목록 보기
6/12

1. 시작말


안녕하세요.

데이터 엔지니어링 & 운영 업무를 하는 중 알게 된 지식이나 의문점들을 시리즈 형식으로 계속해서 작성해나가며

새로 알게 된 점이나 잘 못 알고 있었던 점을 더욱 기억에 남기기 위해 글을 꾸준히 작성 할려고 합니다.

Spark의 경우 Spark 완벽 가이드 책을 많이 참고하여 운영을 하고 있습니다.

반드시 글을 읽어 주실 때 잘 못 말하고 있는 부분은 정정 요청 드립니다.

저의 지식에 큰 도움이 됩니다. :)



2. Backpressure 란?


Data 는 분석 서비스가 결합 되면서 실시간 요구사항이 증가하게 됐습니다.

이로 인해 Data를 수집하는 배치 작업의 주기가 점점 줄어들면서 Stream 단위의 데이터를 처리해야하는 경우가 점차 늘어나게 됩니다.

데이터를 발생하는 주체는 공정이 존재하는 생산 분야의 경우 정기적이거나 일정한 간격이 대부분이기 때문에 약속된 배치 주기를 통해 필요한 데이터를 가져올 수 있었습니다. 하지만 B2C 사업처럼 사람이 발생시키는 방대한 양의 데이터를 실시간으로 수집하는 경우까지는 아니더라도 언제 발생할지 모르는 생산 공정은 분명히 존재했습니다.

이에 비정규적인 이벤트 또는 실시간 발생 데이터를 어떻게든 수집해서 분석 서비스를 제공하기 위해, ms 단위로 데이터 발생을 확인하고 수집하는 기능을 도입하게 됩니다.

이 때 여러 장비에서 한 꺼번에 많은 데이터를 생산해내는 경우 이를 수용할 Buffer 가 필요했고, 이 Buffer 에 담겨 있는 데이터를 처리할 방식이 필요했습니다. 그렇기에 Kafka 와 Spark Structured Streaming 을 활용하여 데이터를 처리할 수 있는 Pipeline 을 구성했습니다.


Backpressure 는 배압을 뜻하는 영단어 입니다. 물을 가득 담고 있는 탱크에 관로 하나를 연결하여 물을 뽑게 되면 물의 양이 베르누이 방정식에 의거하여 수압이 발생하고, 이는 관로에 큰 영향을 미치게 됩니다.

Stream Backpressure 관련 참고 포스팅

데이터는 물에 비유를 해보자면 Backpressure 라는 단어가 SW 에서 쓰이게 되는 경우를 이해하기가 편할듯 합니다.

데이터 발생량이 갑작스럽게 많이 발생하게 되면 이를 처리 하기 위해 만들어놓은 Pipeline 에 영향을 미치게 되고 이는 물과 같이 Backpressure 를 받게 됩니다.

그러나 SW 에서는 베르누이 방정식을 적용하기가 힘들며, 데이터 생산 주체들이 발생시키는 트래픽을 어떻게 처리할지를 생각해야 합니다.



3. Backpressure 의 종류


아래 참조한 글에서는 Backpressure 의 종류를 2가지로 나누고 있습니다.

Stream Backpressure 관련 참고 포스팅

  • Push based backpressure
  • Pull based backpressure

저 또한 이 2가지의 경우로 Backpressure 발생을 고려하려고 합니다.

저의 경우 생산 장비와 Kafka 사이에서 발생하는 Backpressure 가 Push based backpressure 를 뜻하고, Kafka 와 Spark Structured Streaming 사이에서 발생하는 Backpressure 가 Pull based backpressure 를 뜻하게 됩니다.

저는 아직까지 Kafka 를 활용하면서 Push based backpressure 를 겪어보지는 못했지만, kafka 의 데이터를 처리하는 Spark Structured Streaming 에서 Pull based backpressure 를 겪은 경험이 있기 때문에 이를 정리해볼려고 합니다.



4. Stream 처리 때 고려해야할 것들


Stream 처리 시 발생하는 트래픽을 고려해야 할 때 경험상 아래와 같은 것들을 고려해야 했습니다.

  • 데이터 당 평균 사이즈
  • 데이터 발생 주체의 개수
  • 데이터 발생 주기

데이터가 얼마만큼 발생할 것인지를 예측하는 경우는 매우 중요했습니다.

네트워크 쪽의 경우 데이터 플랫폼과 원천 사이에서 오고 갈 데이터 사이즈에 따라 어느정도 대역폭의 선을 준비해야할 지 고려해야 했습니다.

데이터 플랫폼의 경우 데이터 처리량에 따라 어느 정도 Application 사이즈를 잡을지 고려해야 했고, 이에 맞춰 증설 계획을 잡아야 했습니다. 클라우드의 경우 사이징을 간편하게 해보고 남을 시 다시 회수가 가능하지만, On-premise 로 운영하고 있는 경우 Node 구매 및 세팅 등의 증설 계획이 철저하게 분석돼야 하기 때문에 상당히 머리 아픈 경우입니다.

그렇기에 모두가 처음 해보는 실시간 분석 처리이기도 해서 조금씩 장비 대수를 확대 해가며 감을 잡아가고 있습니다.

YARN 에 Spark 을 동작시키고 있고, Queue 는 배치를 위한 Queue 에 임시적으로 Spark 이 동작하고 있는 상태 입니다.

그렇기 때문에 Stream 작업을 위한 별도의 Queue 는 필요하고, 해당 Queue 를 생성할 때 Node 를 증설해서 해당 Queue 에 생성할 것인지, 배치를 위한 Queue 에서 자원을 나누어 Stream Queue 를 생성할 것인지 고민을 해야 했습니다.

이 때 Queue 를 Spark job 이 어느정도 점유를 하는지는 구조가 완벽하게 테스트 되고 나서 계획을 잡으려고 합니다.



5. Spark 에서 Backpressure 를 대비하는 방법


Spark 에서 Backpressure 를 대비하는 방법은 존재합니다.

솔직히 매우 간단하게 옵션만 주면 Backpressure 를 대비할 수 있어 위의 설명이 매우 무색해질 정도 입니다.

Spark 의 Stream 처리는 아래 2가지가 있습니다.

  • Spark Streaming
  • Spark Structured Streaming

Spark Streaming 의 경우는 하기 옵션으로 Backpressure 를 조절할 수 있다고 합니다.

  • spark.streaming.kafka.maxRatePerPartition = "100"
  • spark.streaming.backpressure.enabled = "true"

Spark Structured Streaming 의 경우는 하기 옵션으로 Backpressure 를 조절할 수 있습니다.

  • option("maxOffsetsPerTrigger", "100")

여기서 Spark Structured Streaming Application 을 동작 시켰을 때 첫 배치는 maxOffsetsPerTrigger 옵션이 적용되지 않는다고 합니다. 그렇기 때문에 처음 어플리케이션을 동작시킬 때 데이터양을 고려해야 합니다.

이렇게 Spark 의 Pull based backpressure 를 대비할 수 있습니다.

그러나 해당 옵션들은 Poll 당 처리할 데이터 양을 제한하는 옵션들이기 때문에 어플리케이션이 버틸 수 있는 최대 사이즈까지 제한을 두는 것이 자원을 효율적으로 사용하는 방식일 것입니다.



6. 맺음말


Backpressure 는 비이상적인 데이터 발생으로 생겨납니다. 이에 안전장치가 필요하며, Spark 에서는 해당 Backpressure 에 대한 안전장치가 존재합니다.

그러나 REST API 를 통해 동작중인 어플리케이션의 config 을 변경하는 기능이 없는 점이 불편한 듯 합니다. 시간이 될 때 동작 중인 어플리케이션에서 StartingOffset 이나 maxOffsetsPerTrigger 등의 config을 수정할 수 있는 방법을 개발하거나 찾아봐야겠습니다.



profile
Data Engineer

2개의 댓글

comment-user-thumbnail
2023년 8월 6일

좋은 글 감사합니다. 자주 올게요 :)

1개의 답글