요구사항은 다음과 같았다.
- 매 달 특정 카테고리별로 daily 영어 단어 및 관련 문제 생성 및 저장
- 사용자가 문제를 풀 수 있는 기능을 웹에서 제공
- 매 일 일정시간에 문제 풀 수 있는 웹 URL을 메일로 발송
Spring Batch와 Kafka를 결합하여 문제 생성 및 이메일 발송을 처리하고, 사용자가 문제를 풀고 답을 체크할 수 있도록 구현하고자 했다. 다음은 스프링 배치와 카프카를 사용하게 된 이유와 각 기술 스택의 특성을 정리해보았다.
이번 글에서는 스프링 배치만 다루도록 하겠습니다.
Spring Batch는 대량의 데이터를 효율적으로 처리하기 위한 배치 처리 프레임워크이다. 배치 처리(batch processing)는 특정 시간에 일괄적으로 데이터를 처리하는 방식으로, 은행의 대량 거래 처리, 이메일 대량 발송, 통계 데이터 분석 등에 사용된다.
Spring Batch는 Job과 Step이라는 두 가지 주요 구성 요소로 나뉜다.
스프링 배치가 대량 데이터를 처리하고, 확장 가능하며 신뢰성을 가질 수 있는 원리는 무엇일까 생각해보게 되었다.
스프링 배치에서는 데이터를 작은 단위(Chunk)로 나누어 처리한다. 데이터를 한 번에 모두 처리하지 않고, 일정량의 데이터를 처리한 후 그 결과를 저장함으로써 시스템의 안정성과 성능을 높일 수 있다.
Chunk 기반 처리의 기본적인 흐름은 다음과 같다:
Chunk 크기는 개발자가 조정할 수 있다. Chunk 크기가 작을수록 자주 데이터를 저장하므로 안정성은 높아지지만 성능이 떨어질 수 있다. 반면, Chunk 크기가 클수록 성능이 높아지지만 오류 발생 시 재처리해야 할 데이터가 많아진다.
Spring Batch는 대량 데이터를 처리할 때 병렬 처리 기능을 제공한다. 병렬 처리를 통해 여러 스레드 또는 프로세스가 동시에 데이터를 처리하여, 처리 시간을 단축할 수 있다.
멀티스레드 방식과 파티셔닝이 무슨 차이가 있을까 고민을 했는데, 논리적으로 데이터를 분리할 수 있는가 아닌가에 따라 갈린다. 멀티스레드 처리는 하나의 데이터 셋을 여러 스레드가 처리하는 방식이고, 파티셔닝은 하나의 데이터 셋을 독립적으로 분리시켜서 처리하는 방식이다.
Spring Batch는 각 Chunk를 트랜잭션 단위로 처리합니다. 데이터를 처리하는 도중에 오류가 발생하면 해당 Chunk의 모든 작업이 롤백되고, 이전에 커밋된 데이터는 영향을 받지 않는다. 이를 통해 데이터의 일관성을 보장할 수 있다.
배치 작업이 중간에 중단되더라도, Spring Batch는 작업 상태를 기록하여 재시작 가능한 구조를 제공한다. 배치 작업을 재시작하면, 중단된 지점부터 이어서 작업을 수행한다.
문제들의 데이터 셋을 어떻게 처리할 지 고민하다가, 스프링 배치와 카프카를 찾게 되었다. 더 자세한 구동 원리와 예제 코드를 살펴보면서 학습해야할 필요성을 느끼게 되었다. 또한, '스프링' 배치이니만큼 스프링에서 제공하는 여러 기능들이 있을텐데, 이 부분에 대해서도 구현하면서 추가적으로 학습하고 싶은 마음이 들었다.