전체 글 90

데이터 분할로 친구 관계의 연쇄 작용 제어: 실시간 친구 추천 시스템 구축기

1. 기존 방식 및 문제점1-1. 기존 친구 추천 시스템 개요기존의 친구 추천시스템은 조회용 추천친구 테이블을 별개로 두고 1시간 마다 배치로 친구 테이블에서 추천친구를 계산하여 추천친구 테이블에 저장하였습니다. 아래 표를 기준으로 회원마다 점수를 측정하여 상위 10명을 추천 했습니다. 2촌3촌글 추천댓글 추천댓글 작성공통 2촌 추가 점수 공통 3촌 추가 점수 점수50점20점0.5점0.5점0.5점2점0.5점 점수 제한최대 50점최대 20점최대 10점최대 20점 최대 5점1-2. 기존 방식의 문제점문제점1. 실시간성 불가.2. 추천 친구 테이블을 1시간마다 제거하는 비용.3. 배치를 최적화 시키기 위한 복잡한 조건.4. 만든사람도 알아보기 힘든 스파게티 코드.1. 실시간의 부재가장 심각한건 실시간의 부재입..

Redis를 활용한 게시판 캐싱 전략

커뮤니티 게시판의 인기글 목록 조회 시 다음과 같은 비효율적인 부분이 있었습니다. 1. 반복적인 DB 조회 부담 : 자주 조회되는 실시간/주간/레전드 인기글 목록을 DB에서 조회하여 응답 시간이 증가했습니다. 2. 실시간 인기도 반영의 어려움: RDB만으로 글의 인기도를 실시간으로 반영하려면 요청마다 복잡한 인기글 재선정 로직이 필요했습니다. 따라서 자주 조회되는 요청은 캐싱을 하여 DB의 부담을 낮추고자 했습니다. 캐싱 요구 사항 1. TTL이 만료되어도 집계 쿼리가 재실행되면 안됩니다. 2. 실시간 인기글은 사용자 활동(조회, 댓글, 추천)에 따라 동적으로 변화합니다. 3. 글이 삭제되거나 수정되었을 때 사용자는 이전 버전의 글을 보면 안됩니다. 4. 자주 조회되고 변하지 않는 인기 게시글 목록은 통..

개발 2025.11.19

Redis 캐시 스탬피드 방어: 분산락의 성능 하락 원인 식별과 REP 전략 도입

글 수정 예정이 글의 원인과 결과 및 분석은 잘못되었습니다 조만간 수정할 예정입니다.서론https://jaeiktech.tistory.com/79 의 3번 분산락 부분에서 나타난 성능저하를 분석하는 글 입니다. 캐시 스탬피드를 발견하고 많은 스레드가 DB를 동시 접근 하는 것을 방지하기 위해 다양한 방식의 해결법을 적용하던 과정에서 분산락을 적용했을 때 심각한 성능저하가 나타나는 것을 발견했습니다. 락 대기와 동시성으로 인한 어느정도의 TPS와 Lantency의 하락은 예상했으나 너무 큰 폭으로 감소하였습니다.요약캐시최대 TPS평균 TPS평균 Latancy레디스 메모리커넥션 획득 시간비고캐시 적용59438468ms4.2MB최대 125ms스탬피드 발생분산락 적용345273322ms2.5MB최대 2.5ms응..

Redis TTL 만료 시점 병목 해소: Cache Stampede 방어 전략 측정 및 분석

스탬피드 현상의 측정과 방어 이전에 캐시 다이어그램을 보여드리겠습니다.아래 사진은 제 기존 캐시 설계입니다. 빠른 복구를 위해 Tier2로 설계했습니다.아래 사진은 캐시 전략입니다.아래 사진은 전체 캐시 흐름도 입니다. 캐시 스탬피드의 방법들에 대해 측정했습니다.10분간 부하테스트를 실시했습니다.글 상세 조회 30%주간 인기글 상세 조회 14%레전드 인기글 상세 조회 10%실시간 인기글 목록 조회 20%주간 인기글 목록 조회 14%레전드 인기글 목록 조회 12%로 구성했습니다.테스트 시작후 8분까지 선형적으로 램프업 해나가며 마지막 2분은 최대 부하를 유지했습니다.최대 부하는 사용자 300명이 0.4초에 한 번씩 요청을 보냅니다.커넥션 풀은 30으로 고정하였습니다.캐시최대 TPS평균 TPS평균 Lata..

Redis를 활용한 게시판 캐싱

커뮤니티 게시판의 인기글 목록 조회 시 다음과 같은 비효율적인 부분이 있었습니다.1. 반복적인 DB 조회 부담 : 자주 조회되는 실시간/주간/레전드 인기글 목록을 DB에서 조회하여 응답 시간이 증가했습니다.2. 실시간 인기도 반영의 어려움: RDB만으로 글의 인기도를 실시간으로 반영하려면 요청마다 복잡한 인기글 재선정 로직이 필요했습니다.따라서 자주 조회되는 요청은 캐싱을 하여 DB의 부담을 낮추고자 했습니다. 캐싱 요구 사항TTL이 만료되어도 집계 쿼리가 재실행되면 안됩니다.실시간 인기글은 사용자 활동(조회, 댓글, 추천)에 따라 동적으로 변화합니다.글이 삭제되거나 수정되었을 때 사용자는 이전 버전의 글을 보면 안됩니다.자주 조회되고 변하지 않는 인기 게시글 목록은 통째로 캐싱하여 반환해야 합니다.캐시..

개발 2025.11.02

멀티 스레드 환경에서 공유 세션으로 발생한 동시성 경합과 커넥션 누수 분석 및 해결

동기에서 비동기 로직으로의 변경제 서비스는 상대방에게 편지를 작성하면 DB에 저장하고 편지주인에게 FCM 푸시 알림을 전송합니다.기존에는 편지를 작성하면 DB에 저장하고 상대방에게 FCM 푸시 알림까지 동기적으로 하였습니다.응답속도 개선을 위해 FCM 푸시 알림 로직을 별도의 스레드 풀을 사용하는 비동기 이벤트 구조로 변경했습니다. 문제 발생그 이후 동일한 테스트를 시행했을 때 ConcurrentModificationException이라는 다량의 예외와 동시에 DB 커넥션 누수가 탐지되었습니다. 커넥션 생성주기가 짧아서 그런 것일 까봐 커넥션 생명주기와 RDS의 타임아웃 설정을 조정해도 같은 문제가 발생했습니다. 문제의 코드// 1. 메인 스레드 편지 보내기 로직public void 편지 보내기(Stri..

소셜 로그인/회원가입 반환 프로토콜 재설계

문제 발견시작은 단순했다. “기존 회원과 신규 회원의 로그인 반환값을 어떻게 구분할까?”당시 구조에서는 MemberDetail이라는 DTO가 모든 책임을 떠안고 있었다. 로그인 과정에서 Member 도메인이 MemberDetail을 생성해 Auth 도메인으로 넘기고, Auth는 그 DTO를 기반으로 JWT와 쿠키를 발급했다.하지만 곧 두 가지 문제가 눈에 들어왔다.첫째, 기존 회원과 신규 회원의 흐름이 모두 하나의 DTO에 묶여 있어 분기 로직이 어색했다. 기존 회원의 경우 실제 Member 엔티티가 필요한데, DTO로 변환되는 순간 더티 체킹이나 추가 갱신이 불가능했다. 반대로 신규 회원은 DTO만 넘겨둔 채 Redis에 임시 저장을 맡기다 보니 “회원가입을 완료하지 않은 사용자”의 상태를 추적하기가 ..

로그아웃 로직 Optional과 예외 처리 개선기

문제 : 과도한 예외 처리와 복잡한 흐름처음 작성했던 코드(1번 코드)는 로그아웃 프로세스를 하나의 큰 try-catch 블록 안에 넣고 있었습니다.// 1번 코드함수: 로그아웃을 시작한다 시도해본다: 소셜 계정에서 로그아웃을 요청한다 (이 과정에 사용자 인증 정보 확인도 포함) 로그아웃 완료 이벤트를 알린다 사용자 인증 정보를 모두 지운다 로그아웃용 쿠키를 반환한다 만약 오류가 발생하면: 로그아웃 실패 오류를 발생시킨다이 방식은 얼핏 보면 안전해 보이지만, 다음과 같은 두 가지 큰 문제를 가지고 있었습니다.단일 책임 원칙 (SRP) 위반: 소셜 로그아웃 처리 메서드 안에서 사용자 정보 확인과 실제 로그아웃 요청이라는 두 가지 책임이 섞여 있었습니다. 이 때문에 코드를 이해..

개발 2025.09.23

비밀로그 개발 예정 기능

향후 추가기능탑재를 위한 버전2가 완성되어간다버전2라고하지만 준비한 기간에 비해서는 사용자가 느끼는 기능추가가많지않다버전2는 향후 추가기능 탑재를 위한 서버내부리팩토링이 주 목적이다사용자가 느끼기에는 디자인 친화적 변화 오류개선 정도의 개선만있다 (디자인 변화가 사용자가 느끼기에는 많이 변하게 느껴지려나..?)아키텍처변경이외의 기능은 보안강화 로깅강화 관리자기능강화가 주된 변화다향후 추가할 기능을 적어보려한다메인은 채팅기능추가다 (단체채팅,익명채팅,닉네임채팅)친구기능추가도 필요하다친구추천기능도 필요하다 (흔히말하는 2촌, 3촌등등 유니온파인드를 활용하는게 떠올랐지만 아무리 빨라도 데이터를 가져와서 지지고볶는건 아닌거같다 nosql쪽에 해답이 있으려나? 구현은 더 고민해야한다)실시간 인기 롤링페이퍼도 만들..

개발 2025.09.14

헥사고날 아키텍처에서 신고(Report) 엔티티의 도메인 위치 딜레마

1. 상황 비밀로그(BimilLog) 프로젝트를 헥사고날 아키텍처로 설계하면서 신고 기능을 구현하게 되었다. 현재 시스템은 7개의 주요 도메인(admin, auth, comment, notification, paper, post, user, common)으로 구성되어 있으며, 각 도메인은 명확한 책임과 경계를 가지고 있다. 신고 기능의 요구사항은 다음과 같았다: - 글 신고: 부적절한 게시글 신고 - 댓글 신고: 부적절한 댓글 신고 - 건의사항: 사용자가 시스템에 대한 건의사항 제출 - 신고 관리: 관리자가 신고 내역을 조회하고 처리 자연스럽게 각 기능은 관련 도메인에 배치되었다: - 신고 하기→ user 도메인의 in 어댑터 (UserCommandController) - 신고 조회 →..