Spring Batch : Step 도메인 이해

    이 글은 인프런 정수원님의 강의를 복습하며 정리한 글입니다.

     

    Step Execution

    기본개념

    • Step Execution은 Step이 실행될 때 마다 생성됨.
    • Step이 한번 실행될 때, 실행 중 발생 정보를 저장한 객체
    • Job이 재시작할 때, 기본적으로 성공한 Step은 재시작하지 않음. 따라서 재시작하지 않는 Step은 StepExecution이 생기지 않고, 재시작하는 Step은 StepExecution이 생성됨.
    • StepExecution 중 하나라도 실패가 있으면, 관련된 JobExecution은 항상 실패. 모두 성공 시, Job Execution은 성공.

     

    DB 스키마 매핑

    • BATCH_STEP_EXECUTION 테이블과 매핑됨.
    • JOB_EXECUTION과 STEP_EXECUTION은 1:M 맵핑

     

    실제 실행과 DB 확인

    JobExecution은 모든 StepExecution의 실행이 정상적으로 완료되어야 Batch_Status가 Completed가 된다. StepExecution 중 하나라도 실패가 발생하면, JobExecution의 Batch_Status는 Failed가 된다. 이 상황을 확인하기 위해서 아래와 같은 상황을 가정하고 DB 테이블을 확인해본다.

    1. 첫번째 Job 실행 → STEP1 성공, STEP2 실패.
    2. 첫번째 Job 재실행 → STEP2 성공.

    첫번째 Job은 Step2에서 실패를 했다. 따라서 JobExecution의 첫번째 Batch Status는 Failed가 된다.

    Step Execution을 확인해본다. Step1은 성공했던 Step이기 때문에 다시 재수행하지 않는다. Step2는 처음 수행 결과가 Failed였기 때문에 Job이 재실행할 때, 다시 수행한다. Step2의 재실행 결과는 Completed가 되었고, 이제 Job Execution의 Batch Status는 Completed가 된다.

     

    StepExecution Column

    • Batch_Status : 현재 Step의 실행 상태를 알려줌
    • Exit_Status : Step의 실행 결과를 알려줌.
    • Execution_Context : Step이 실행하면서 가지고 있는 데이터를 가진 객체를 가지고 있음.
    • FailureExceptions : 실행 중 발생한 예외 리스트를 가지고 있음. 

    이 외에도 더 많은 Column들이 있지만, 대부분 Column 명을 보고 유추가 가능하다.

     

     

    Step Contribution

    기본개념

    • Chunk Process의 변경 사항을 저장해둔 다음, StepExecution의 상태를 업데이트하는 객체
    • Chunk Commit 직전에 StepExecution의 apply 메서드를 호출해 상태 업데이트함.

     

    구조

    readCount / writeCount / filterCount / parentSkipCount / readSkipCount/ StepExecution / ExitStatus 등 주로 Chunk Process에서 일어난 데이터 정보를 가지고 있고, StepExecution의 값, 그리고 ExitStatus의 값을 가지고 있음. 

     

     

    저장 방법

    taskletStep이 실행하는 시점에 StepExecution과 StepContribution을 생성한다. Chunk는 processor / reader / writer를 통해서 Chunk 처리를 하는데, 이 때 발생한 값들을 StepContribution에 저장해둔다. 그리고 Chunk가 완료되고 Commit 되기 직전에 StepContribution을 StepExecution에 apply 메서드를 이용해 저장한다. 즉, 단일 비즈니스 로직이 아닌 Chunk처럼 대규모 데이터 처리를 할 때 데이터 처리 결과를 저장하기 위한 방편이다. 

     

     

    Execution Context

    기본 개념

    • 프레임워크에서 StepExecution / JobExecution 정보를 저장하기 위한 객체.
    • DB에는 JSON 형식으로 직렬화 되어 저장됨 ( {"key" : "value"} 형식)
    • JobExecutionContext는 Job끼리 공유 안됨. Job에 포함된 Step들에게는 공유됨.
    • StepExecutionContext는 Step끼리 공유 안됨.

     

    구조 

    ExecutionContext는 내부적으로 ConcurrentHashMap을 가지고 있다. 이 ConcurretnHashMap의 Value Type은 Object로 어떤 값도 들어갈 수 있다. 

     

    객체 관점

    StepExecution은 JobExecutionContext를 꺼낼 수 있다. StepExecution은 JobExecution을 참조하고, JobExecution은 내부적으로 ExecutionContext를 참조하기 때문이다. 따라서 getter를 이용해서 찾아올 수 있다. 

    또한 Job이 가지는 ExecutionContext가 Step끼리 공유할 수 있다는 것을 감안하면, Step간의 데이터를 전달해주는 역할을 해줄 수도 있다. 유용할 수도 있는데, 기본적으로 Step은 독립적이기 때문에 데이터를 공유하지 않기 때문이다. 

     

    실제 실행 관점

    예를 들어 다음과 같이 Execution Context에 각각 값을 넣으면 어떻게 될까? 그리고 DB에는 어떻게 저장이 될까? 우선 값을 넣게 되면 ExecutionContext가 가지는 ConcurrentHashMap에 값이 key / value 형식으로 저장되게 된다. 그리고 DB에는 이 key / Value 형식이 직렬화 되어 저장된다.

    job_execution_id short_context serialized_context
    1 { “inputCount” : “150” , “date” : “20210101”}  

    JobExecutionContext는 다음과 같은 형태가 된다. 

    step_execution_id short_context serialized_context
    1 {"batch.taskletType":"io.batch.springbatch.job.HelloJobConfiguration$1",
    "name":"leaven",
    "batch.stepType":"org.springframework.batch.core.step.tasklet.TaskletStep"}
     

    StepExecutionContext는 다음과 같은 형태로 DB에 저장된다.

     

     

     

     

    댓글

    Designed by JB FACTORY