ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Batch - 스프링 배치 총정리
    개발 관련/Spring 2022. 3. 25. 16:08

    Spring Batch

    1. 개요

    1-1 배치란?

    배치(Batch)는 일괄처리라는 뜻입니다.

    실시간으로 할 필요가 없이 정해진 시간에 사람의 개입이 필요 없이 자동으로 진행되는 작업들을 batch 라고 합니다.

    1-2 배치 애플리케이션이란?

    대용량의 데이터를 처리하는 애플리케이션을 말합니다.

    배치 애플리케이션은 다음의 조건을 만족해야합니다.

     

    1. 대용량 데이터 : 배치 어플리케이션은 대량의 데이터를 가져오거나, 전달하거나, 계산하는 등의

    처리를 할 수 있어야 합니다.

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

    니다.

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

    4. 신뢰성 : 배치 어플리케이션은 무엇이 잘못되었는지를 추적할 수 있어야 합니다. (로깅, 알림)

    5. 성능 : 배치 어플리케이션은 지정한 시간 안에 처리를 완료하거나 동시에 실행되는

    다른 어플리케이션을 방해하지 않도록 수행되어야합니다.

    1-3 배치의 사용 이유

    • 대용량의 데이터를 처리할 때
    • 서비스에 영향을 끼치지 않기 위해 사용
    • 사용자 없이도 프로그램을 실행시키기 위해 사용

    1-4 Batch 와 Quartz

    • Spring Batch : 대용량의 데이터 배치 처리
    • Spring Quartz : 스케줄러의 역할

    전혀 다른 역할을 수행하며 Batch + Quartz 를 조합해서 많이 사용합니다.

    2. Spring Batch의 구조

    2-1 Job

    Job 이란 배치 작업의 단위입니다.

    Job 안에는 여러 Step이 존재하고 Step 안에는 Tasket 또는 Reader→Processor→ Writer 묶음이 존재

    합니다. 보통 2-10개의 Step으로 구성하는 것을 권장합니다.

    2-2 Step

    Step 이란 Tasklet 또는 읽기( Reader ) → 가공( Processor ) → 쓰기( Writer ) 의 묶음입니다.

    이 묶음을 Chunk 라고 부르는데 이 Chunk 단위 별로 트랜잭션이 이뤄집니다.

     

    Tasklet 이란?

    간단히 Component 라고 생각하면 되며 Step에서 작성하고 싶은 내용을 자유롭게 만들 수 있습

    니다. Tasklet 하나와 Reader & Processor & Writer 한 묶음이 같은 레벨입니다.

    따라서 Reader & Processor 가 끝나고 Tasklet으로 마무리 지을 수 없습니다.

    2-2-1 ItemReader

    ItemReader 란 인터페이스로 이름 그대로 데이터 읽기를 담당합니다.

    읽어들인 데이터를 반환하며 만일 null을 리턴할 경우에는 읽어야하는 모든 데이터의 마지막이라는

    뜻입니다.

    CursorItemReader : Streaming 으로 데이터 처리

     

    🖍 주의점 : Cursor는 하나의 Connection으로 Batch가 끝날때까지 사용되기 때문에 Batch

    가 끝나기전에 Database와 어플리케이션의 Connection이 먼저 끊어질수 있습니다.

    → 이런 경우에는 PagingItemReader 을 사용 !

     

    PagingItemReader : 데이터를 PageSize에 맞춰 가져옵니다.

    → 각 페이지마다 새로운 쿼리를 실행하므로 페이징시 결과를 정렬하는 것이 중요합니다.

    🖍 주의점 : 정렬 ( order ) 이 무조건 포함되어 있어야 합니다.

    2-2-2 ItemProcessor

    ItemProcessor는 ItemReader에게서 Object를 넘겨받아 원하는 방식으로 가공한 후

    ItemWriter에 넘겨주는 역할을 합니다.

    또한 필터 즉 Writer에 값을 넘길지 말지를 Processor에서 판단할 수 있습니다.

    인터페이스이며 제너릭에 InputType 과 OutputType 을 지정해줘야합니다.

    Input은 ItemReader 에게서 넘겨받는 타입, Output은 ItemWriter에게 넘겨줄 타입입니다.

    • ItemProcessor<I,O> 의 I : ItemReader에서 받을 데이터 타입
    • ItemProcessor<I,O> O : ItemWriter에 보낼 데이터 타입

    즉, ItemReader 의 T = ItemProcessor<I,O> 의 I : 같은 타입

     ItemProcessor<I,O> 의 O = ItemWriter<T> T  :  같은 타입

    ItemProcessor 는 반드시 필요한 것은 아니며 데이터를 가공할 필요가 없다면

    ItemReader → ItemWriter 로 바로 넘겨도 상관없습니다.

    2-2-3 ItemWriter

    ItemWriter는 출력하는 역할을 합니다.

    ItemWriter는 Chunk 단위로 묶인 item List를 다룹니다.

    ItemReader 혹은 ItemProcessor가 ItemWriter로 데이터를 넘겨주면 item List에 차곡 차곡

    쌓이게 되는데 Step 에서 정의된 개수만큼 데이터가 모이면 write 메소드를 실행하게 됩니다.

    2.3 Chunk 지향 처리

    • Reader에서 데이터를 하나 읽어옵니다.
    • 읽어온 데이터를 Processor에서 가공합니다. ( 생략 가능 )
    • 가공된 데이터들을 별도의 공간에 모은 뒤, Chunk 단위만큼 쌓이게 되면 Writer에 전달하고→ Reader와 Processor에서는 1건씩 다뤄지고, Writer에선 Chunk 단위로 처리됩니다.
    • Writer는 일괄 저장합니다.

    Chunk Size는 보통 1만건 정도가 적당합니다. 만약 Chunk Size를 크게 잡는다면 ,예를 들어 10만건,

    해당 Batch의 속도는 빨라지겠지만 Chunk Size 만큼 메모리가 확보되야하기 때문에

    다른 프로그램에 영향을 미칠 수 있습니다.

    그렇기 때문에 적절한 크기로 Chunk를 쪼개는 것이 중요합니다.

    2.3.1 Chunk 지향 처리를 왜 사용하는 걸까?

    위와 같이 Reader Writer 구조를 안쓰게 된다면 잘못하다간 처리 시간이 지수함수로 증가할

    위험이 있습니다. 왜냐하면 DB에서 데이터를 가져올 때 커넥션에서 비롯되는 시간 등등이 처리

    시간에 영향을 미치기 때문입니다. 또한 안정성이 떨어집니다.

    그렇기 때문에 Chunk 지향 처리를 하는것이 안정적이며 처리 속도면에서도 효율적입니다.

    3. Metadata Table

    Spring Batch는 위의 6개의 테이블이 존재해야 실행됩니다.

    3-1 BATCH_JOB_INSTANCE

    job 이 실행되면 BATCH_JOB_INSTANCE에 새로운 row를 만듭니다.

    Job Parameter에 따라 생성되는 테이블입니다.

     

    Job parameter : Spring Batch가 실행될때 외부 또는 내부에서 받을 수 있는 파라미터입니다.

    Map 형식입니다. 같은 Batch Job 이라도 Job Parameter가 다르면 Batch_JOB_INSTANCE에는 기록되며

    Job Parameter가 같다면 기록되지 않습니다.

     

    Job Instance = Job + Job parameter

    3-2 BATCH_JOB_EXECUTION

    BATCH_JOB_INSTANCE의 자식 테이블로 JOB_INSTANCE가 성공/실패했던 모든 내역

    즉, Job의 실행 내역을 가지고 있습니다.

    3-3 BATCH_JOB_EXECUTION_CONTEXT

    Job 안에 있는 step 등이 정보를 교환해야할 때 BATCH_JOB_EXECUTION_CONTEXT을 사용해 정보를 넣거나 빼올 수 있습니다.

    이하 STEP 관련 테이블도 위 테이블과 Step 에서 같은 역할을 수행합니다.

    4. Job Flow

    Step 에서는 Batch 에서 실제로 처리하고자 하는 기능과 설정을 모두 포함하고 있습니다.

    그러다 보니 Job 내부의 Step 사이에서 순서 또는 처리 흐름을 제어할 필요가 있습니다.

    4-1 Next

    • next () : 순차적으로 Step들을 연결시킬 때 사용합니다.

    ex ) step1 → step2 → step3 ...

    4-2 Flow ( 조건별 흐름 제어 )

    next 는 앞의 step 에서 오류가 나면 나머지 뒤에 있는 step 들은 실행되지 못합니다.

    상황에 따라 다른 Step을 사용해야할 때가 있습니다.

    예를들면 step A 다음 step으로 진행한다고 했을때

    정상 ) step A → step B

    오류 발생 ) step A → step C

    이런 식으로 수행해야 할 때 , Spring Batch에는 2 가지 선언 방법이 존재합니다.

    1. java Config
    2. xml

    이때 java Config 방법에서 사용할 수 있는 메소드는 아래와 같습니다.

    • .on () : 캐치할 ExitStatus 지정
    • ex) .on( FAILED )
    • to () : 다음으로 이동할 Step 지정
    • from () : 이벤트 리스너같은 역할. ( 추가적로 이벤트를 캐치하려면 from 을 써야합니다.)
    • end () : 종료

    ✔ BatchStatus 와 ExitStatus ?

    • BatchStatus : Job 또는 Step 의 실행 결과를 Spring에서 기록할 때 사용하는 Enum입니다.
    • ExitStatus : Step의 실행 후 상태를 뜻합니다. ( Enum 이 아닙니다 ! )

    4-3 Decide (✨ 중요 ✨) - next 의 확장 구조

    Step 들의 Flow 속에서 분기만 담당하며 JobExecutionDecider 라고 합니다.

    • start () : job Flow의 첫번째 Step 을 실행합니다.
    • next () : startStep 이후에 decider를 실행합니다.
    • from () : 이벤트 리스너 역할

    예를 들어 대량의 키워드를 규정에 맞게 변환시켜줘야 할 때 키워드 목록을 csv 파일로 받은 뒤

    차곡 차곡 쌓아 두었다가 한번에 batch를 돌린다고 가정해보겠습니다.

    앞서 Spring Batch 는 Chunk 지향 처리를 한다고 했는데 이렇게 되면 어떤 단위로 Chunk를

    나눠야 할지 상당히 애매해집니다. 왜냐하면 각각의 파일에는 각각 다른 갯수의 키워드가 있기

    때문입니다. 이때 우리는 크게 2가지 방법을 선택할 수 있습니다.

    1. 모든 파일의 키워드를 통합시킨다.
    2. decide를 사용한다.

    4-3-1 모든 파일의 키워드를 통합시킨다

    모든 파일의 키워드를 통합시킨뒤 chunk로 나뉘어서 하는 방법이 있습니다.

    만약 통합시키는 코드가 간단하다면 이 방법을 사용해도 괜찮습니다.

    하지만 만일 통합시키는 코드가 복잡하다면 ... ?

    4-3-2 decide를 사용한다.

    위의 예시로 설명을 하자면 키워드 리스트를 받은 뒤 decider 가 리스트면 다른 스텝으로 진행시키고

    리스트가 없다면 complete 한다고 합시다.

    Step A → Decider → (리스트가 있을 때 ) → Step B ( 컨버팅이 완료되면 다시 Decider 로)

                             → ( 리스트가 없을 때 ) Complete  !

    이런 식으로 Decider를 사용할 수 있습니다.

    5. Scope 와 Job Parameter

    Job Parameter를 사용하기 위해서는 항상 Spring Batch 전용 Scope를 선언해야합니다.

    Scope에는 크게 2가지가 있으며 사용시 구현부에 다음과 같은 annotation이 강제됩니다.

    1. @StepScope : Tasklet 사용시 사용
    2. @JobScope : Step 사용시 사용
    • 사용 방법
    @Value("#{jobParameters[파라미터명]}")

    5-1 JobParameter 주의 사항

    1. JobParameter는 @Value를 통해서만 값을 할당 받을 수 있습니다.
    2. @JobScope@StepScopeBean을 생성할때만 Job parameter가 생성되어 사용 할 수 있습니다.

    * 출처 : https://jojoldu.tistory.com/category/Spring%20Batch  

     

    'Spring Batch' 카테고리의 글 목록

    Java, TypeScript, ORM, RDBMS, AWS 를 주로 다루고 공유합니다.

    jojoldu.tistory.com

    * 잘못된 부분이 있으면 댓글로 알려주세요~!

    댓글

Designed by Tistory.