프로젝트 구조 변경
위 구조가 원래 사용하고 있었던 배치 구조이다.(이름도 잘못 지어서 setp인데 job으로 되어있는것도 있다.)
한 패키지에 step이랑 job이 합쳐져있고 dto 또한 하나의 패키지에서 관리되고 있어서 수정사항이 생겼을 때 한참을 찾아 헤매야 한다.
step에는 모든 로직이 전부 들어있는데 repository, sevice, controller가 하나의 클래스안에 모두 들어있는 느낌을 주었고
이 또한 수정 할때 헤매는 이유중 하나였다.
위와 같은 방식으로 domain 별로 배치 flow 작업을 나눴고
@Configuration
public class ElectricityStep {
private final BatchConfig batchConfig;
private final ItemReader<ControlValueData> itemReader;
private final ItemWriter<ControlValueData> itemWriter;
public ElectricityStep(BatchConfig batchConfig, @ElectricityReaderAno ItemReader<ControlValueData> itemReader,
@ElectricityWriterAno ItemWriter<ControlValueData> itemWriter) {
this.batchConfig = batchConfig;
this.itemReader = itemReader;
this.itemWriter = itemWriter;
}
@Bean
@JobScope
@ElectricityStepAno
public Step getElectricityStep() {
return batchConfig.stepBuilderFactory.get(ELECTRICITY_STEP)
.<ControlValueData, ControlValueData>chunk(100)
.reader(itemReader)
.writer(itemWriter)
.build();
}
}
reader와 wrtier를 만들어서 step에 모두 들어가있는 코드를 분할해서 관리할 수 있게 만들었다.
결과적으로 클래스 별로 코드가 나뉘어서 하나의 클래스에서 담당하고 있는 일이 적어져 코드양도 줄고 유지보수하기 쉽게 되었다
bulk insert
insert 쿼리를 단건씩 저장하게 되면 저장할 데이터의 양이 많아질수록 성능에 부하가 생긴다.
이러한 성능 문제를 해결하기 위해 저장할 데이터를 묶어서 대량의 데이터를 한번에 처리하는 방식
적용 방법
rewriteBatchedStatements=true 옵션 추가
- batch 형태의 SQL로 재작성 해주는 옵션
jdbc:mysql:://DB주소:포트/스키마?rewriteBatchedStatements=true
저장 속도 비교
기간 : 2월21일 ~ 2월 28일
chunk size : 10000
데이터 건수: 약 55만건
시작 시간 종료 시간 소요 시간
기존 | 2024-02-28 13:54:11 | 2024-02-28 14:08:08 | 13분 56초 |
변경 후 | 2024-02-28 14:12:52 | 2024-02-28 14:13:56 | 1분 4초 |
Jpa(Hibernate)를 사용하고 ID 생성을 Auto Increment로 되어있을 경우엔 JdbcBatchItemWriter를 사용해야 Bulk Insert로 처리된다.
일반적으로 100만건 이상의 데이터를 단일테이블에 일괄 저장할 경우 Bulk Insert로 처리하면 좋다.
참고
'트러블슈팅' 카테고리의 다른 글
관제값 조회 디자인 패턴 적용 (1) | 2024.10.13 |
---|---|
그래프 조회 속도 개선 (1) | 2024.10.13 |
요금 계산 리팩터링 (0) | 2024.10.10 |
비동기 테스트 처리 (3) | 2024.10.07 |
대용량 데이터 다운로드 (2) | 2024.10.06 |