인프런 커뮤니티 질문&답변

김기훈님의 프로필 이미지
김기훈

작성한 질문수

스프링 배치

ClassifierCompositeItemProcessor

분류가 필요한 상황이 있는데 방향에 대해 질문드립니다.

해결된 질문

작성

·

235

·

수정됨

0

안녕하세요.

구현하고자 하는 배치를 해보면서 강의를 부분부분 병행하며 듣고 있는데, 제가 원하는 배치는 어떻게 설계 해야 하는지 고민이 되어 조언을 얻고 싶어 질문드립니다.

구현하려는 상황은 다음과 같습니다.

 

  1. db 컬럼 중 플래그 값이 있고 그걸로 reader 에서 read

  2. read 한 데이터들로 processor 에서 로직 진행 (

    로직 중간중간 db 조회나 업데이트하는 상황도 생김)

     

  3. writer 에서 write 해야 하는 테이블이 4개 인데 processor 로직 조건에 따라 어떤 경우는 2개, 어떤 경우는 4개 등 write 되는 테이블 개수가 달라짐

  4. 마지막에 최종적으로 read 한 모든 데이터의 플래그 값을 업데이트 쳐서 다음 read 에서 조회되지 않게 함

 

처음 생각은 reader 와 processor 를 하나씩 만들고 writer 를 여러개 만드려고 했습니다.

processor 에서 리턴되는 객체 하나로 여러 테이블에 write 해도 될만큼 필드가 겹치는게 많아서 이렇게 생각했습니다.

그래서 찾아보니 writer 에도 composite 과 classifierComposite 구현체가 있더라구요.

그런데 둘 다 사용해봤는데 제가 원하는 바를 실현시키지 못했습니다. 분류 후 여러개를 writer 해야 하는데 composite 는 분류가 안되고 classifierComposite 은 하나만 writer 되더라구요.

그래서 writer 여러개로 설계하는게 안맞는 방법인가 싶어서요.

같은 맥락으로 processor 여러개로 하는 방법도 뭔가 그림이 잘 안그려지고..

결국 step 을 여러개 하는 방향을 생각 중인데 이때도 고민거리가 생깁니다.

step 으로 했을 때는 같은 조건으로 테이블 개수만큼 read 를 여러번 하게 된다는 단점이 있는 것 같아서요.

그리고 4번에서 read 하는 조건 플래그 값을 update 하는데 첫번째 스탭에서 해버리면 다음 스탭에서 read 를 못하게 되버립니다.

그리고 2번 과정도 각 테이블마다 거의 똑같고 마지막에 조건에 따라 저장할 테이블만 분류하는 과정만 있는건데 그거를 스탭마다 중복되게 하는 것도 그렇습니다.

 

구현 상황을 보셨을 때 어떤 식으로 처리하는게 좋다고 생각하시는지 궁금합니다.

 

답변 2

1

정수원님의 프로필 이미지
정수원
지식공유자

음..

이 부분은 사실 코드를 직접 확인하고 테스트 하면서 완성해 나가야 하는 부분이라 구체적인 답변을 드리기가 쉽지 않네요

스텝을 여러개 이용한다면 중복코드가 생길 수 있고 reader, processor, writer 를 각 생성해서 하기에는 너무 복잡할 수도 있습니다.
저도 이런 경우에는 이런 저런 방식으로 계속 테스트 하면서 최선의 방법을 택합니다.
중복을 피할 수 없다면 객체지향적인 방법으로 중복을 최소화 하는 방식으로 갈 수도 있습니다.

스프링 배치에서 기본적으로 제공하는 API 로 해결이 되지 않는 부분은 어차피 최대한 커스트 마이징 할 수 있는 환경을 자체적으로 만들어야 합니다.

혹시 전체 강의를 다 들으셨는지는 모르겠는데 후반부에 보시면 멀티스레드 관련 내용이 나오는데 그 중 파티셔닝 관련 챕터가 있습니다.

그 강의가 도움이 될 수 도 있습니다.

여러 스레드가 데이터를 읽고 처리하고 쓰기 작업을 하는데 읽기 작업을 할 때 스레드마다 조건에 따른 데이터를 각각 읽어서 각각 처리하고 각각 쓰기 작업하게 됩니다.

물론 멀티 스레드관련 주제가 약간 어려울 수도 있습니다.

한번 참고해 보시기 바랍니다.

1

안녕하세요, 인프런 AI 인턴입니다.

김기훈님, 스프링 배치에 관한 깊이 있는 질문을 주셔서 감사합니다.

스프링 배치에서 말씀하신 상황을 처리하는 일반적인 방법은 다음과 같습니다:

  1. ItemReader를 사용하여 플래그 값 기준으로 데이터를 읽습니다.
  2. ItemProcessor에서 비즈니스 로직에 따라 데이터를 처리하고, 필요에 따라 중간에 DB 조회나 업데이트를 진행합니다.
  3. 처리된 데이터를 ItemWriter에 전달하기 전에, Classifier를 이용하여 어떤 ItemWriter들을 사용할지 결정합니다.
  4. 모든 데이터 처리가 완료된 후에, 일괄적으로 플래그 값을 업데이트하는 별도의 스텝을 둘 수 있습니다.

CompositeItemWriter를 사용할 때는 각각의 writer가 항상 작업을 수행하는 방식이기 때문에, ClassifierCompositeItemWriter를 통해 각 상황에 맞는 writer를 결정하는 방식이 바람직합니다. 그러나 ClassifierCompositeItemWriter가 한 번에 하나의 writer만 작동하도록 설계되었다는 부분에 주목해야 합니다. 이 부분은 각 케이스에 맞는 custom writer를 구현하여 해결할 수 있을 것입니다.

말씀하신대로 각 스텝에서 같은 데이터를 여러 번 읽는 것은 비효율적일 수 있으나, 이는 Job 내에서 공유되는 JobParameters나 ExecutionContext를 사용하여 최적화할 수 있습니다. 업데이트는 모든 스텝이 수행된 후에 한 번만 실행되도록 설계하는 것이 좋습니다.

정확한 아키텍처는 구현하려는 비즈니스 로직의 세부사항에 따라 달라질 수 있으므로, 복잡한 로직을 담당하는 ItemProcessor와 ItemWriter의 구현을 세심하게 설계하시고, 여러 Writer들을 적절히 조합하여 사용하시길 권장합니다.

추가로, Spring Boot Reference Documentation에서 배치 어플리케이션 관련 섹션을 참고하시면 구현에 도움이 될 만한 정보를 얻으실 수 있을 겁니다.

배치 프로세스 설계에 어려움이 있을 때는 단순화와 모듈화를 기반으로 단계별로 나누어 접근하는 것이 도움될 수 있습니다. 각 스텝을 독립적으로 또는 조건에 따라 서로 정보를 교환하며 실행할 수 있는 방식을 고민해보시는 것도 좋을 것입니다.

프로젝트의 성공을 기원합니다!

김기훈님의 프로필 이미지
김기훈

작성한 질문수

질문하기