팀 프로젝트64 조회 성능 향상시키기(7) Semaphore에서 Mutex로 갈아타기 개요현재 단일 인스턴스 환경에서 비동기 쿼리 동시실행 제어를 Semaphore로 진행하고 있었다.근데 생각해보니까 하나만 허용할거면 Mutex가 더 나을 거 같아서 리팩토링 하게 되었다 Mutex vs Semaphore항목MutexSemaphore주 목적상호 배제 (Mutual Exclusion)리소스 수 제한된 접근 제어값0 또는 1 (이진락)0 이상 (카운터)오버헤드보통 더 적음보통 더 큼시스템 콜대부분 커널 공간 필요대부분 커널 공간 필요사용자 수1개 스레드만 소유 가능여러 스레드가 접근 가능 뮤텍스가 보통 더 가벼운데, 오직 하나의 스레드만 접근 허용하기 때문에 0 또는 1의 간단한 상태만 관리하면 되기 때문이다.커널 락 사용 방식이나 구현체에 따라 차이는 있지만, 카운트 관리가 필요 없는 뮤텍.. 2025. 4. 10. Transactional인데, 왜 Redis 로직에서 Connection을? 개요2025.04.04 - [팀 프로젝트/플러스 프로젝트] - Transactional-Readonly가 어플리케이션에 미치는 영향 Transactional-Readonly가 어플리케이션에 미치는 영향개요Hot Key를 관찰하려고 부하테스트를 하던 도중, 세션 자동 생성에 이어 이상한 점을 하나 더 발견했다.우선, 짧게 실험 결과를 요약하고 가면..1. 실험 목적:Hot Key가 Redis 또는 시스템에 어떤 영roqkfchqh.tistory.com지난번에 이어서... Transactional Readonly에 관한 글이다.Transactional readonly를 불필요한 상황에서 사용했을 때 쓸모없는 DB 커넥션이 생겨버려서 부하가 몰릴 경우 어플리케이션 전반의 latency가 증가하는 현상을 관측할.. 2025. 4. 6. Transactional-Readonly가 어플리케이션에 미치는 영향 개요Hot Key를 관찰하려고 부하테스트를 하던 도중, 세션 자동 생성에 이어 이상한 점을 하나 더 발견했다.우선, 짧게 실험 결과를 요약하고 가면..1. 실험 목적:Hot Key가 Redis 또는 시스템에 어떤 영향을 미치는지 확인2. 실험 조건:key: "popular:market:items"TTL: 무제한 - '인기 검색' 은 redis만 사용하도록 할 것이기 때문. 물론 fallback도 존재함.JMeter: 3000유저 / 1초 ramp / 1000 loopRedis: 단일 인스턴스, 로컬실험 도중 1-2번의 Key Update 진행하여, 시스템에 미치는 영향 확인사용한 툴: Prometheus, Grafana, Jmeter3. 결과 요약:Redis key rate(GET)초당 5000~6000.. 2025. 4. 4. Actuator가 자동으로 Session을 생성한다 개요Redis Hot Key Issue를 겪어보려고 Jmeter로 부하테스트를 돌리는 도중에 이슈가 발생했다.정확히는 Hot Key 부하테스트와 관련은 없지만, Redis Insight를 뒤적거리다 발견했다.어플리케이션을 켜놓고 가만히 놔뒀는데, 세션이 스스로 생성되었다..하나에 632B라 무시할만한 수준이라고 생각할 수도 있지만, 15초에 한번 Metrics를 수집하며 이것의 TTL이 30분이니까 서버가 지속될 때 최대 약 74KB * 인스턴스 개수 만큼 Redis에 쌓인다.그리고 어쨋든 버그기도 하고.. 거슬린다. 대체 왜 생긴걸까? 파악너무 예전에 만들었던 Session + Security 구조라 기억이 잘 안 나니까 우선 세션이 어디에서 생성되는지 로그를 찍어보자.@Slf4j@Componentp.. 2025. 4. 2. 조회 성능 향상시키기(6) Redis Hot Key Issue Redis Hot Key?Hot Key는 말 그대로 "너무 자주 접근되는 단일 키" 이다. 이때 요청이 모두 읽기일 경우와, 일부라도 쓰기가 섞인 경우는 시스템 관점에서 부하의 성격이 완전히 달라진다. MESI 프로토콜MESI 프로토콜은 멀티코어 CPU 환경에서 캐시 일관성(Coherency)을 유지하기 위한 프로토콜이다.MESI는 각각의 캐시 라인이 4가지 상태 중 하나를 가지도록 해서, 각 CPU 코어가 동일한 메모리에 주소에 접근하더라도 데이터 불일치를 막아주는 방식이다. MESI의 4가지 상태는 다음과 같다:Modified (수정)이 캐시 라인만 최신 데이터를 가지고 있고, 메모리에는 반영 안 됨다른 캐시에 없음 + dirty 상태Exclusive (배타적)이 캐시 라인만 데이터 가지고 있고, .. 2025. 4. 1. AOP(트랜잭션)와 try-catch 개요2025.03.08 - [팀 프로젝트/최종 프로젝트] - 트러블슈팅: 크롤링 시 트랜잭션 범위가 너무 길다 트러블슈팅: 크롤링 시 트랜잭션 범위가 너무 길다현재 문제점크롤링을 진행하는 메서드 전체에 트랜잭션이 잡혀있다.크롤링 해올 페이지가 적은 상황에선 문제가 안 되지만, 여러 페이지를 한 트랜잭션에 포함시킬 때 문제가 될 수 있다.중간roqkfchqh.tistory.com이 문제를 해결할 때, 한 클래스 내에서 트랜잭션 같이 사용하면 정상적으로 작동하지 않는다는 걸 어렴풋이 알고는 있었지만,왠진 모르겠지만 그냥 되길래(??) 잠시 묻어두고 넘어갔었다. 그러다 지금 AOP를 공부하다가 깨달았다.Spring의 트랜잭션은 AOP 기반이다. 즉, 프록시를 통해 메서드가 호출될 때만 트랜잭션이 적용된다. 그.. 2025. 3. 27. 조회 성능 향상시키기(5) Semaphore로 비동기 쿼리 동시 실행 제어하기 개요현재 로직에는 잠재적인 문제가 존재한다비동기 방식으로 캐시 갱신 쿼리를 실행할 경우, 최소 1초에 한 번 실행될 수 있다.하지만 일시적인 DB 부하로 인해 쿼리 실행 시간이 1초 이상 걸리는 상황이 발생한다면, 다음과 같은 문제가 생길 수 있다 1. 동일 작업이 중복 실행되어 jvm의 스레드 자원이 낭비된다.2. 캐시 갱신 타이밍이 겹치면서 race condition이 발생할 수 있다.3. 불필요한 느린 쿼리들이 중복 호출될 수 있다(현재 기준 동일 네트워크 상에서 평균 600ms로 빠른 편이 아니다) -> 결과적으로 어플리케이션, DB, Redis 모두에 영향을 끼칠 수 있다. Semaphore세마포어를 활용해 비동기 메서드 실행을 하나의 스레드로 제한하는 방식으로 문제를 해결할 수 있다고 판단했.. 2025. 3. 26. LazyInitializationException 개요프로젝트 기간에 발생했던 오류다. 시간에 쫓겨 정확한 원인을 파악하지 못한 채로 해결했었는데, JPA 공부를 하다가 깨달은 부분이 있어서 되짚어보기로 했다북마크를 조회할 때, LazyInitializationException이 발생했다.개발하신 분 환경에서는 오류가 발생하지 않았지만, 운영 환경과 내 로컬 환경에서는 동일한 오류가 발생했다.이로 인해 개발자 분께서 직접 디버깅이 어려운 상황이었고, 내가 수정해야 하는 상황이었다.비슷한 맥락으로 이런 오류도 볼 수 있다. 지연 로딩과 프록시지연 로딩이란, 연관관계를 가진 엔티티를 즉시 불러오지 않고 실제로 사용할 때 까지 로딩을 미루는 전략이다.이렇게 FetchType.LAZY로 설정하면 Bookmark 객체를 조회할 때 user는 즉시 DB에서 불러.. 2025. 3. 25. 조회 성능 향상시키기(4) 인기 품목 조회 최적화 개요인기 거래소, 경매장 조회를 어떻게 구성할지 고민이 된다.일반적인 캐시 방식으로 설계할 경우 설계에 따라 사용자가 보게 되는 수량이나 가격 정보가 실제 데이터와 달라질 수 있다.특히 인기품목은 거래가 활발히 이루어지기 때문에, 캐시를 사용하면 이미 품절된 상품이 인기품목으로 계속 노출되는 문제가 발생할 수 있다.그렇다고 DB에서 직접 조회하기에는 부담이 있다. 현재 기준으로도 거래소는 621ms, 경매장은 322ms로 성능이 썩 만족스럽진 않으며,실제 운영 환경에서는 삽입 및 수정 요청까지 동시에 발생할 가능성이 높아서 락 경합이 발생할 위험이 있다.이 문제를 어떻게 해결할 수 있을까? 고려 중인 전략1. 캐시 + 스케줄러 도입을 통한 성능 개선상대적으로 변동이 적은 인기 품목은 역시 캐시 스케줄러.. 2025. 3. 24. 조회 성능 향상시키기(3) Pagination Count Query 최적화 문제 상황현재 '전체 경매장 조회'는 커버링 인덱스로 개선하였음에도 불구하고 702ms로 1초 가까이 소모된다.로컬에서 네트워크 지연시간이 0ms인 걸 감안하면, 실제 서버에선 1초가 넘는다는 소리다 수많은 개선방법이 있겠지만, 나는 count query 최적화를 우선 진행하기로 했다.'전체 거래소 조회' 에도 같은 로직을 적용할 수 있기 때문이다. count query 최적화는 꽤 많은 방법을 적용해볼 수 있을 거 같다. 하나씩 적용해보고 장단점을 비교해보자. count query 개선 방법우선 대상 count query들은 이미 index를 꽤 잘 타고 있기 때문에 DB레벨에서의 최적화는 더이상 힘든 상황이다. 1. 마지막 페이지 근처에 도달하기 전까지는 count query 생략하기데이터가 100.. 2025. 3. 23. 이전 1 2 3 4 ··· 7 다음