본문 바로가기

카테고리 없음

Spring Batch 테크 세미나 준비

 

 

설계자 팀원의 내용 추가 필요.

 

팀 전체 성과를 발표한다면 어떤 시나리오가 좋을까?

1. 기술 별로 발표

배치 -> api, ext-api (웹개발팀 파트일지도) -> 인프라 구성 -> pi-core기능 -> 테스트 코드

2. 시간 순 발표 (간트차트+ 스프린트 회의록 참조)

문화상품권 개발 후 운영 + 인수인계 자료 만들기 -> 이행배치 API화 -> pi-core 분리 -> 테스트 코드 


발표 아웃라인

1. 프로젝트 배경 및 목표 (5분)

  • 기존 시스템의 문제점 (오래된 프로시저의 한계점)
    • 형상관리 안됨 (2002 월드컵 할인이벤트)
    • 단위 테스트 불가능
    • 수많은 수기작업 (이메일 요청 > 담당자 확인 / 데이터 추출 등)
    • 자바 대비 개발자 수급 어려움
  • 새로운 시스템으로 전환하게 된 비즈니스적/기술적 이유
    • 체계적인 관리
    • 단위 테스트 가능
    • 영업 담당자를 포함한 많은 부서에 뿌려져있던 수기작업들 최소화
    • 새로운 기술 표준으로 새로운 시스템 구축

2. 아키텍처 및 기술 스택 (20분)

  • 전체 시스템 아키텍처 다이어그램
    • 내재화 운영계 정산 시스템 (배치, DB, CORBAT DB, 젠킨스, 다보아 FE, BE, EXT-API, 알람, 타이탄)
    • 배치 중 API 형태 실행과 일반배치 실행, 스케줄링 테이블
  • 데이터 아키텍처 전환
    • AS-IS: MySQL, MSSQL 개별 서비스별 구조
      • 기존 DB 구조의 문제점 (데이터 정합성, 의미없는 seq 칼럼, bizCode 등 통일성 없는 용어 등)
      • 서비스별 분리로 인한 운영상 관리 포인트 증가
    • TO-BE: EPAS 통합 DB 구조
      • 새로운 DB 설계의 핵심 원칙
      • 통합으로 인한 이점 (데이터 일관성, 관리 효율성)
      • 향후 확장 가능성
        • 새로운 정산 서비스 추가 용이성
        • 데이터 분석/리포팅 확장성
  • Spring Batch, Spring Boot, Jenkins 등 주요 기술 스택 선정 이유
    • 모든 개발자에게 매력적이고 일반적인 기술 스텍
    • 인력 구하기에 용이
    • 승인측 기술표준인 스프링 부트와 스프링 배치의 호환성
    • 직관적인 웹인터페이스(젠킨스)
  • 공통 모듈의 역할과 재사용성
    • 서비스코드로 구분해서 비즈니스 로직을 공유하고, 1가지 JOB으로 통합
      • 기존에는 각 통신사별로 다른 sql 프로시저 실행했었음
    • 그 외 유사한 로직을 가진 배치끼리 코드 재사용 가능
    • COROWN 속 Entity 를 모든 프로젝트에서 공유함
    • 정산 배치에 항상 필요한 날짜 처리 관련 로직 다날에 맞게 개발 및 공통 모듈화

3. 핵심 기능 구현 사례 (15분)

  • 정산 프로세스의 주요 개선 사례 2-3가지 선정
    • ex) 자동취소 로직 프로시저 vs 스프링 배치
    • 추가 선정 필요
  • 실제 코드와 함께 설명 (복잡한 로직을 어떻게 개선했는지) 
    • 젠킨스 웹 UI 로 실행하는 모습
    • Reader, Processor, Writer (+UpdateWriter)
    • 로깅을 통한 명확한 처리 과정 확인 (프로시저는 안됨)
    • 테스트 코드를 통한 단위테스트 모습
    • 추후 승인도 내재화 됐을 때 더 최적화된 모습 예상
  • 성능 개선 수치 등 정량적인 지표 제시
    • 자동취소엔 내세울만한 지표는 없는 듯. 
    • 실행계획 확인 및 리더 / 리팩터링을 통한 성능 개선 사례 필요

4. 프로젝트 성과 및 교훈 (10분)

  • 시스템 안정성/성능 개선 수치
    • 복제 확장 용이한 스프링 배치 정산 시스템
    • 몇개월간 문화상품권 운영을 통해 도출한 수치?
  • 운영/유지보수 편의성 향상
    • 비개발자 / sql 을 모르는 사람도 이해 & 사용가능한 웹 인터페이스
    • 명확한 형상관리
    • 정산 시스템의 개발 / 체크 / 운영 분리
  • 프로젝트를 통해 얻은 기술적/협업적 인사이트
    • 모든 개발자의 기술적 성장? 을 보여줄 수 있는 시각적 자료가 있을까?

5. Q&A (10분)


발표 스크립트 초안

(발표 자료는 따로 PPT 형태로 만들 예정)

챕터1. 프로시저와 스프링 배치, 누가 더 알찬 밥상을 차릴까?

여러분, 우리가 데이터 작업을 할 때 프로시저와 스프링 배치라는 두 도구를 만납니다. 이 둘은 마치 할머니의 손맛과 백종원 레시피 같은 관계예요. 할머니의 손맛, 즉 프로시저는 빠르고 익숙한 요리를 만들어주지만, 인수인계가 어렵고 가맹점 확장이 어렵습니다. 반면 백종원 레시피, 즉 스프링 배치는 체계적이고 반복 가능하며 확장이 쉬운 요리를 만듭니다.

이제 자세한 사례를 들어 두가지를 비교해봅시다.

프로시저 방식의 데이터 처리

먼저, 프로시저로 데이터를 처리한다고 상상해봅시다. 예를 들어, 우리는 월말에 모든 고객의 포인트를 업데이트해야 해요.

프로시저 예시 코드:

CREATE PROCEDURE update_customer_points()
BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE customer_id INT;
    DECLARE points INT;
    DECLARE cur CURSOR FOR SELECT id, current_points FROM customers;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

    OPEN cur;
    read_loop: LOOP
        FETCH cur INTO customer_id, points;
        IF done THEN
            LEAVE read_loop;
        END IF;

        UPDATE customers
        SET current_points = points + 10
        WHERE id = customer_id;
    END LOOP;

    CLOSE cur;
END;



어때요? 언뜻 보면 간단해 보이지만, 생각보다 문제가 많습니다.

  • 에러 처리가 어렵다. 예를 들어, 중간에 실패하면 어떻게 복구할까요? Transaction 의 통째 롤백 말고는 방법이 없습니다.
  • 성능 조율이 복잡하다. 데이터가 많고 로직이 복잡해질 수록 프로시저가 느려지고 데이터베이스에 부하를 줍니다.
  • 확장성 부족: 새로운 요구사항이 들어오면 코드가 산으로 갑니다. 버전관리도 힘들죠.

 

스프링 배치 방식의 데이터 처리

이제 같은 작업을 스프링 배치로 처리해볼까요? 여기선 코드를 나눠 깔끔하게 관리하고, 실패해도 다시 시도할 수 있으며, 데이터 규모에 따라 성능을 조율할 수 있어요.

스프링 배치 예시 코드:

@Configuration
public class CustomerPointsBatchConfig {

    @Bean
    public Job updateCustomerPointsJob(JobBuilderFactory jobBuilderFactory,
                                       Step updatePointsStep) {
        return jobBuilderFactory.get("updateCustomerPointsJob")
                .start(updatePointsStep)
                .build();
    }

    @Bean
    public Step updatePointsStep(StepBuilderFactory stepBuilderFactory,
                                 JdbcCursorItemReader<Customer> reader,
                                 JdbcBatchItemWriter<Customer> writer) {
        return stepBuilderFactory.get("updatePointsStep")
                .<Customer, Customer>chunk(100) // 한 번에 100개의 데이터를 처리
                .reader(reader)
                .processor(customer -> {
                    customer.setCurrentPoints(customer.getCurrentPoints() + 10);
                    return customer;
                })
                .writer(writer)
                .build();
    }

    @Bean
    public JdbcCursorItemReader<Customer> reader(DataSource dataSource) {
        return new JdbcCursorItemReaderBuilder<Customer>()
                .dataSource(dataSource)
                .sql("SELECT id, current_points FROM customers")
                .rowMapper((rs, rowNum) -> new Customer(
                        rs.getInt("id"),
                        rs.getInt("current_points")))
                .build();
    }

    @Bean
    public JdbcBatchItemWriter<Customer> writer(DataSource dataSource) {
        return new JdbcBatchItemWriterBuilder<Customer>()
                .dataSource(dataSource)
                .sql("UPDATE customers SET current_points = :currentPoints WHERE id = :id")
                .beanMapped()
                .build();
    }
}


스프링 배치의 장점은?

  • 관리와 확장성: Step, Job, Reader, Writer를 분리해서 관리합니다. 새로운 요구사항이 들어와도 특정 부분만 수정하면 돼요. 성능 향상을 위한 Scale Out도 가능합니다. 이는 프로시저는 구현불가능한 선택지입니다.
  • 재시도와 장애 복구: 실패하면 바로 다시 시도하거나 실패 지점을 기록해 복구가 가능합니다.
  • 대용량 처리: Chunk 기반으로 데이터를 나누어 읽고, 처리하고, 저장합니다. 데이터베이스 부하를 줄이고 처리 속도를 높이죠.

스프링 배치는 데이터를 처리하고 저장하는 강력한 프레임워크로, 대규모 데이터 처리 파이프라인의 표준적인 구조를 제공합니다. 이를 이해하기 위해 스프링 배치의 주요 구성 요소, 데이터 처리 방식, 그리고 작업 관리 방식을 기술적으로 살펴보겠습니다.

 

챕터2. 스프링 배치의 기본, 정교한 공장 시스템

여러분, 스프링 배치는 데이터를 가공하는 공장이라고 생각하면 됩니다. 공장에선 원자재(데이터)를 받고, 이를 가공해서 새로운 제품(결과물)으로 내보내죠. 자, 이 공장 시스템이 어떻게 돌아가는지 알아봅시다!

1. 스프링 배치의 주요 구성 요소

Job
Job은 배치 프로세스의 최상위 구성 요소로, 전체 작업의 정의를 담고 있습니다. 예를 들어 "데이터 로드, 정리, 결과 저장"이라는 큰 작업 단위를 정의하는 역할을 합니다. 

Step
Step은 Job의 세부 단계로, 데이터의 입력, 처리, 출력 단계를 정의합니다. 각각의 Step은 독립적으로 실행될 수 있으며, 다양한 Step을 조합하여 복잡한 Job을 구성할 수 있습니다.

ExecutionContext
ExecutionContext는 작업의 상태를 저장하는 컨텍스트입니다. 예를 들어, 대량의 데이터를 처리하는 중간에 실패했을 경우, 이 컨텍스트를 통해 어디까지 진행되었는지 기록하고 재시작할 수 있습니다.

2. 데이터 처리 흐름 in step

Reader
Reader는 데이터 소스에서 데이터를 가져오는 구성 요소입니다. 데이터베이스, 파일, 큐 등 다양한 소스를 지원하며, 데이터를 한 번에 한 항목씩 가져옵니다.

Processor
Processor는 가져온 데이터를 원하는 형태로 변환하거나, 필터링하는 역할을 합니다. 예를 들어, 데이터의 특정 필드를 암호화하거나, 특정 조건에 맞는 데이터만 선택할 수 있습니다.

Writer
Writer는 처리된 데이터를 저장합니다. 데이터베이스, 파일, 혹은 외부 API로 전송할 수 있으며, 최종 결과를 지속 가능한 저장소에 남깁니다.

3. 배치의 스타일, Chunk와 Tasklet 비교

Chunk: 데이터를 일정 크기(Chunk) 단위로 처리합니다. 예를 들어, 한 번에 100개의 레코드를 읽고, 처리 후 저장합니다. 이는 대규모 데이터 처리에 적합하며, 성능 최적화를 위해 트랜잭션 단위로 작동합니다.

Tasklet: 단일 작업 단위를 정의하며, 초기화 작업이나 단순 반복 작업에 적합합니다. 예를 들어, "특정 파일 삭제", "특정 데이터 update" 같은 작업을 수행할 수 있습니다.

4. Meta Database

Meta Database는 작업 실행 정보를 저장하는 "작업 메모장"입니다. 스프링 배치의 핵심 관리 도구로, 작업 이력을 기록합니다. 작업의 성공 및 실패 여부, 시작/종료 시간, 입력/출력 데이터 크기 등이 저장됩니다. 이러한 정보는 재처리 및 디버깅에 유용하며, 작업의 안정성과 추적 가능성을 보장합니다.

5. 작동 흐름

  1. Job 시작: 배치 애플리케이션은 Job을 실행하여 작업의 전체 플로우를 시작합니다.
  2. Step 처리: Job은 여러 Step으로 구성되며, 각 Step은 Reader, Processor, Writer를 통해 데이터를 처리합니다.
  3. 작업 완료: Job이 완료되면 Meta Database에 작업 결과가 기록됩니다.

스프링 배치는 데이터 파이프라인을 체계적으로 설계하고 실행할 수 있는 도구를 제공합니다. 대량의 데이터를 효율적으로 처리하기 위한 강력한 구조와 다양한 유연성을 제공하므로, 실무에서 매우 유용하게 활용됩니다. 다음 강의에서는 이러한 구조를 기반으로 한 고급 설정과 실무 팁을 다룰 예정입니다.

... 추가 작성 필요


프로시저 vs 배치 설명 자료

  • 당연히 Java로 만든 배치가 DB프로시져의 성능을 뛰어넘기는 힘듭니다.
    Java로 만든 배치는 DB 서버 밖에서 호출되니 네트워크 호출비용도 있고, 같은 서버에서 돌리더라도 JDBC 드라이버의 콜스택을 거쳐야하므로  성능에 불리합니다.
    그러나 Java배치나 스프링배치가 가지는 장점도 많은데
    1. 버전관리, 배포를 웹어플리케이션과 같은 방식으로 할 수 있습니다.
    2. 부분적으로 테스트하기에 편합니다. 스프링배치처럼 구조가 나누어져 있지 않다면 읽는 부분만 따로 테스트, 쓰는 부분만 따로 테스트하기가 정말 힘듭니다. batch에서의 testablility는 생산성과 직결되는 문제인 거 같다라구요.
    3. 꼭 DB서버가 하지 않아도 되는 작업은 다른 서버로 분리해서 DB서버의 자원을 조금이나마 절약하는 의미도 있습니다.  DB서버는 분할해서 구성하는 비용이 크므로 대용량시대에는 가장 아껴야할 자원인데, 어플리케이션서버는 상대적으로 여러대로 늘이는 구성이 어렵지 않습니다. 스프링배치에서도 여러서버를 써서 분산처리하는 구성도 가능합니다.
    4. 스프링배치를 쓴다면 배치 모듈을 세분화해서 추후에 기능을 추가하거나 에러를 재현하기 쉬운 구조로 유도합니다.

 

  • DB프로시져로도 잘 짠다면 유지보수성에 문제가 없을수도 있지만, 레거시 중에 몇천라인이 넘어가서 담당자외에는 손댈수가 없는 DB프로시져가 많습니다.

    그리고 스프링배치은 생산성은 유사한 job을 모아서 factoryBean을 만들 때부터 나옵니다. FactoryBean을 잘 만들면 같은 유형의 Job이면 설정 1~2개만 바꿔서 새로운 job을 만들수가 있죠. 일종의 추상화의 틀로서 SpringBatch+나름대로의 FactoryBean이면 맨땅에서 만드는 것보다 훨씬 편합니다. 실제로 자사 배치는 서비스 코드만 바꿔치기하면 같은 배치 프로그램으로 다른 원천사의 배치가 처리됩니다.

 

반응형