개요 PuppyNote 서비스의 게시물 좋아요 기능을 구현하면서 DB 부하 최소화와 실시간 반영이라는 두 가지 요구사항을 동시에 만족시켜야 했다. 단순히 좋아요를 누를 때마다 DB에 바로 쓰는 방식은 트래픽이 몰릴 때 DB 부하가 급격히 증가한다. 이를 해결하기 위해 Redis Write-Behind Cache 패턴을 적용했다. 문제 정의 ...
개요 이전 포스트에서 해시태그 검색 성능 비교를 통해 Elasticsearch 도입을 결정했다. 이번에는 MySQL을 원본 데이터 저장소로 유지하면서 Elasticsearch와 자동으로 동기화하는 파이프라인을 Logstash로 구축한 과정을 정리한다. 아키텍처 [Spring Boot 앱] │ ▼ MySQL (post...
개요 PuppyNote 서비스의 게시물 검색 기능을 개선하면서 MySQL과 Elasticsearch 중 어느 쪽이 더 적합한지 판단하기 위해 성능 벤치마크를 진행했다. 100만 건의 게시물 데이터를 기준으로 해시태그 정확 검색 시나리오에서 두 기술의 평균 응답 시간을 비교했다. 테스트 환경 및 데이터 구성 항목 ...
개요 ALB나 Auto Scaling Group 없이 EC2 단일 서버에서 Blue/Green 무중단 배포를 구현했습니다. Nginx의 proxy_pass 포트를 배포 시마다 교체하는 방식으로, 추가 인프라 비용 없이 다운타임 제로 배포가 가능합니다. 기존 In-place 배포의 문제 stop.sh → 기존 프로세스 종료 ← 이 순간 ...
개요 PuppyNote 서버를 GitHub에 push하면 자동으로 EC2에 배포되는 CI/CD 파이프라인을 구축했습니다. AWS CodePipeline, CodeBuild, CodeDeploy를 활용했고 서버는 t4g.small(ARM64) EC2 인스턴스를 사용합니다. 전체 아키텍처 GitHub (main push) → CodePipe...
개요 커뮤니티 기능에 해시태그 검색을 구현하면서 Elasticsearch를 도입했습니다. MySQL의 LIKE 검색은 인덱스를 타지 못해 대규모 데이터에서 느리지만, Elasticsearch는 역색인(Inverted Index) 구조로 구글처럼 빠른 검색이 가능합니다. 이 글에서는 Docker Compose로 Elasticsearch와 Kibana...
개요 이전 글에서 Prometheus + Grafana 모니터링 환경을 구축했습니다. 대시보드로 메트릭을 눈으로 확인하는 것만으로는 부족합니다. 서버에 문제가 생겼을 때 담당자가 직접 대시보드를 보고 있지 않으면 이상 징후를 놓칠 수 있기 때문입니다. 이번 글에서는 GC 이후에도 힙 메모리가 80%를 초과하면 Slack으로 알림을 발송하는 Graf...
개요 운영 중인 Spring Boot 서버가 저사양이라 Prometheus + Grafana를 동일 서버에 올리기 어려웠습니다. Prometheus와 Grafana는 합쳐서 400~800MB의 메모리를 사용하기 때문에 별도 모니터링 서버로 분리하는 것이 필수였습니다. 전체 아키텍처 [앱 서버 (저사양)] [모니터링 서...
개요 Apache POI를 사용한 엑셀 다운로드 기능에서 메모리 누수 문제가 발생했습니다. XSSFWorkbook 리소스가 제대로 해제되지 않아 대량의 엑셀 다운로드 요청 시 메모리 부족 문제가 발생할 수 있었습니다. 이 글에서는 AutoCloseable 인터페이스를 활용하여 리소스 관리를 개선한 과정을 상세히 다룹니다. 주요 개선 사항 XS...
대용량 날씨 데이터, 파티셔닝으로 해결하다 문제 상황 회사 프로젝트에서 전국 지역별 날씨 예보 데이터를 저장하는 batch.weather_forecast_latest 테이블을 운영하고 있었다. 시간이 지나면서 데이터가 기하급수적으로 쌓이기 시작했고, 최신 데이터만 필요한 쿼리에서도 테이블 풀스캔이 발생하는 심각한 성능 문제가 생겼다. -- 기존 ...