Batch Serving
- 실시간 응답이 중요하지 않은 경우:
데이터 처리에 일정 시간이 소요되어도 괜찮은 경우
- 대량의 데이터를 처리할 때
- 정기적인 일정으로 수행할 때
- 인력
- 인력이 적은 경우:
Batch Serving이 Online Serving 보다 쉬울 수 있음
데이터 저장 형태
- RDB, 데이터 웨어하우스(GCP의 Big Query)
예시
- Netflix의 추천시스템, DoorDash의 레스토랑 추천
- 1시간, 4시간, 24시간 단위로 예측 후에 DB에 저장하고, 서비스(앱/웹)은 DB에 있는 예측 결과를 활용하게 됨
Online Serving
- 상황
- 실시간 응답이 중요한 경우:
즉각적으로 응답을 제시해야 하는 경우- 개별 요청에 대한 맞춤 처리가 중요할 때
- 동적인 데이터에 대응할 때: 데이터가 지속적으로 변하는 경우
인력
- API서버, 실시간 처리 등의 경험이 필요
데이터 저장 형태
- 요청할 때 같이 데이터 제공
- API, 메세지
예시
- 유튜브의 추천 시스템(새로고침)
- 번역
- 은행의 사기 탐지 시스템: 실시간 거래 이슈 탐지
- 요청(Request)이 오면 바로 요청에 대한 응답(Response) 제공
소프트웨어 개발에 있어서의 패턴 => 디자인 패턴
디자인패턴 = Template
- 과거부터 문제를 해결한 사람들이 반복된 내용을 패턴으로 정리
- 코드의 재사용성, 가독성, 확장성 등을 향상시키기 위한 목적으로 도입됨.
- 주로 객체 지향 프로그래밍에서 사용되지만, 다른 프로그래밍 패러다임에서도 유용
- 개발 과정의 커뮤니케이션에서 이런 패턴을 사용하기도 함
- ex) "이번 서빙은 Batch 패턴으로 구현하죠"
- 안티 패턴: 보통 좋지 않다고 알려진 패턴
- 머신러닝의 특수성으로 별도의 디자인 패턴이 생김
- 일반적인 소프트웨어 개발: Only Code
- 머신러닝 개발의 특수성: Data, Model, Code
자주 나오는 용어 정리
- 예측 서버: 모델 예측 제공
- 데이터베이스: 회원가입 등 데이터 저장
- 서비스 서버: 유저에게 제공
핵심
실시간성이 필요 없는 경우에 주기적으로 예측 결과를 DB에 저장하고, 활용하는 쪽은 DB에서 결과를 읽어와서 사용
장점
고민할 점
Use Case

출처: https://mercari.github.io/ml-system-design-pattern/Serving-patterns/Batch-pattern/design_en.html
Job Managemnet Server
- 작업을 실행하는 서버
- Apache Airflow 등을 주로 사용
- 특정 시간에 주기적으로 Batch Job을 실행시키는 주체
Job
- 어떤 작업 실행에 필요한 모든 활동
- Job이 실행되는 과정에 Model Load, Data Load도 포함
- Python Script를 그냥 실행하는 경우도 있고, Docker Image로 실행하는 경우도 존재
Data
- 서비스에서 사용하는 DB(AWS RDS 등) 또는 데이터 웨어하우스에 저장
- 서비스 서버에서도 데이터를 불러오는 스케줄링 Job이 존재 => 특정 시간 단위로 가져옴
Web Single 패턴
모델이 항상 Load 된 상태에서 예측을 해주는 API 서버를 만들고, 추천 결과가 필요한 경우에 서비스 서버에서 이 예측 서버에 직접 요청을 하면 어떨까? => Online Serving핵심
장점
고민할 점
Use Case
예측/추론 Server
FastAPI, Flask 등으로 단일 REST API 서버를 개발 후 배포
- 예: POST api-server-url/predict로 예측
API 서버가 실행될 때 모델을 로드
API 로직 내에 전처리도 같이 포함
Client
- 앱에서 직접 요창할 수도 있고, 앱이 서비스 서버에 요청하고 서비스 서버가 예측 서버에게 또 요청할 수도 있음 (개발을 어떻게 했는지에 따라 다르다)
- 웹 페이지라면 브라우저에 요청
Data
- 요청할 때 같이 데이터를 담아 요청
- 상황에 따라 데이터의 용량 제한이 있을 수 있음
Load Balancer
- 트래픽을 분산시켜서 서버에 과부하를 걸리지 않도록 해줌
- Nginx, Amazon ELB(Elastic Load Balancing) 등을 사용
Synchronous 패턴
하나의 작업이 끝날 때까지 다른 작업을 시작하지 않고 기다리고, 작업이 끝나면 새로운 작업을 시작하는 방식
FastAPI로 모델을 Web Single 패턴으로 구현하고, 클라이언트는 API 서버로 요청을 한 뒤 이 요청이 끝날 때까지 기다려야 하는 경우가 해당
핵심
앞에서 설명한 Web Single 패턴을 동기적(Synchronous)으로 서빙
기본적으로 대부분의 REST API 서버는 동기적으로 서빙
장점
고민할 점
Usecase
예측의 결과에 따라 클라이언트의 로직이 즉각적으로 달라져야 하는 경우

Asynchronous 패턴
하나의 작업을 시작하고 결과를 기다리는 동안 다른 작업을 할 수 있음
작업이 완료되면 시스템에서 결과를 알려줌
(음식점 진동벨과 유사)
Stynchronous 패턴으로 서빙한 결과 API 서버에서 이제 수많은 요청을 감당할 수 없어졌음
API 서버의 CPU와 memory를 증가하면 해소가 되긴 하겠지만 이건 비싸고 단기간 해결방법임. 나중에 또 요청 더 늘어가면 어떡할래?
그래서 등장한게 Asynchronous
API 서버의 부하가 늘지 않게 요청을 하며 다 처리할 수 있어야 하고, 클라이언트의 경우 당장의 결과를 받지 않더라도 최종적으로만 결과를 받으면 됨
핵심
앞에서 설명한 Web Single 패턴을 비동기적(Asynchronous)으로 서빙
장점
클라이언트와 예측 프로세스가 분리 => 관계가 의존적이지 않음
클라이언트가 예측을 기다릴 필요는 없음
고민할 점
Usecase
- Queue
- 클라이언트와 예측 서버 사이에 메시지 시스템(Queue)을 추가
- 대표적인 메시지 프레임 워크: Apache Kafka
- 지하철 물품 보관소와 유사한 역할
- Push:
메시지 저장- Pull:
메시지를 가지고 와서 작업(예측) 수행
권장되지 안는 패턴
실시간 대응이 필요한 온라인 서비스에 예측이 오래걸리는 모델을 사용하는 경우
요청에 대한 응답이 막 10초씩 걸린다.. ㅠㅠ
문제
대안
하나의 서버에 여러 예측 모델을 띄우는 경우...
predict1, predict2, predict3으로 나눠서 하나의 서버에서 모두 실행하는 경우