Programming/Java

Spring Batch에 대한 고찰

armyost 2023. 3. 31. 17:51
728x90

배치가 단순히

Fetch From Source > Data CUD > Data Write

이런 프로세스라면 어려울 것도 없다.

 

데이터가 많은 금융, 산업 쪽은 배치가 무지무지 복잡하다...

배치가 복잡해지는 이유는 다음의 요소들이 흐름에 끼어있기 때문이다.

 

1. FETCH SOURCE가 여러개

 

2. DATA WRITE DESTINATION이 여러개

- 병렬 WRITE

- 분기 WRITE

 

3. FETCH DATA FILTERING을 통한 다이어트

 

4. DATA 가공 과정에서 분기

- 단순 분기

- 동적 조건에 따른 분기

 

 

이런 요소들로 인해서 복잡한데 이걸 극복하는 컨셉은 크게 두가지가 있다.

. Spring Batch Object를 써서 극복할 것인지

. JAVA SQL로 극복할 것인지

 

. Spring Batch Object로만 해결한다면 가독성이 좋긴하다. 그리고 기능이 직관적이라 리뷰가 좋다. 다만 JAVA개발자가 Object에 대한 이해도가 필요하고 쌩코딩에 비해서는 자유도가 떨어진다.

. 높은 자유도와 친숙함을 준다. 다만 코드가 길어지고 일일이 소스를 까봐야 이해할 수 있다.

 

필자는 원칙보다 가치와 퀄리티를 중요하게 생각하기 때문에, 개발이 쉬운 방법을 선호한다. Object를 어떻게 배치할지 연구할 시간에 Data의 논리적인 흐름을 심플하게 개선하는게 더 가치 있어 보인다.

 

따라서 위의 4가지 복잡성 Case는 아래와 같이 극복하였다. 물론 정답은 아니다.

 

1. FETCH SOURCE가 여러개

  TABLE JOIN으로 해결해야 하고, JOIN으로 합칠 수 없는 상이한 포맷인 경우에는 무리하게 하나로 짜지말고 배치를 나누는 것도 좋은 방법인거 같다.

 

2. DATA WRITE DESTINATION이 여러개

- 병렬 WRITE

 compositeItemWriter를 쓰는게 좋아보인다. 명확해서 좋다.

- 분기 WRITE

→ 조건이 따라 쓰기 대상이 달라지는 경우 그냥 if조건문을 사용하자.

※ 만약 해당 Step 이후에도 수행할 프로세스가 많이 남아있다면 Classfier로 분기시켜야한다. 왜냐면 if로 분기시키는건 실제로 레코드를 쪼갠게 아니라, 같은 레코드에서 엑션만 다르게 주었을 뿐이기때문이다. 후속프로세스가 많은경우 레코드를 아에 쪼개서 독립적으로 흘리는것이 좋다

 

3. FETCH DATA FILTERING을 통한 다이어트

 itemProcessor에서 if조건문을 통해 return null하여 불필요한 Data 없애기

 SQL문에서 조건식을 사용해도 해결가능하나 가독성이 떨어지고 SQL 성능이 떨어지는 단점이 있음

 

4. DATA 가공 과정에서 분기

- 단순 분기

 itemProcessor에서 if로 조건을 주고 Data 가공 수행

- 동적 조건에 따른 분기

 itemProcessor에서 if로 조건을 주고 Data 가공 수행