본문 바로가기

Project/SW Maestro

[SW Maestro 1편] 작업 큐 아키텍처에 대한 고민

반응형

배경

사용자가 학습 PDF 자료를 업로드하면, 이를 분석하고 서비스를 제공해주는 서비스를 개발하고 있습니다. 

문서 업로드 기능을 구현하면서 업로드 시 다양한 이벤트들이 발생하는데, 이를 어떻게 관리할 수 있을지 고민한 내용을 포스팅했습니다.

 

문제 상황

문서 업로드 시 관리하는 기능을 담당했는데, 업로드 시 아래의 과정이 필요합니다:

1. 썸네일 추출 및 S3 업로드

2. PDF 기본 정보 분석 (총 페이지 수, 페이지별 텍스트 추출 등)

3. AI 기반 문서 요약 자료 생성

4. RAG 검색을 위한 chunking 및 Embedding

 

처음 PoC를 구현할 때에는 1->2->3->4 가 모두 잘 동작하는 happy case만 가정했고, 각 단계를 순차적으로 호출하는 동기 방식으로 구현했습니다. 즉 각 작업 상태에 대한 관리나 재시도 구조 없이 순차 실행한 것입니다. 하지만 실제 운영환경에서는 다양한 이유로 인해 각 단계에서 오류가 발생할 수 있습니다. 예를 들자면,

1. 썸네일 추출 및 S3 업로드

1. PDF 읽기/렌더링 오류 (PDF 파일이 손상된 경우, 페이지 크기가 너무 커서 메모리 부족 발생, 렌더링 타임아웃 발생)

2. 이미지 변환 오류 (이미지 인코딩 실패, 임시 파일 생성 실패)

3. S3 업로드 오류 (S3 권한 부족,  네트워크 오류)

2. PDF 기본 정보 분석

1. PDF 파싱 오류

2. 텍스트 추출 오류

3. 성능/리소스 오류

3. AI 기반 문서 요약 자료 생성

1. LLM 호출 오류

4. RAG 검색을 위한 chunking 및 Embedding

1. Chunking/Embedding 실패 (API 호출 오류, 토큰 길이 초과 등)

2. Vector DB 저장 오류

 

이런 오류가 발생했을 때에도 안정적으로 서비스를 운영하기 위한 아키텍처가 설계되어야 합니다. 어떤 방식으로 이를 개선할 수 있을까요?

개선 후보 아키텍처

1. 메시지 큐 기반 비동기 처리 방식 (RabbitMQ, Kafka)

업로드 이후 처리해야 할 작업을 메시지 큐에 발행하고, Worker가 메시지를 소비해 작업을 처리하는 방식

장점: 요청 처리와 문서 분서 작업 분리가능하여 확장성이 좋음

단점: 메시지 중복 처리, 실패 메시지 관리

참고자료:
- 네이버 작업 큐: https://engineering.linecorp.com/ko/blog/decaton-case-studies

- 카카오 message streaming platform: https://tech.kakao.com/posts/485?utm_source=chatgpt.com

 

2. 이벤트 기반 처리 방식 (Kafka)

각 단계가 완료될 때마다 이벤트를 발행하고, 다음 단계가 해당 이벤트를 구독해 실행되는 방식

장점: 단계간 결합도를 낮출 수 있어 기능 확장에 유리

단점: 전체 처리 흐름 추적 어려움, 개발 복잡도 증가

참고자료:

- 토스 kafka를 활용한 비동기 트랜잭션 분리: https://toss.tech/article/slash23-corebanking

 

3. 워크플로우 엔진 기반 처리 방식 (AWS Step Functions, Airflow)

문서 분석 과정을 하나의 워크플로우로 정의하고, 각 단계를 상태 머신처럼 관리하는 방식

장점: 재시도, 타임아웃, 실패 분기, 보상 처리 등을 명시적으로 관리할 수 있어 복잡한 파이프라인에 적합

단점: 초기 비용

 

4. DB 상태 기반 Polling Worker 방식

각 처리 단계를 Job으로 저장하고, Worker가 주기적으로 DB를 조회해 처리 가능한 작업을 실행하는 방식

장점: 작업 상태를 DB에 남길 수 있어 실패 추적, 재시도, 특정 단계 재처리가 가능

단점: DB를 작업 큐로 사용하여 작업량 증가시 DB 부하 가능성 존재

참고자료:

- 배민 RDB 기반 Task Queue: https://techblog.woowahan.com/23625/ 

 

장시간 비동기 작업, Kafka 대신 RDB 기반 Task Queue로 해결하기 | 우아한형제들 기술블로그

장시간 비동기 작업, Kafka 대신 RDB 기반 Task Queue로 해결하기 | 전자계약서 시스템에서는 다양한 업무 목적에 따라 여러 형태의 대용량 엑셀 파일을 생성할 수 있습니다. 예를 들어 생산성 지표 엑

techblog.woowahan.com

 

선택 아키텍처: RDB 기반 Task Queue (DB 기반 Polling Worker 방식)

위 자료들은 현업에서 사용하고 있는 그중에서도 가장 인상 깊게 본 문서는 배민 RDB 기반 Task Queue 자료입니다.

 

Kafka나 메시지 큐 기반 구조도 고려했지만, 현재 문제의 핵심은 고처리량 이벤트 스트리밍이 아니라 장시간 문서 분석 작업의 상태 관리와 실패 복구였습니다.

 

문서 업로드 이후의 작업은 썸네일 생성, PDF 분석, AI 요약, Embedding 생성처럼 순서가 있는 파이프라인입니다. 각 단계에서 실패가 발생했을 때 어느 단계까지 성공했는지, 어떤 오류로 실패했는지, 몇 번 재시도했는지, 특정 단계부터 다시 실행할 수 있는지를 명확히 관리해야 했습니다.

 

메시지 큐를 사용할 경우 작업 실행 자체는 비동기로 분리할 수 있지만, 전체 진행 상태 추적, 중복 메시지 처리, 실패 메시지 관리, 재시도 정책, 단계별 재처리 구조는 별도로 설계해야 합니다. Kafka 역시 여러 서비스가 동일 이벤트를 독립적으로 구독하거나 대량 이벤트를 스트리밍 처리하는 상황에는 적합하지만, 현재처럼 하나의 문서 분석 작업을 안정적으로 완료시키는 목적에는 운영 복잡도가 더 크다고 판단했습니다.

 

따라서 별도의 메시지 브로커를 도입하기보다, RDB에 작업 상태와 재시도 정보를 저장하고 Polling Worker가 처리 가능한 작업을 가져가는 RDB 기반 Task Queue 방식을 선택했습니다. 이 방식은 구현과 운영이 비교적 단순하면서도, 실패 추적, 재시도, 단계별 재처리, 관리자 기반 복구가 가능하다는 점에서 현재 요구사항에 더 적합했습니다.

 

반응형