[batch][nestJS] DB 데이터를 옮기게 하고 특정 시간에 옮기게 하려면..?! 배치를 쓴다(feat.구조분해 할당)

여리·2023년 9월 19일
0

이번 사이드프젝트를 경험하면서 배워야할 것들도 많고 힘들기도(자괴감)하고 어려웠지만 새로운 경험들도 할 수 있는게 너무 좋았다.

내용의 순서는 이렇다

  1. DB 데이터를 옮긴다.
  2. nestJS의 라이브러리를 사용해서 batch 작업을 수행한다.

그럼 시작해보자

1. DB데이터 옮기기

상황

  1. table1, table2가 있다.
  2. table 1의 2개의 column을 table 2에 옮긴다.(옮길때 table2를 일부가공하는 과정도 있었다.)
  3. 사전에 table1에서 2로 옮긴 데이터는 변경사항이 있을 수도 있으니 update쿼리를 수행하게 하고 새로운 데이터가 생기는 경우에는 insert 쿼리를 수행할 수 있도록 하게 한다.
//table1에서 table2로 옮기기

async generateFuction(){

//1. 데이터 추출(예시코드이기 때문에 실제로 사용하고자하는 코드에서는 다듬기가 필요하다.)
const table1Datas= query(`select distinct column1, column2 from table1 `)

const table2Datas= query(`select distinct column1, column2 from table2`)

//아래 절차를 수행하기 위해 table2의 가공이 필요(데이터의 요소 추출)
const table2List=table2Datas.map(el=>el.column1)

//2. table1과 2가 서로 매칭되는지 확인
//table1Datas에서 추출한 데이터를 반복문 배열로 추출
for(const[table1Emelents] of table1Datas){
  //taeble1에서 추출한 요소들이 table2Datas에 들어있는지 확인하고 true이면 update쿼리 실행
  if(table2List.includes(table1Elements['table1EmelentColumn1']){
   
     const returnItem={...table1Elements}
  	//returnItem의 가공 시작
 	returnItem['~~~']=returnItem['table1ElementColumn1'].sort().reverse()...
    //계속 가공
    .
    .
    .
    
     }
	// 가공이 끝난 값을 update 쿼리로 DB에 반영시키기
	await this.yourRepository.query(
      `
		UPDATE table2 SET column1, column2 WHERE column3=?
      `
    ),[parameter1, parameter2, parameter3]
 }else{
  // table1에서 추출한 요소들이 table2에 없으면 없는 경우에는 insert 쿼리 실행
   
   returnItem={...table2Elements}
   
   returnItem['~~~~~']=returnItem['table1ElementColumn1'].sort().reverse()
   //계속 가공
   .
   .
   .
   await this.yourRepository.query(
     `
	  INSERT INTO table2(column1, column2, column3, column4)
		VALUES(?,?,?,?)
     `,[parameter1, parameter2, parameter3, parameter4]
   )
 }
}

위의 방식에서는 한가지 변수에 여러 데이터를 포함할 수 있기 때문에 구조분해할당도 사용하게 되었다. 구조분해할당을 잘 사용할 수 있는 아주 좋은 예시였다고 생각한다.
구조분해 할당에 대해서는 따로 작성한 구조분해할당블로그 기초내용을 참고하면 좋을 것 같다.

이런방식의 코드를 예시로하면 table1, table2에 대한 DB를 이동할 수 있는 기반을 마련할 수 있다. 이렇게 작업하는 기능에 대해서는 완성했다고하면
그다음 작업은 이 기능을 스케줄링을 통해서 정기적으로 기능을 수행할 수 있게 하는 기능이 필요했다. 그래서 나온것이 batch!

2. batch

일단 batch에 대한 간단한 설명을 하자면 '데이터를 실시간으로 처리하는것이 아닌 원하는 시점에 한번에 (대량의)데이터를 처리할 수 있도록 하는 있는 기능(시스템)' 이다.

이런 시스템을 사용하는 경우의 예시를 들자면

1. 금융 시스템(ex.은행)의 정산
2. 커머스 프로그램의 대규모 변경사항의 일괄 진행
등
등
등..

을 예로 들 수 있다.

나는 이 배치를 왜 활용하게 됐냐면 위 1번 DB 옮기는 작업이 수시로 업데이트 될 수 있기 때문에 특정 시간대에 업데이트가 될 수 있는 기능이 필요하다고 생각했다.

그리고 나는 nestJS로 프로젝트를 진행하고 있었기 때문에 batch를 보다 편하게 할 수 있는 방법이 있었다.
공식문서에서도 이에 대한 방법이 있다.공식문서 링크

이런 기능들에 대해서는 scheduling 이라고 표현하는 것 같다.
nestJS에서는 @nestjs/schedule이라는 라이브러리를 활용하고, Cron이라는 데코레이터를 활용한다.

$ npm install --save @nestjs/schedule

해당 라이브러리를 설치하고 활용하면 된다.

import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';

@Module({
  imports: [
    ScheduleModule.forRoot()
  ],
})
export class AppModule {}

module 데코레이터를 활용해서 schedule 모듈을 import를 해서 사용할 수 있도록 한다.

그리고 모듈을 불러와서 기능을 활용하도록 코딩하자면 방법에 따라 작성해볼 수 있다.

//file.scheduler.ts

//type 1
import { Injectable, Logger } from '@nestjs/common';
import { Cron } from '@nestjs/schedule';
import {YourService} from './yourService.ts'

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name)
  constructor(private yourService:YourService){}
 

  @Cron('45 * * * * *')
async handleCron() {
    this.logger.debug('Called when the current second is 45');
    await yourService.function();
  }
}


//type2
import { Injectable, Logger } from '@nestjs/common';
import { Cron, CronExpression } from '@nestjs/schedule';
import {YourService} from './yourService.ts'

@Injectable()
export class TasksService {
  private readonly logger = new Logger(TasksService.name);
  constructor(private yourService:YourService){}

  @Cron(CronExpression.EVERY_30_SECONDS)
  handleCron() {
    this.logger.debug('Called every 30 seconds');
    await yourService.function();
  }
}

이렇게 준비하고 서버를 작동시키면 스케줄러에 따라서 설정한 시점에 사용하고자 하는 기능을 포함시키면 batch를 사용할 수 있게 된다.

작성하는 방법은 여러방법이 있으니 공식문서를 참고하고 다른 블로그들을 참고해서 본인만의 방식으로 batch를 만드는 게 좋을 것 같다!

추가참고 블로그 링크
1. https://velog.io/@jojoo/NestJS-Batch-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0-with-cron

끝 !

profile
beckend developer

0개의 댓글