진짜 개발자
본문 바로가기

전체 글 (총 580개)

Spring JPA - @OneToOne 관계에서 Lazy로딩이 동작하지 않는 경우 문제상황 User와 Car는 OneToOne 양방향 관계입니다. 연관관계의 주인은 User입니다. 성능 향상을 위해, @OneToOne 관계의 FetchType은 거의 항상 LAZY 전략을 사용하고 있었습니다. (물론, 어플리케이션의 특성에 따라 대부분 항상 같이 조회된다라면 EAGER를 사용할 수 있겠지만, 그래도 FetchType은 LAZY로 두고 필요한 곳에서 FetchJoin을 사용하는 편입니다.) 그런데, 분명 LAZY 전략이 적용되어 있지만, 조회 시에 연관관계를 로딩하기 위해 즉시, 추가 쿼리가 발생하는 상황이 발생했습니다. 원인 파악 원인 파악을 위해 여러 시도를하다가, 연관관계의 주인인 User를 조회하는 경우에는, LAZY Loading이 정상 작동함을 확인할 수 있었습니다. 반대로, ..
ApplicationKnowhow/Server - 성능 개선기 3 (Jvm Heap 설정) Server의 Memory 공간은 충분해 !(?) 최초 테스트 시, 2CPU, 1GB Mem 의 자원으로 테스트를 진행했습니다. 또 테스트를 하는 동안 memory는 부족한 적이 없었습니다(그런줄로 믿고 있었습니다). 항상 htop으로 appServer의 cpu와, mem을 모니터링을 한 결과 memory는 사용률이 70%정도도 안되었기 때문에 memory가 부족하지는 않은 것으로 생각을 하고 CPU만을 scale up하여 테스트를 진행했었습니다. visualVM으로 Heap영역을 확인을 해보아도 maxHeap Size 250MB이며 usedHeap size는 30MB 정도로 아직 여분이 많이 남아있었기 때문에 더더욱 아닐 것이라고 생각을 했습니다. (저 그래프를 처음 볼 당시에는 현재 heap의 siz..
ApplicationKnowhow/Server - API 성능 개선기 2 (Query 개선) 이번에 테스트할 대상 API는 특정 영화의 당일 상영 목록을 반환하는 API입니다. 우선 어느정도의 성능이 측정 되는지 확인해보도록 하겠습니다. 약 평균 22 TPS, 660ms Latency 의 성능이 측정되었습니다. 이전 영화 목록 조회 API에 비해 더욱 성능이 감소되었음을 확인할 수 있습니다. 1차 개선(JPA 관련 성능 개선) 1. 원인 파악 Hibernate에 의해 발생하는 쿼리를 로그를 통해 확인해보니, seats에 대해서, N+1문제가 발생하는 것을 볼 수 있었습니다. 2. 개선 과정 좌석에 대해 fetch Join을 설정합니다. (추가로 MovieEntity에 대해서도 fetch Join을 합니다) 단 한번의 쿼리만 발생한 것을 확인할 수 있습니다. 바로 부하테스트를 다시 진행해보도록 하..
ApplicationKnowhow/Server - API 성능 개선기 1 (JPA 성능 개선(kotlin)) 이번 부하테스트 대상 API는 DB 참조가 포함된 API입니다. 최초 단순 문자열("OK")을 반환하는 API에 대해 부하테스트를 진행하여 900 TPS, 9ms Latency 정도의 성능을 내는것을 파악했습니다. DB 조회가 추가 되었을 때 어느 정도의 성능 저하가 발생하는지 확인을 위해 부하테스트를 진행해보겠습니다. 1. 원인 파악 TPS가 정말 급감하는 것을 볼 수 있습니다. 여러번의 테스트 결과 평균 195TPS, 76ms Latency 의 성능을 보였습니다. 병목 현상이 어느 곳에서 발생하는지를 관찰하기 위해 Thread Dump를 분석하기로 했습니다. 당연하겠지만, 실행중인 대부분의 thread 들은 위와 같이 SQL관련 메소드들을 실행중이었습니다. Thread Dump 분석 중 이상한 부분을..
Spring JPA - JPA N+1 문제 완전 정리 N+1에 대해 포스팅한지 1년이 넘어 제대로 다시한번 정리하는 차원에서 이번 포스팅에서는 N+1이란? N+1이 발생하는 경우 X To One 관계 N+1문제와 해결방법 X To Many 관계 N+1문제 주의할 점 들에 대해서 알아보도록 하겠습니다. EAGER vs LAZY 그리고 마지막으로는 Eager와 Lazy중 어떤것을 사용하면 좋을지에 대해서도 생각을 해보도록 하겠습니다. 사용 언어는 Kotlin 이며, Spring Boot + JPA를 이용했습니다. https://github.com/galid1/jpa_study 코드는 위에서 보실 수 있습니다. 1. N+1 이란? N+1 문제는, JPA의 Entity 조회시 Query 한번 내부에 존재하는 다른 연관관계에 접근할 때 또 다시 한번 쿼리 가 발생하..
Redis - 영속화(Persistence) 이번 포스팅에서는 Redis의 영속성(Persistency) 에 대해서 알아보도록 하겠습니다 1. RDB 첫번째 영속성을 얻기 위한 방법은 RDB입니다. 관계형 DB가 아니라, Redis Database의 줄임말입니다. 이 방법은 지정된 간격으로, 데이터의 스냅샷을 찍어 저장합니다. 즉, 현재 메모리에 저장된 데이터 상태들을 특정 시점에 저장하는 방법을 말합니다. 장점 RDB는 매우 압축된(작은 크기의) 특정 시간에 대한 메모리 상태(데이터)를 나타냅니다. Ex) 예를들어, 시간마다, 또는 매일 스냅샷을 통해 Redis에 장애가 발생한 경우 원하는 특정 지점의 데이터를 복구할 수 있습니다. 별도의 저장소로 보낼 수 있는 단일 압축 파일이기 때문에 재해 복구에 좋습니다. 단점 특정 시간마다 현재 메모리의 ..