본문 바로가기
반응형

혼자 공부하는 것들/Spring28

Spring Batch에서 Bulk Insert로 전환하기 회사에서 혼자 관리하고 있는 배치가 40개가 넘는다.... 허허... 특정 기존 배치가 너무 느려 성능 최적화를 일정을 잡고 진행하기로 했다. 최적화를 한 번 해본 경험이 도움이 되었는지 첫 번째로 구조적으로 문제가 없는가?를 판단했다. 처리해야 하는 데이터는 볼륨이 얼마나 되는지, 읽어오는 쿼리가 최적화가 되어있는지, 메모리 누수는 없는지 등등... 정확하게 파악해 나갔다. 특정 Step에서 대략 2500만 데이터를 읽어서 10개가 넘는 테이블에 적재해야 하는 작업이 발생했다. 이 시점에 정말 느려 최적화가 필요했다. 일단 이 Step에서 병렬처리(Parallel)로 진행하도록 변경했다. 메모리 사용량도 증가시켰다. 병렬처리의 키가 될 수 있는 데이터를 분석해서 thread를 20개로 적용해 놨다. 기.. 2024. 2. 3.
Spring Batch Partitioner를 이용해서 병렬처리할 때 주의점! 배치에서 여러 개의 하위 Step에 OOM이 발생했다. 원인이 무엇일까? 해당 배치에 Heap Dump를 분석했다. 특정 배치가 뒤로 갈수록 메모리 사용률이 90%가 넘는 것을 확인했다. 다시 확인해 봤다. 특정 Step에서 병렬처리하기 위해 partitioner를 사용해서 병렬처리를 하고 있는데 이 방식이 잘못된 것을 인지했다. 보편적으로 병렬처리 할 Setp이 실행되기 전 partition을 구하고 병렬처리하는 것이 일반적이다. 해당 배치는 병렬처리하는 Step이 많아 파티션을 공통으로 사용하도록 설계되었다. public class StepUtil { public static Map context; ~~~~~하위 코드작성~~~~~~ } 이런 정적(static) 클래스로 파티션이 될 모수를 미리 구해놓.. 2023. 9. 28.
Spring Batch(+Mybatis)에서 Commit하기 전 실행된 SQL 문의 개수를 확인하고싶으면? 정말 간단한 배치를 만들고 있었다. 복잡하지 않아서 Tasklet방식으로 만들었다. 간단히 설명하자면 하나의 Step에서 자료를 밀어 넣고 넣은 총개수를 다른 테이블에 넣어주는 작업이 있었다. 물론 step을 나눠서 하는 방법도 있었지만, 정말 간단한 배치고 일 년에 한 번 정도로 사용 빈도도 적어 하나의 Step에서 처리하고 싶었다. insert를 하고 commit 하기 전에 개수를 확인할 수 있는 방법은 없을까? 찾아보니 확인할 수 있는 방법이 있었다. import org.springframework.batch.core.StepContribution; import org.springframework.batch.core.scope.context.ChunkContext; import org.springf.. 2023. 7. 15.
서버가 죽었다!.... 502....(100 % of root file system is in use. 0 MB free.) 주말 동안 삽질을 오지게 했다... 정리할 겸... 작성해 보자... 현재 Amazon Elastic Beanstalk, EC2로 서버를 운영하고 있다. 물론 인스턴스는 t2.micro로 무료버전을 쓰고 있다. 잘 사용하다가 갑자기 배포가 안된다... Git-Actions로 배포파이프라인을 구축해서 사용하고 있다. EC2의 볼륨을 8GB로 사용하고 있어서 부족한 걸까?.... 확인해 보자! 100 % of root file system is in use. 0 MB free. 예상이 맞았다. 어떤 파일이 용량을 잡아먹고있는지 확인해 보니 로그 파일이 원인이었다. https://stackoverflow.com/questions/50847838/running-out-of-disk-space-in-amazon-.. 2023. 5. 6.
회사에서 Spring batch 짜면서 삽질한거 정리 요즘 배치 작업을 하면서 항상 벽에 막힌다... 데이터 양이 많아 일반적인 처리방식으로는 평생 안 끝날 것 같다... 그래서 DB 테이블을 업무에 맞춰서 파티션을 나누기도 하고 인덱스를 어떻게 잡아야 하는지도 많이 고민했었다. 혼자 끙끙 앓고 있었는데 유튜브에서 아주 좋은 영상을 봤다. https://www.youtube.com/watch?v=2IIwQDIi3ys 직접 겪어보니 더 재미있었다. 병렬 처리 할 때는 파티션을 나누는 기준부터 각 데이터 순서를 보장해야 하는 작업은 별도로 청크방식으로 작업하고 순서를 보장 안 해줘도 되는 작업은 병렬처리를 통해 속도를 개선하고 있다. 특히 병렬 처리 할 경우 스레드 안정성도 고려해야 하고 서버 자원의 대한 이해가 있어야 한다... 암튼... 성능 최적화가 더 .. 2023. 4. 5.
@Component는 어떻게 동작하는 걸까? 실무에서 @Component로 Bean을 편리하게 만들어줘서 사용하고 있지만, 동작 원리부터 어떤 식으로 작용하는지 궁금했습니다. 일단 @Component를 쓰기 위해서는 @ComponentScan과 @Configuration을 알아야 합니다. @Configuration는 간단하게 이야기하자면 해당 클래스는 설정파일이라고 인식시켜 주는 것입니다. Bean Object 생성 이상으로 전체 애플리케이션을 구성하는 가장 중요한 기능들을 넣을 수 있습니다. @ComponentScan는 @ComponentScan를 적용한 해당 클래스 아래에 있는 @Component가 붙은 모든 클래스들을 Bean으로 등록할 수 있게 도와줍니다. 필요하다면 의존 Object를 찾아서 생성자를 찾아 파라미터로 넘겨주기도 합니다. @.. 2023. 1. 24.
spring-data-envers로 데이터 변경 이력(히스토리)을 관리해보자! Spring Boot + JPA로 상품 주문 프로세스 주제로 사이드 프로젝트를 하고 있었습니다. 이때 상품 주문에 대한 히스토리를 어떻게 관리해야 할지 고민을 했었습니다. 첫 번째 방법으로 직접 주문 히스토리 테이블을 설계하여 상품 주문, 취소 등등... 데이터가 변경될 때 하나하나 직접 테이블에 넣어주는 방식으로 설계하다 보니 정확한 시점에 못 넣는 일이 발생하고 사람이 코드로 직접 넣는 거다 보니 데이터에 적합성도 떨어졌습니다. 또한, 똑같은 코드가 반복해서 들어가는 보일러 플레이트 코드가 생산되는 단점이 있었습니다. 찾아보다가 spring-data-envers라는 데이터 변경을 쉽게 관리할수있도록 도와주는 것이 있다고 하여 학습하여 적용시켰습니다. https://github.com/hygl/spri.. 2022. 9. 4.
[Spring] @RequestBody는 객체로 받자! PUT으로 해당 JSON 객체 요청이 들어온다고 가정해봅시다. PUT {URL/~} content-type: application/json { "phoneNumber": "010-0000-0000", "name": "김아무개", "age": 28 } Body에 핸드폰 번호, 이름, 나이의 정보를 받습니다. 이때! Map을 사용하지 말고 객체를 생성해서 만들어줍시다. /** * 사용자 승인 * @param req * @return */ @PutMapping("/~") public Object approvalFrom(@RequestBody Map req){ ... } 이런 식으로 하면 문제점이 무엇일까요? Map으로 리퀘스트를 처리할 경우 어떤 값이 넘어오는지 알 수 없고, 관리하기가 다소 어렵습니다. 정확.. 2022. 5. 30.
Reflection(리플렉션) 활용 앞서 프록시를 사용해서 기존 코드를 변경하지 않고 부가적인 기능들을 추가할 수 있는 방법을 배웠습니다. 앞 게시글에서 보았듯이 프록시만 적용한다면 해당 클래스 수만큼 부가적인 기능을 위한 프록시 클래스를 만들어야 한다는 단점이 있습니다. 이러한 단점을 보안하기 위해 자바에서 기본적으로 제공하는 JDK 동적 프록시 기술이나 CGLIB(개발자는 굳이 사용할 일이 없지만 그래도 알아놓자!) 같은 프록시 생성 오픈소스 기술을 사용하면 객체를 동적으로 만들 수 있습니다. 간단하게 리플렉션을 설명하자면 클래스나 메서드의 메타정보를 사용해서 동적으로 호출하는 메서드를 유연하게 끼워 넣을 수 있습니다. https://applepick.tistory.com/160 2022. 5. 22.
반응형