트러블슈팅과 고민28 Single Flight 운영 중 스레드 풀 포화 비율 50% 식별, Soft TTL 전환으로 5배 개선 1. 배경2. 결론 요약3. 스탬피드 발생 상황4. 싱글 플라이트5. 가상 스레드 (자바 25)6. PER 7. 소프트 TTL 1. 배경비밀로그에는 다른 사용자의 롤링페이퍼로 가기위해 모든 회원의 목록을 볼 수 있는 공간이 있다. 캐시 구조는 String을 쓰며 키는 member:page:0:size:10 형식으로 0페이지의 사이즈 10 을 나타낸다.값에는 회원 이름이랑 회원 ID의 목록을 JSON으로 넣었다. 사용자가 요청한 페이지와 사이즈를 그대로 캐싱하여. 캐시 어사이드로 갱신하고 삽입시에는 DB에만 저장한다. TTL은 1분이다. 캐시 스탬피드 방지 목적으로 싱글플라이트를 적용하였는데 스레드 스파이크 현상이 식별되었다.따라서 다른 스탬피드 방지 전략들을 테스트 하였다.스탬피드 발생 상황부터 천천히.. 2026. 4. 25. DI, IoC, AOP에 관한 고민 책이나 인터넷 강의에서는 DI, IoC, AOP에 대해서 잘 알려주지만 많이 들어도 역시나 모호한 면이 있다.그것은 직접 코드가 물리적으로 돌아가는 것을 보지 못해서인것같다.그동안 고민도 많이하고 자바로 스프링도 조금씩 만들고 있는데 내 나름대로의 결론이다. 아직까지 부족한 면이 있을것이다. DI 1. IoC를 구현하는 방법중하나2. 프록시빈을 주입할 수 있어 AOP를 가능하게한다.3. 개발자가 하나하나 팩토리를 작성할 필요 없음4. 외부에서의 구현체 주입으로 구현체 변경에도 수정이 일어나지 않아 결합도 하락 (구현체가 여러개일때 프라이머리) IoC1. 객체의 생성, 생명주기, 메소드의 실행 흐름등을 외부로 위임2. 객체를 생성하지 않아 결합도 하락 (new 연산자의 외부 이동) (DI가 없으면 구현체 .. 2026. 3. 15. 레디스 파이프라인으로 인한 Netty 태스크 큐 병목 식별 및 해결 후 Spring Data Redis 기여 목차 1. 서론 1.1 오류발생 1.2 상황종합 1.3 결과요약2. 원인 탐색 2.1 FD, Redis 커넥션, 메모리, 로그, 실행시간 분석 2.2 커넥션 풀이 없는 경우 파이프라인의 동작 2.3 Redis가 수신한 커넥션과 현재 커넥션 수의 괴리 2.4 레터스의 첫 응답 마지막 응답 시간 비교 - 병목 시간 식별 2.5 Lettuce의 커넥션 해제 로직 - Netty 이벤트루프 호출 2.6 Redis CPU 2.7 Unable to connect to Redis 발생 이유 2.8 Pipeline contained one or more invalid commands 발생 이유 2.9 재테스트 - Netty 병목 식별 2.1.. 2026. 3. 9. DB의 4500만개의 데이터를 레디스로 옮기기 너무 바빠서 아직 글을 완성하지 못했습니다 ㅠ제 서비스에는 친구관계와 멤버들끼리의 상호작용 점수가 있습니다. 이것들은 추천친구를 계산하는데 사용되며 레디스에서 관리되고 유사시에 RDB에서 복구할 수 있습니다. 친구관계는 레디스에서 Set 상호작용 점수는 ZSET으로 관리됩니다. 회원이 10만명이고 회원마다 친구가 300명 있고 회원마다 300명과 상호작용한 상황에서 레디스의 데이터가 전부 사라졌다고 가정하겠습니다. 그렇게되면 친구관계는 3000만 레코드 하지만 디비에서는 중복을 허용하지 않기에 1500만 레코드입니다. 그리고 상호작용 점수는 누군가의 글과 댓글을 추천하거나 글에 댓글을 달았을 때 작성자 끼리의 상호작용 점수가 추가됩니다.이 경우 10만명 각각이 300명과 상호작용을 했다고하면 총 3000.. 2026. 2. 28. 게시글 목록 조회 API 응답시간 200ms 이내 TPS 12.3배 개선 목차 1. 서론 1.1 서론 1.2 테스트 시나리오 및 환경 1.3 게시글 목록 조회 테스트 결과 요약 1.4 캐시 수정 상황 테스트 결과 요약2. 기존 로직 2.1 기존 코드 2.2 게시글 목록 조회 테스트 결과3. 커서 기반 페이징 3.1 로직 3.2 게시글 목록 조회 테스트 결과4. CQRS 4.1 설계 4.2 게시글 목록 조회 테스트 결과5. 캐싱 5.1 설계 5.1.1 캐싱 전략 후보군 5.1.2 TTL 전략 5.1.3 최종 전략 5.2 게시글 목록 조회 테스트 결과6. 깨달음 (CQRS 제거) 6.1 비정규화만 남기기 6.2 게시글 목록 조회 테스트 결과 6.3 캐시 변동 시나.. 2026. 2. 3. 레디스 장애 시 서킷브레이커와 로컬 캐시를 활용한 실시간 인기글 API 개선 목차1. 문제 상황 1.1 테스트 시나리오 1.2 레디스 정상 상황 테스트 1.3 DB 타격 상황 : 문제 - 성능 하락 1.4 DB 타격 상황 : 문제 - 실시간 인기글의 퀄리티 하락2. 결과 요약3. 고민 3.1 쿼리최적화 3.2 센티널, 리플리카 도입 3.3 서킷 브레이커4. 레디스 장애시 서킷브레이커로 경로 제어 4.1 서킷 브레이커 아키텍처 4.2 서킷브레이커 실시간 인기글 퀄리티 테스트 동기화 X 4.3 동기화 구현 4.4 서킷브레이커 실시간 인기글 퀄리티 테스트 동기화 O 4.5 서킷브레이커 성능 테스트 제가 운영하는 비밀로그는 SNS 서비스입니다.SNS의 특성상 실시간 인기글은 사람의 유행을 활성화하고 서로 의견을 나누며 서.. 2026. 1. 30. 실시간 인기글의 캐시 갱신시 빈 페이지 반환에 대한 개선 (스케줄러, 캐시어사이드 동시 사용) 캐시전략은 백그라운드 갱신, 라이트 어라운드, 캐시 무효화이다.실시간은 더해서 캐시 어사이드도 사용한다.게시글 수정과 삭제시 캐시를 삭제한다.캐시 무효화를 쓴 이유는 수정이 되었을 때 글 내용이 달라지는 것은 비즈니스에 타격을 준다고 생각했기 때문이다. 백그라운드 갱신을 한 이유는 빈페이지 반환을 막기 위해서다. 조회시마다 캐시 갱신을 하면 대용량 트래픽의 디비 접근을 막기 위해서 빈페이지를 반환할 수 밖에 없다. 핫 키를 계산하여 미리 갱신할 수 있지만 어쨌거나 핫 하지 않은 키는 빈페이지를 받는다. 키가 많으면 레디스의 보호를 위해 락이 있어도 핫 키를 계산해야하지만 키가 몇개 없어서 핫 키계산은 현재 사용안한다. 실시간 인기글의 스케줄러 갱신의 어려움하지만 실시간인기글은 이 방법을 사용할 수 없다.. 2026. 1. 27. 게시판 조회 쿼리 개선 게시판 조회 쿼리게시판조회는 페이징으로 특정 글 목록을 표시합니다.조건1 : 목록의 글마다 글에 달린 댓글 수가 있어야합니다.조건2 : 목록의 글마다 글이 받은 추천 수가 있어야합니다.조건3 : 차단되거나 차단한 회원의 글은 보이지 않습니다.결과 요약10000개의 글이 있을 때 페이징으로 20개 글을 조회하는 테스트를 하였습니다.쿼리첫 페이지중간 페이지마지막 페이지최초 쿼리54ms78ms130ms리팩토링 후 문제 발생778ms770ms744ms최종 개선23ms44ms66ms 1. 최초 쿼리쿼리dsl 사용 시 발생하는 sql입니다.SELECT p1_0.post_id, p1_0.title, p1_0.views, (SELECT CAST(COUNT(pl1_0.post_like_id) AS .. 2025. 12. 31. 작성자 검색 인덱스 사용 불가 문제 해결 게시판의 제목, 제목+내용 검색에는 FULLTEXT 인덱스를 적용했지만, 작성자 검색에는 적용하지 않았습니다. FULLTEXT에는 불용어 개념이 있습니다. 한마디로 텍스트를 언어의 개념으로 간주하여 의미가 있는 제목, 내용에는 적합하나 주로 의미 없는 문자열로 구성된 작성자 검색에는 부적합하다 생각했습니다. 문제 진단 및 원인 분석따라서 유니크 인덱스를 이용하여 작성자 검색을 하게 되는데 %LIKE% 검색 시 유니크 인덱스를 사용할 수 없다는 문제가 있었습니다. 이로 인해 인덱스를 포기하고 %LIKE%로 정확성을 확보할 것인지, 혹은 인덱스를 활용하여 속도를 확보할 것인지 고민했습니다.다음과 같은 분석을 통해 해결책을 모색했습니다.짧은 검색어일수록 중간 단어 검색(%LIKE%)을 선호하는 경향이 있습니다.. 2025. 11. 25. 배치 기반 친구 추천 API의 실시간 전환 목차1. 기존 방식 및 문제점 1.1 기존 친구 추천 API 방식 1.2 기존 방식의 문제점 1.3 실시간 조회를 구축하기 위해 반드시 해결해야 할 것2. 결과 요약 2.1 원인 2.2 성능 지표 2.3 성과 요약3. 설계 목표와 고민 3.1 설계 목표 3.2 고민과 대안 4. 실시간 친구 추천 API 아키텍처5. 테스트 5.1 테스트 결과 5.2 친구가 많고 많은 추천친구를 보여줘야하는 상황의 테스트 결과 5.3 레디스 장애시 DB조회 테스트 결과6. 정합성 1. 기존 방식 및 문제점1.1 기존 친구 추천 API 방식아래는 기존 친구 추천 API의 아키텍처입니다.1시간마다 전체 유저를 대상으로 기준에 따라 친구 점수를 계산한 뒤, 상위 10.. 2025. 11. 23. 분산락에서 비동기 스레드풀 실행 거부 예외 식별과 해결 서론캐시 스탬피드를 발견하고 많은 스레드가 DB를 동시 접근 하는 것을 방지하기 위해 다양한 방식의 해결법을 적용하던 과정에서 분산락을 적용했을 때 게시글을 조회하지 못하는 오류가 발생했습니다.요약캐시평균 Throughput캐시 갱신 시 레디스 CPU 사용량캐시 갱신 시 실행거부 오류분산락 개선 전2350.06%RejectedExecutionExeption 466건분산락 개선 후2600.03%오류 0건 증상 요약1. 캐시 스탬피드 해결2. 커넥션 획득 시간 50배 감소3. 레디스 메모리 사용량 1.8배 감소4. TTL 만료시 비동기 스레드로 캐시 갱신을 할 때 RejectedExecutionExeption 발생 결론 요약1. 비동기 스레드에서 waitTime을 설정해 스레드 풀 병목이 발생했다. wai.. 2025. 11. 19. Redis TTL 만료 시점 병목 해소: Cache Stampede 방어 전략 측정 및 분석 스탬피드 현상의 측정과 방어 이전에 캐시 다이어그램을 보여드리겠습니다.아래 사진은 제 기존 캐시 설계입니다. 빠른 복구를 위해 Tier2로 설계했습니다.아래 사진은 캐시 전략입니다.아래 사진은 전체 캐시 흐름도 입니다. 캐시 스탬피드의 방법들에 대해 측정했습니다.10분간 부하테스트를 실시했습니다.글 상세 조회 30%주간 인기글 상세 조회 14%레전드 인기글 상세 조회 10%실시간 인기글 목록 조회 20%주간 인기글 목록 조회 14%레전드 인기글 목록 조회 12%로 구성했습니다.테스트 시작후 8분까지 선형적으로 램프업 해나가며 마지막 2분은 최대 부하를 유지했습니다.최대 부하는 사용자 300명이 0.4초에 한 번씩 요청을 보냅니다.커넥션 풀은 30으로 고정하였습니다.캐시최대 TPS평균 Latancy레디스.. 2025. 11. 3. 이전 1 2 3 다음