개발자로서 어플리케이션을 개발하고 운영하다보면 자연스럽게 사용자가 늘어나고
비즈니스가 커져감에 따라 성능을 개선해야할 필요성이 생기게 된다.
이때 자연스럽게 고민하게 되는 것이 확장인데,
Spring Batch에서는 공식적으로 4가지의 확장 방법을 가지고 있다.
1. Multi-threaded Step
2. Parallel Steps
3. Partitioning
4. Remote Chunking
이 중에서 Remote Chunking 방법은 Message Queue를 통한
방법으로 고급스킬에 속하기 때문에 추후에 공부하는 것으로 하고,
우선은 위 세 가지 확장 방법에 대해서만 공부해보고자 한다.
Multi-threaded Step
Multi-threaded Step 방식을 사용하면
chunk 단위를 병렬로 실행시켜 빠르게 구동시킴으로써 성능을 개선할 수 있다.
하지만, 멀티 쓰레드로 데이터에 접근하기 때문에
레이스 컨디션이 발생할 수 있다는 단점이 있다.
여기서 레이스 컨디션이란 멀티 쓰레드 환경에서
여러 쓰레드가 동시에 동일한 데이터에 접근하거나 수정할 경우
발생할 수 있는 문제를 일컫는다.

따라서 Multi-threaded Step 방식을 사용하려면
직접 thread-safe하게 구현체를 구현하거나
Spring Batch공식문서를 확인하여 thread-safe한 구현체만을 사용해야한다.

물론 Java docs에서도 thread safe 한지 확인할 수 있다.

Multi-threaded Step을 적용하는 방법은 매우 간단한데,
taskExecutor를 SimpleAsyncTaskExecutor로 바꾸어주면 된다.

Parallel Steps
아래 이미지와 같이 Parallel Steps는
Step2와 Step3,4가 병렬적으로 함께 실행되는 구조이다.

Parallel Steps는 아래와 같이 Flow Step을 활용해서 구현할 수 있다.

Partitioning
Partitioning은 Manager Step이 있고 그에 대응되는 Worker Step들이 있다.
Manager Step은 전체 작업을 관리하는 역할을 한다.
즉, 큰 작업을 여러 개의 작은 작업으로 나누고,
각 작은 작업을 Worker Step으로 분배한다.
Worker Step은 작은 작업을 실제로 처리하는 단위이다.
각 Worker Step은 독립적으로 실행되며, 나누어진 작업을 병렬로 처리한다

Manager Step(=Master Step)에는 Partitioner와 PartitionHandler가
존재한다.

PartitionHandler
PartitionHandler에서는
Master Step이 Worker Step을 어떻게 다룰지에 대해 정의한다.
즉, Master Step이 여러 개의 Worker Step을
실행하고 관리하는 방식에 대한 구체적인 규칙을 설정하는 것이다.


여기서 GridSize는 Worker Step의 Size와 같다.

Partitioner
여러 개의 Worker Step을 만들 때,
각 Step이 처리할 작업의 범위나 데이터 분할을 담당하는 역할을 한다.

Map의 형태로 반환이 되고,
Map 안에는 각각의 Worker Step들이 처리해야하는 범위가
minValue, maxValue 값으로 표현된다.

queryString에 minValue와 maxValue를 넣어 사용한다.
