Youtube 개발자 인큐티비의 SpringBatch 편을 참고하여 질문지를 리스트업 했습니다.
- 왜 스프링 배치를 사용하는가?
- 대용량 데이터를 처리해야 함
- 사용자 개입 없이 동작
- 로깅, 통계처리, 트랜잭션 등의 비즈니스 로직 외에 배치 어플리케이션에 필요한 기능 사용 가능
- 지정한 시간 내에 다른 어플리케이션을 방해하지 않고 수행
- 충돌이나 중단 되었을 때 컨트롤이 가능함
- 멱등성은 어떻게 유지하는가?
- 멱등성 : 연산을 여러번 적용하더라도 결과가 달라지지 않는 성질
- Spring Batch Job Parameter를 사용하여 외부에서 값을 주입받도록 하여 제어가 불가능한 코드를 제거한다.
- ex) LocalDateTime.now()
- 멱등성이라는 패러다임이 Spring Batch와는 적합하지 않다는 내용의 의견도 많다. (https://namocom.tistory.com/752)
- Job Parameter를 이용해 외부에서 주입하는 것은 책임의 이동 정도로 이해하자는 의견도..
- Spring Batch 메타 데이터 테이블은 어떤 것이 있는가?
- (맨 하단 ERD 참고)
- BATCH_JOB_INSTANCE (최상위)
- Job Instance 객체의 정보를 담고 있음
- BATCH_JOB_EXECUTION_PARAMS
- Job Parameter 정보를 담고 있음, Job 실행 시 사용된 파라미터 저장
- 정규화되지 않은 형태의 테이블로 TYPE_CD 컬럼에서 저장되는 파라미터 타입을 가진다.
- BATCH_JOB_EXECUTION
- Job Execution 객체의 정보를 가지고 있음, Job이 run 할 때마다 row가 추가됨
- BATCH_STEP_EXECUTION
- Step Execution 객체의 정보와 대응되는데 하나의 Job Execution에서 사용하는 Step 개수만큼 테이블의 row에 추가된다.
- 배치가 돌아서 처리한 개수를 알고 싶을 때는 이 테이블을 찾아보면 된다.
- BATCH_JOB_EXECUTION_CONTEXT
- 하나의 Job Execution 에 대해 하나의 Job Execution Context가 존재하며, Job레벨의 모든 데이터를 다 가지고 있다.
- BATCH_STEP_EXECUTION_CONTEXT
- 하나의 Step Execution 에 대해 하나의 Step Execution Context가 존재하며,
- JobInstance가 중단된 위치에서 다시 시작할 수 있도록 실패 후 검색되어야 하는 정보도 담고 있음
- 배치 중간 실패하면 어떻게 처리하는지?
- skip
- 데이터를 처리하는 동안 설정된 Exception이 발생했을 경우, 해당 데이터 처리를 건너뛰는 기능
- default 값은 0으로 사용을 원하는 경우 반드시 0 이상의 숫자를 입력해주고, 어떤 Exception을 skip 할 것인지 반드시 명시해주어야 한다.
- chunk 내부에서 이뤄지는데 Read/Process/Write 하는 과정에 설정해줄 수 있다.
- retry (아래 그림 참고)
- 데이터를 Process/Write 하는 과정에서 설정된 Exception이 발생했을 경우, 지정한 정책에 따라 데이터 처리 재시도 하는 기능.
- Read과정에서 주로 발생하는 FlatFileParseException 에 대한 문제는 대부분 Skip에서 처리가 된다.
- 예를 들면 DeadlockLoserDataAccessException 발생 시 Retry가 일어나도록 설정할 수 있다. 다른 프로세스에서 처리중인 데이터에 새로운 프로세스가 접근하면 Locak이 걸려 있어 에러가 발생하는데 Retry를 하면 성공할 수 있을 것이다.
- skip
- 트랜잭션 관리 왜 청크단위로 하는가?
- Chunk
- 각 커밋 사이에 처리되는 row 수
- Chunk 지향 처리란?
- Chunk 단위로 트랜잭션을 다루는 것
- Reader와 Processor에서는 1건씩 다뤄지고, Writer에선 Chunk 단위로 처리
- Reader에서 데이터를 하나 읽어옵니다
- 읽어온 데이터를 Processor에서 가공합니다
- 가공된 데이터들을 별도의 공간에 모은 뒤, Chunk 단위만큼 쌓이게 되면 Writer에 전달하고 Writer는 일괄 저장합니다.
- Why Chunk?
- 커밋을 매번 하면 비용이 많이 듭니다. 데이터가 많은 경우라면 (Spring Batch를 사용한다면 당연하겠죠?) 매번 커밋을 하는 것은 이상적이지 않고, 각 트랜잭션에서 가능한 한 많은 항목을 처리하는 것이 바람직합니다. 이러한 이유로 한 커밋 내에서 처리하는 수를 chunk로 관리하게 된 것입니다.
- Chunk-oriented 프로세싱을 하게 되면 다양한 기능들을 사용할 수 있는 것이 장점인데 skip, retry, 특정 Exception에 대한 Rollback, 다양한 ItemReader 그리고Cursor, Paging 등이 대표적이다.
- Page Size와 Chunk Size
- PagingItemReader를 사용하면 보이는 Page Size는 한번에 조회할 Item의 양이고, Chunk Size는 한번에 처리될 트랜잭션 단위이다.
- 보편적으로 두개의 사이즈 크기는 일치하는게 좋다.
- Chunk
- Cursor 기반 vs Paging 기반
- Cursor는 한칸씩 커서를 옮기면서 데이터 1 Row씩을 가져온다.
- 배치 처리가 완료될 때까지 데이터를 읽어오기 때문에 DB Connection Time이 Paging보다 길다.
- 모든 데이터를 메모리에 저장하기 때문에 메모리 사용량이 많다.
- Paging은 설정한 PageSize 만큼 데이터를 가져오며 데이터 결과의 순서가 보장될 수 있도록 order by 사용 필요
- PageSize만큼 DB Connection을 읽고 종료한다. 따라서 Cursor에 비해 상대적으로 DB Connection Time이 적다.
- 하지만 트랜잭션을 여러번 타야하는 단점이 있긴 하다.
- Cursor는 한칸씩 커서를 옮기면서 데이터 1 Row씩을 가져온다.
- Multi Thread & Partitioning
- 정해진 시간 안에 많은 데이터를 처리하기 위해 성능을 높이기 위해 사용하는 방법
- 서비스에 적재된 데이터가 적을 경우에는 Spring Batch의 기본 기능들만 사용해도 큰 문제가 없으나, 데이터가 엄청나게 많이 쌓일시 배치 애플리케이션 역시 확장이 필요
- Multi-threaded Step (아래 그림 참고)
- 단일 Step을 수행할 때, 해당 Step 내의 각 Chunk를 별도의 여러 쓰레드에서 실행하는 방법
- 정한 개수(throttleLimit)만큼의 스레드를 생성하여 수행하는데 ItemReader는 반드시 Thread-safe인지 확인해야 하며(데이터를 중복으로 읽어 오지 않게 하기 위해) 스프링 배치에서 제공하는 것중 JdbcPagingItemReader, JpaPagingItemReader가 Thread-safe하다.
- Partitioning
- Master가 데이터를 파티셔닝 한 다음 Slave가 개별 스레드를 통해 각 파티션을 처리하는 방식
- 각 SlaveStep은 ItemReader / ItemProcessor / ItemWriter 등을 갖고 동작하며 작업을 독립적으로 병렬 처리합니다.
- Multi-threaded 는 Thread-safe를 신경써야 하나 Partitioning은 Thread-safe하지 않아도 됩니다.
- tasklet model vs chunk (reader,processor,writer)
- Step은 Tasklet 혹은 Chunk로 처리할 수 있다.
- When to use
- Tasklet
- 실행할 작업이 간단하여 집계가 필요없고, 실행만 필요한 경우
- Chunk
- 실행할 작업이 복잡하고 청크 지향 처리를 사용하는 읽기, 처리 및 쓰기와 관련된 작업 실행이 포함된다고 가정합니다.
- Tasklet
- Batch 실행은 어떻게 하는지
- Jenkins로
- 모니터링은 어떻게?
- 예전에는 Spring Batch Admin이 있었는데 deprecated 되었고, 현재는 spring에서 Spring Cloud Data Flow 를 사용하라고 한다.
- 요건 직접 사용해보고 내용 추가해보겠습니다~
참고
https://jojoldu.tistory.com/489
https://docs.spring.io/spring-batch/docs/current/reference/html/step.html#commitInterval
https://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte2:brte:batch_core:skip_repeat_retry
'스프링 > Spring Batch' 카테고리의 다른 글
Spring Cloud Data Flow & Spring Batch 사용 (실패), docker-compose 파일 (0) | 2023.03.22 |
---|---|
Spring Batch를 사용하며 맞닥뜨린 상황 기록 02 (0) | 2023.02.28 |
Spring Batch를 사용하며 맞닥뜨린 상황 기록 01 (0) | 2023.02.14 |
Spring Batch - @JobScope, @StepScope / LocalDate 사용법 (0) | 2022.10.25 |
Spring Batch 에 대한 이해 (0) | 2021.02.08 |