Spring

Spring batch란

leeheefull 2022. 6. 30. 00:35

해당 글은 이론 위주의 설명입니다. 실제로 구현한 예제는 여기에서 볼 수 있습니다.

 

 

이번에 배치 모듈을 사용해보게 됐습니다. 한 번도 배치 모듈을 사용해본 적이 없었지만, 앞으로 배치를 자주 사용하게 될 것 같아 공부하면서 내용을 정리해보려 합니다.

 

 

 

 

왜 사용할까?

 

크롤러로 어떤 사이트의 정보를 주기적으로 긁어 온다고 가정해보겠습니다. 크롤링할 때마다 개발자가 직접 API로 수행해야 할까요? 아닙니다. 자동으로 할 수 있다면 좋을 것입니다.

 

또한, 크롤링하는 정보의 양이 상당히 많다면 서버의 자원을 다 써버려서 다른 작업을 수행하기에 어려운 상태가 됩니다. 그렇다면, 사용량이 적은 시간대인 새벽에 처리한다면 좋을 것입니다.

 

그리고, 1억 개를 처리한다고 할 때 5만 번째에서 실패를 했는데 자동으로 5만 1번 째부터 다시 실행할 수 있다면 이것 또한 굉장히 편할 것입니다.

 

이처럼 배치는 보통 실시간 처리가 어려운 대용량 데이터나 대규모 데이터일 경우에 배치 애플리케이션을 작업합니다.

 

 

 

 

Batch

 

배치는 일괄처리라는 뜻을 갖고 있습니다. 그리고 배치 애플리케이션은 아래와 같은 특성을 갖고 있습니다.

 

(대용량 데이터)

배치 애플리케이션은 대량의 데이터를 가져오거나, 전달하거나, 계산하는 등의 처리를 할 수 있어야 합니다.

 

(자동화)

배치 애플리케이션은 심각한 문제 해결을 제외하고는 사용자 개입 없이 실행되어야 합니다.

 

(견고성)

배치 애플리케이션은 잘못된 데이터를 충돌/중단 없이 처리할 수 있어야 합니다.

 

(신뢰성)

배치 애플리케이션은 로깅이나 알림 등처럼 무엇이 잘못되었는지를 추적할 수 있어야 합니다.

 

(성능)

배치 애플리케이션은 지정한 시간 안에 처리를 완료하거나 동시에 실행되는 다른 애플리케이션을 방해하지 않도록 수행되어야 합니다.

 

 

 

 

Spring batch

 

스프링 배치는 스프링 프레임워크와 배치 프레임워크를 합친 것입니다. 스프링의 특성을 그대로 가져왔기 때문에 DI나 AOP 등을 사용할 수 있습니다. 이를 이용하여 보다 더 효율적인 배치 애플리케이션을 만들 수 있습니다.

 

스프링 배치를 사용하기 위해서는 여러 가지 개념 및 키워드를 알아야 합니다. 간단하게 설명하겠습니다.

 

 

 

 

Batch meta table

 

https://user-images.githubusercontent.com/58816862/176469511-f30cc009-3500-4170-92bb-eb24bae30391.png

 

위의 테이블들은 스프링 배치의 메타 테이블이라고 하는 것입니다. 배치가 실행될 때 관련된 모든 것을 기록하는 역할을 합니다. 중요한 테이블 몇 개에 대해 설명하겠습니다.

 

 

 

JOB_INSTANCE

 

일부러 예외를 발생시켜서 같은 Job을 여러 번 실행하고 Job Instance가 더 이상 생기지 않는 모습 확인

일부러 예외를 발생시켜서 같은 Job을 여러 번 실행하고 Job Instance가 더 이상 생기지 않는 모습 확인

 

JobInstance는 배치 처리에서 Job이 실행될 때 하나의 Job 실행 단위를 말합니다.

 

하루에 한 번 씩 배치의 Job이 실행된다고 가정하겠습니다. 어제 Job이 실패한다면, 다음 날에는 어제와 동일한 JobInstance를 가지고 실행하게 됩니다. 왜냐면, Job 실행이 실패하면 JobInstance가 끝나지 않는 것으로 간주하기 때문입니다.

 

그리고, 하나의 JobInstance는 실패한 어제의 JobExecution과 성공한 오늘의 JobExecution 두 개를 가지게 됩니다.

 

 

 

JOB_EXECUTION

 

일부러 예외를 발생시켜서 같은 Job을 여러 번 실행하고 Job Execution이 여러 개 생기는 모습 확인

일부러 예외를 발생시켜서 같은 Job을 여러 번 실행하고 Job Execution이 여러 개 생기는 모습 확인

 

JobExecution은 JobIstance에 대한 한 번의 실행을 나타내는 객체입니다. 오늘 Job이 실패하고 내일 다시 동일한 Job을 실행한다면, 오늘과 내일 모두 같은 JobInstance를 사용하지만 JobExecution은 다르게 됩니다.

 

JobExecution은 JobInstance와 배치 실행 상태, 시작 시간, 끝난 시간, 실패했을 때 메시지 등의 정보를 갖고 있습니다.

 

 

 

STEP_INSTANCE

 

일부러 예외를 발생시켜서 같은 Step을 여러 번 실행하고 Step Instance가 더 이상 생기지 않는 모습 확인

일부러 예외를 발생시켜서 같은 Step을 여러 번 실행하고 Step Instance가 더 이상 생기지 않는 모습 확인

 

JobInstance에 Job 인스턴스 정보가 있다면, Step에는 StepInstance라는 Step의 인스턴스 정보를 담는 것이 있습니다.

 

 

 

STEP_EXECUTION

 

일부러 예외를 발생시켜서 같은 Step을 여러 번 실행하고 Step Execution이 여러 개 생기는 모습 확인

일부러 예외를 발생시켜서 같은 Step을 여러 번 실행하고 Step Execution이 여러 개 생기는 모습 확인

 

JobExecution에 Job 실행 정보가 있다면, Step에는 StepExecution이라는 Step 실행 정보를 담는 것이 있습니다.

 

 

 

 

Spring batch object

 

https://user-images.githubusercontent.com/58816862/176475074-8368901a-6a92-43b7-9dab-c9b61f8569a3.png

 

 

Job

 

https://user-images.githubusercontent.com/58816862/176470729-05fa7a76-107c-4dbf-b8b8-039fc5da679d.png

 

Job은 배치 처리 과정을 하나의 단위로 만들어 표현한 객체입니다. 하나의 Job 객체는 여러 개의 Step 인스턴스를 포함할 수 있습니다.

 

Job 객체는 JobBuilderFactory로 쉽게 만들 수 있습니다. JobBuilderFactory는 JobBuilder를 생성할 수 있습니다. 그리고 JobBuilder로 Job을 생성할 수 있습니다.

 

 

 

Step

 

https://user-images.githubusercontent.com/58816862/176470839-4ce2b68a-0ac2-47a3-89c1-5e1cd6e2811e.png

 

Step은 실직적인 배치 처리를 정의하고 제어하는데 필요한 모든 정보가 있는 도메인 객체입니다. Job을 처리하는 실질적인 단위로 쓰입니다. Job과 Step은 1대 N관계입니다.

 

 

 

JobRepository

 

배치 처리 정보를 담고 있는 메커니즘입니다. 어떤 Job이 실행되었으면 몇 번 실행되었고 언제 끝났는지 등 배치 처리에 대한 메타데이터를 저장합니다.

 

또한, Step의 실행 정보를 담고 있는 StepExecution도 저장소에 저장하여 전체 메타데이터를 저장 및 관리하는 역할을 수행합니다.

 

 

 

JobLauncher

 

Job과 JobParamerters와 함께 배치를 실행하는 인터페이스입니다.

 

 

 

Tasklet

 

배치의 처리 방식은 테스크릿 방식과 청크 방식이 있습니다. 테스크릿 방식은 배치 처리 과정이 비교적 간단한 경우에 사용합니다. 반면, 청크 방식은 대량 처리를 하는 경우에 사용합니다.

 

테스크릿은 청크 방식인 Item 객체들을 대체할 수 있는 인터페이스입니다. 아래에서 설명할 Item 객체들은 읽어오는 것과 수행하는 것, 저장하는 것을 나누어 진행하였다면, 테스크릿은 단순하게 수행한다는 개념의 인터페이스입니다.

 

 

 

ItemReader

 

ItemReader는 Step의 대상이 되는 배치 데이터를 읽어오는 인터페이스입니다. File, Xml, Db 등 여러 타입의 데이터를 읽어올 수 있도록 하는 인터페이스입니다.

 

 

 

ItemWriter

 

ItemWriter는 배치 데이터를 저장합니다. 일반적으로 DB나 파일에 저장할 수 있도록 하는 인터페이스입니다.

 

 

 

ItemProcessor

 

ItemProcessor는 ItemReader로 읽어 온 배치 데이터를 변환하는 역할을 수행하는 인터페이스입니다.

 

 

 

 

Scope

 

Job Parameter와 Scope를 적용한 모습

Job Parameter와 Scope를 적용한 모습

 

스프링 배치에서는 외부나 내부 파라미터를 받아 여러 배치 컴포넌트에서 사용할 수 있게 지원하고 있습니다. 이것을 Job Parameter라고 합니다. 잡 파라미터는 스코프 빈을 생성할 때만 사용이 가능하기 때문에, 이를 사용하기 위해서는 스프링 배치 전용 스코프를 사용해야 합니다.

 

스코프란 변수에 접근할 수 있는 범위를 말합니다. 스프링 빈의 기본 스코프는 싱글톤이지만, 스프링 배치에서는 @JobScope와 @StepScope를 지원하고 있습니다.

 

@JobScope는 스텝 선언문에서 사용이 가능하고 잡 실행 시점에 해당 컴포넌트를 스프링 빈으로 생성합니다. @StepScope는 Tasklet, ItemReader, ItemWriter, ItemProcessor 등의 선언문에서 사용이 가능하고 스텝 실행 시점에서 해당 컴포넌트를 스프링 빈으로 생성합니다.

 

결론적으로, 스프링 배치 전용 스코프를 사용하면 빈 생성 시점을 지정된 스코프가 실행되는 시점으로 지연시킬 수 있습니다.

 

 

 

 

Chunk

 

[사진 출처](https://github.com/jojoldu/spring-batch-in-action/blob/master/6_CHUNK.md#6-1-chunk)

사진 출처

 

청크란, 데이터 덩어리로 작업할 때 각 커밋 사이에 처리되는 열의 수를 말합니다. 다시 말해서, 청크는 한 번에 하나씩 데이터를 읽도록 덩어리를 만든 것을 말합니다. 이렇게 청크 단위로 나눈 이유는 해당 단위로 트랜잭션을 구분하기 위해서입니다.

 

ItemReader로 데이터 하나를 읽고, ItemProcessor에서 가공을 한 뒤에 가공된 데이터 들을 별도의 공간에 모은 후에 청크 단위만큼 싸이게 되면 ItemWriter가 일괄 저장하게 되는 구조입니다.

 

결론적으로 Reader와 Processor에서는 한 건씩 다뤄지고, Writer에서는 청크 단위로 처리되게 되는 겁니다.

 

 

 

 

Reference