Search
Duplicate

[Java] FokeJoin, newFixedThreadPool, ThreadPoolTaskExecutor

순서
2
날짜
2023/01/25
사람
상태
Done
오늘은 일괄의 데이터처리를 수정한 작업에 대해 정리하도록 하겠다.
관령링크 - 일괄처리 데이터
[일괄 데이터 처리]위에 언급한 테이블을 업데이트 할때마다 API를 전송해야되는데, 이를 일괄로 처리하고 있다. 일반유저를 대상으로 하는 웹사이트가 아니기때문에 쓰레드로 하는게 맞다고 생각하는데, 일반유저가 사용하는 부분이라면 비동기 방식으로 작업을 진행해야된다.
1.
사전 조사 어떻게 처리하면 좋을지 분석.
쓰레드풀을 사용하는 방법은 3가지
FokeJoin
ExecutorService
ThreadPoolTaskExecutor
현재 발생하는 문제를 해결하기위해 새로운 배치서버를 구성하고, 배치서버에서는 일괄검수에 대한 로직만 처리하기 때문에 newFixedThreadPool을 사용하여, 50만건의 데이터를 한번에 처리 할수있는 메모리를 지정하고, 사용하는게 정답이라고 생각하였다. 만약 배치버서에서 새로운 로직을 추가로 한다면, ThreadPoolTaskExecutor을 사용하면 될 것으로 보인다.

FokeJoin

해당 하는 부분은 잘 정리해놓은 글이 있어서, 링크로 첨부하도록 하겠다.
문제점 : FokeJoin을 사용하면, 테스트 결과 newFixedThreadPool 보다 빠르다는 것을 알 수 있다. 하지만 주의해야 될 점은 따로 있엇다. FokeJoin안에 비동기 방식의 처리가 있으면, get함수를 지정할 때 Thread를 지정했던 것보다 더 발생한다는 것이다. 아래 링크를 보면, 비동기 방식의 로직이 있을경우 newThread함수가 동작되고, 쓰레드가 증가되는 것을 알 수 있다. 이를 해결하기 위해서는 Future를 사용해야되고 이렇게 할 시 Blocking 되면서 처리속도가 급격하게 증가한다.

newFixedThreadPool

해당하는 부분은 잘 정리해놓은 글이 있어서, 링크로 첨부하도록 하겠다.
고정적인 쓰레드를 생성하고, 재사용하는 방식으로 한가지 작업만 처리하는 배치서버에는 알 맞는 방법인것으로 보인다.

ThreadPoolTaskExecutor

해당하는 부분은 잘 정리해놓은 글이 있어서, 링크로 첨부하도록 하겠다.
동시처리를 위해 고려중이라면 위에 링크를 보면 이해가 될 것으로 판단되고, 현재 내가 처한 문제에서 가장 안정적이고, 처리속도가 좋은 것을 선택하기위해 테스트 했던 테스트 코드를 공유하려 한다.
1.
Runtime.getRuntime().availableProcessors(); : 현재 최대 프로세스를 가져온다.
2.
10만건의 데이터를 기준으로 테스트한다.
소스코드
결론
현재 10만건의 데이터 기준으로 테스트를 해봤을때, 일반 ArrayList가 Future blocking 처리를 한 동시 쓰레드보다 빠르다는 것을 알 수 있다. 때문에, 굳이 Future를 사용해서 동시처리를 할 것이라면, List를 사용하는게 좋을것이라고 생각된다.
Future를 사용하지 않고, 동시처리중 비동기 방식을 사용하지 않는다면, ForkJoinPool+ParallelStream
Future를 사용하지 않고, 동시처리중 비동기 방식을 사용한다면, newFixedThreadPool사용
Future를 사용한다면 ArrayList를 사용, 동시처리가 더 늦을수 있다.