본문 바로가기
Project/Tech_review

스프링 배치

by 스타트업_디벨로퍼 2021. 2. 26.

배치 애플리케이션이란?

💡
배치는 사전적인 정의로 집단이나 무리를 한번에 묶다라는 의미로서, 실제 개발에서는 한번에 일괄 처리하는 애플리케이션이라고 보면 된다. 실제 배치를 적용한 애플리케이션으로는 - 매출 데이터를 이용한 일매출 집계 - 매우 큰 데이터를 활용한 보험급여 선정 - 트랜잭션 방식으로 포맷, 유효성 확인 및 처리가 필요한 내부 및 외부 시스템에서 수신한 정보를 기록 시스템으로 통합

💡
일반적으로 배치는 실시간 대응 보다는 집계의 목적이 강하므로, 사용자의 이용빈도가 적은 시간대에 특정 주기를 갖고 집계하는 특징을 갖음. 예를 들어, 메일 구독 서비스의 경우 : 정해진 시간에 구독을 신청한 회원에게 일괄전송하지만, 다른 정보를 열람하거나 하는 경우에도 다른 서비스에 영향을 주지 않는다.!

💡
배치 애플리케이션이 필요한 상황 : 일정 주기로 실행해야 할 때 - 실시간 처리가 어려운 대량의 데이터를 처리해야할 때 → 이런 작업을 하나의 애플리케이션에서 수행하면 성능 저하를 유발할 수 있으니 배치 애플리케이션을 구현한다.

💡
배치 어플리케이션은 다음의 조건을 만족해야만 합니다. 대용량 데이터 - 배치 어플리케이션은 대량의 데이터를 가져오거나, 전달하거나, 계산하는 등의 처리를 할 수 있어야 합니다. 자동화 - 배치 어플리케이션은 심각한 문제 해결을 제외하고는 사용자 개입 없이 실행되어야 합니다. 견고성 - 배치 어플리케이션은 잘못된 데이터를 충돌/중단 없이 처리할 수 있어야 합니다. 신뢰성 - 배치 어플리케이션은 무엇이 잘못되었는지를 추적할 수 있어야 합니다. (로깅, 알림) 성능 - 배치 어플리케이션은 지정한 시간 안에 처리를 완료하거나 동시에 실행되는 다른 어플리케이션을 방해하지 않도록 수행되어야합니다.

배치와 스케쥴러의 차이

💡
스프링 배치 vs Quartz (스케쥴러) 스케쥴링이란? 매시간 지정한 시간에 지정한 동작을 수행하는 것!! - 배치 애플리케이션의 절대적인 목적은 대용량 데이터 처리이다. - 배치 프레임워크에서 스케쥴링 기능을 제공하지 않는다. - 스케쥴링 프레임워크는 배치를 도와주는 보완제 역할이다.

배치의 도메인 용어

💡
배치의 일을 잡이라고 하고 잡을 수행하기 위한 JobLauncher가 있고, Job 자체에는 여러개의 Step으로 구성되어 있고, Step은 ItemReader, ItemProcessor, ItemWriter로 구성된다!!! 또한 이를 수행하게 하기 위한 Repository가 있다!

💡
Job - Job 이름을 정의 - Step을 정의하고 순서를 정의함 - Job의 재사용 가능성을 정의 JobInstance - 논리적으로 Job을 실행 - JobParameters를 허용하여 구분함. - JobInstance = Job = identifying JobParameters JobExecution - Job을 실행하는 단일 시도 - 실패했던 JobInstance에 대해 새로운 실행을 하면 새로운 JobExecution이 생성됨

JobExecution Properties

  • BatchStatus : 실행상태를 나타낸다. 실행중이면 Started, 실패하면, failed, 성공하면 completed
  • ExiStatus : 실행 결과를 나타낸다. ExitCode를 포함하고 있다.

Job Hieracchy with Steps

Step

  • 배치 작업의 독립적이고 순차적인 단계를 캡슐화하는 도메인 객체
  • 모든 Job은 하나 또는 그 이상의 Step으로 구성된다.
  • Step의 내용은 개발자의 재량이므로 복잡하거나 단순하게 구현 가능하다.

StepExecution

  • Status : 실행 상태를 나타낸다.
  • ExitStatus : 실행의 결과를 나타낸다.
  • ReadCount, WriteCount, CommitCount, RollbackCount, FilterCount 등 실행에 대한 다양한 정보를 담고 있다. (어떤 데이터를 어떻게 처리했나에 대한 정보)

JobRepository

: Job, Step 구현을 위한 CRUD 작업을 제공한다.

JobLauncher

: Job을 시작하기 위한 간단한 인터페이스. 구현시 JobRepository에서 유효한 JobExecution을 획득하고 Job을 실행한다.

→ Spring Batch 사용시 제공받는다. ( 특히 메타데이터 또한 스프링 부트에서 전반적으로 제공해주기 때문에, 보다 본질에 집중할 수 있도록 도움을 준다!)

Item

  • Item : 작업에 사용하는 데이터
  • ItemReader : Step에서 한 항목씩 검색한다. 모든 항목이 소진된 경우 null을 반환한다.
  • ItemWriter : 여러 출력 항목을 나타낸다.
  • ItemProcessor : 비즈니스 처리를 담당한다. 항목이 유효하지 안핟고 판단되는 경우 null을 반환한다.

스프링 배치 활용하기

💡
프레임워크를 활용하다 보니까 Joblancher나 JobRepository는 굳이 신경 쓸 필요가 없게 된다.! Job 내부에 Step은 익명 Tasklet과 함꼐 Chunk Oriented Tasklet으로 구성된다. 이는 다시 read, proces, write로 구성되고,

💡
chunk : 각 커밋 사이에 처리될 row(item)의 수 성공 시 chunk만큼 커밋. 실패 시 chunk만큼 롤백을 거치게 된다. 최종적으로 write단에서 chunk를 한번에 write 하게 된다.!

List items = new Arraylist(); for(int i =0; i<commitInterval; i++){ //commitInterval : chunksize Object item = itemReader.read(); Object processedItem = itemProcessor.process(item); items.add(processedItem); } itemWriter.write(items);

ItemReader

  • Cursor와 Paging 기능을 제공한다.

💡
메모리에 page 사이즈만큼 데이터를 가져온다.) (chunk size == page size) (chunk size가 크게 되면 : 하나의 트랜잭션 처리를 위해 여러번의 조회를 해야 한다.) chunk를 하나의 트랜잭션에서 처리 - > JPA를 영속성 컨텍스트 사용 가능!
💡
ItemProcessor(Optional) - Chunk - Oriented - Tasklet을 구성할 때 선택 요소이다. - 데이터를 가공/필터링 하는 역할을 한다. → writer에서도 구현 가능한 역할 → 비즈니스 코드가 섞이는 것을 방지한다. - step에 여러 로직이 필요할 때 도입을 고려해 유지보수성을 증가시키다. - 데이터 처리를 실패했을 떄 null을 반환해 writer에 전달되지 않는다.
@Bean //Sequential flow public Job job() { return this.jobBuilderFactory.get("job") .start(stepA()) .next(stepB()) .next(stepC()) .build(); }

@Bean //Java configuration -> Conditional flow public Job job() { return this.jobBuilderFactory.get("job") .start(stepA()) .on("*").to(stepB()) .from(stepA()).on("FAILED").to(stepC()) .end() .build(); //ExitStatus로 판단하는 것을 알 수가 있다.!  }

배치 어플리케이션 운영하기

💡
배치 애플리케이션 운영하기 테스트 코드를 반드시 작성한다. - QA를 하기 어렵기 때문에 테스트 코드가 필요하다 - 복잡한 쿼리를 실행한 결과를 처리하고 다시 데이터 베이스에 저장하는 작업이기 때문에 통합 테스트를 실행한다. - 보통 단위 테스트를 이용해서 내부 작업을 검사하고 전체 테스트 코드를 반드시 작성한다.

//when JobExecution jobExecution = myTestJobExecution.launchJob(); List<StepExecution> stepExecution = new ArrayList<>(jobExecution.getStepExecution()); StepExecution stepExecution = stepExecution.get(0); //then assertThat(jobExecution.getExitStatus()).getExitCode().isEqualTo("FAILED"); assertThat(stepExecution.getWriteCount()).isEqualTo(2); assertThat(stepExecution.getRollbackCount()).isEqualTo(1);

관리 도구

  • Cron : 리눅스 작업 스케쥴러
  • Spring MVC + API Call : 권장하지 않는 방법
  • Spring Batch Admin : Deprecated
  • Quartz + Admin : 스케쥴러 프레임워크 + 관리자 페이지 구현
  • CI Tool(Jenkins) → 적극 권장함!!

Jenkins의 장점

  • Integration(Slack, Email 등)
  • 실행 이력 / 로그 관리
  • 다양한 실행 방법(REST API / 스케쥴링/ 수동 실행)
  • 파이프라인

Jenkins의 장점 - 공통 설정 관리 → Global Properties를 통해서 공통 설정 주입 가능!!

java -jar\ -XX:+UseG1GC\ //공통 설정을 관리할 수 있다. -DSpring.profiles.active= dev \ Application.jar \ --job.name= job이름 \ jobParameter1 = jobParameterValue1 \ jobParameter2 = jobParameterValue2 \ 

Jenkins의 장점 - 파이프라인

→ Job 내무에 Step을 여러개 설계하는 것보단 권장된다!

→ Job을 단독으로 실행할 수 있도록 설계한느 것이 유지보수에 더 좋다

Chunk 최적화

  • 구체적인 가이드가 존재하지 않는다.
  • 설계한 비즈니스 로직에 대해서 가장 효율적인 단위를 설정해야 한다.
  • 여러개의 배치 작업을 구성하는 것은 다른 배치 작업에 영향을 주면 안된다.

→ 스프링 배치에서는 chunk 사이즈 만큼 메모리에 데이터를 적재해야 하기 때문에 다른 배치에서 사용할 수 있는 메모리가 줄어들 수 있다.

💡
요약 - 배치 애플리케이션의 절대적인 목적은 대용량 데이터 처리이다. - 배치와 스케쥴링의 차이를 이해한다. → 스케쥴링은 배치의 보완제 역할 - 배치 애플리케이션의 기본 구성은 JobLauncher, Job, Step으로 구성된다. → 스프링 배치와 같은 프레임워크를 이용해서 비즈니스 로직에 집중할 수 있다. - 다양한 방법으로 배치 애플리케이션을 운영할 수 있고, 설계한 비즈니스 로직에 맞춰서 선택한다!

💡
프로젝트 시사점 : 결국에 대용량 데이터 처리위한 기능 구현을 할 것인가 말 것인가에 대한 고민을 하게 될거 같은데, 순위 집계(조회수, 좋아요수) 등의 경우 배치를 시도해보는 것도 상당히 좋을 거 같다는 생각은 든다. 조졸두 님의 경우에도 포인트 집계나 리뷰 집계와 같은 경우 쓰인다고 하셨는데, 실제 프로젝트에서는 우선 기술 문서를 바탕으로 적용은 해봐야겠지만, 정말 상당한 로드가 걸리고 시간도 꽤 오래걸릴 거 같기는 하다.

출처

Configuring and Running a Job
@Configuration @EnableBatchProcessing @Import(DataSourceConfiguration.class) public class AppConfig { @Autowired private JobBuilderFactory jobs; @Autowired private StepBuilderFactory steps; @Bean public Job job(@Qualifier("step1") Step step1, @Qualifier("step2") Step step2) { return jobs.get("myJob").start(step1).next(step2).build(); } @Bean protected Step step1(ItemReader reader, ItemProcessor processor, ItemWriter writer) { return steps.get("step1") .
https://docs.spring.io/spring-batch/docs/current/reference/html/job.html
[10분 테코톡] 🍦라빈의 Spring Batch
🙋‍♀️ 우아한테크코스의 크루들이 진행하는 10분 테크토크입니다. 🙋‍♂️'10분 테코톡'이란 우아한테크코스 과정을 진행하며 크루(수강생)들이 동료들과 학습한 내용을 공유하고 이야기하는 시간입니다. 서로가 성장하기 위해 지식을 나누고 대화하며 생각해보는 시간으로 자기 주도적인...
https://www.youtube.com/watch?v=1xJU8HfBREY&list=PLgXGHBqgT2TvpJ_p9L_yZKPifgdBOzdVH

1. Spring Batch 가이드 - 배치 어플리케이션이란?
Spring Batch In Action이 2011년 이후 개정판이 나오지도 않고 (2019.03 기준), 한글 번역판도 없고, 국내 Spring Batch 글 대부분이 튜토리얼이거나 공식 문서 중 일부분을 짧게 번역한 내용들이라 대용량 시스템에서 사용할때 정말 많은 삽질을 했습니다. Spring Boot가 활성화되면서 Spring Batch도 이전에 비해 훨씬 사용하기 편해졌지만 제대로 정리된 곳 찾기가 쉽지 않았습니다.
https://jojoldu.tistory.com/324

[Spring Batch] 배치의 도메인 언어
그러나 Spring patterns, operations, templates, callbacks 및 idioms 때문에 다음과 같은 기회가 있습니다. 아래 다이어그램은 수십년 동안 사용된 배치 참조 아키텍처의 단순화된 버전입니다. 이는 배치 프로세싱의 도메인 언어를 구성하는 구성요소에 대한 개요를 제공합니다. Batch Stereotypes 위의 다이어그램은 배치의 도메인 언어를 구성하는 핵심 개념을 강조합니다.
https://eagle-dev.tistory.com/7
https://terrykerrigan.medium.com/2-spring-batch-%EA%B8%B0%EB%B3%B8-%EA%B0%9C%EB%85%90-%EC%B6%94%EA%B0%80-908e848a6ebb
Spring Book - Chapter 21 - Spring Batch - Java Codebook
Chapter 21, "Spring Batch", similar to other chapters will introduce you to Spring Batch in a comprehensive manner. Batch operation is one among the integral parts of modern day application and Spring's support comes in the form of Spring Batch and we will deep dive into this in all aspects possible.
https://www.javacodebook.com/2013/09/17/spring-book-chapter-21-spring-batch/8/
반응형

'Project > Tech_review' 카테고리의 다른 글

캐시 그리고 세션  (0) 2021.02.26
빌드와 배포  (0) 2021.02.26