Project 해축갤(27)
-
손흥민 결승골 후 데이터 폭증: 해축갤에서의 3가지 인덱스 전략
배경 최근 이런 시나리오를 생각해봤습니다. 월드컵 결승에서 손흥민 선수의 골로 인해 극적인 승리를 한다면 해축갤에 무슨 일이 일어날까? (제발 이런 일이 일어났으면) 생각만 해도 달달하다. 이런 경우 아마 해축갤에 흥민찬양에 대한 주제로 글이 미어터질 것입니다. 이렇게 생성된 글들이 쌓이면, 이는 결국 대규모 데이터라고 불릴 만큼 늘어날 것입니다. 그리고 저는 늘어난 글의 갯수를 대략 1억개로 잡아봤습니다. 그래서 최근 데이터를 200만 개에서 1억 개로 늘리고 난 뒤 기존 API의 성능이 얼마나 나오는지 궁금해 쿼리를 한번 테스트해 봤습니다. 정신 나갔다,,, 쿼리 응답시간 4분 20초…? 해축갤은 제 자식과 같은 프로젝트이지만, 저라도 이 서비스는 사용하지 않을 거 같습니다 ㅠ 상황 현재 해축갤의 E..
2024.03.26 -
MySQL 인덱스 크기와 디스크 I/O 최적화: 데이터베이스 성능 향상 가이드
배경 해축갤 프로젝트를 하며 데이터가 200만개에서 1억개로 늘어났을 때 게시물 조회 성능이 급격히 안 좋아져 쿼리 개선, title, content 기준 인덱스를 이것저것 넣어보며 실험을 하고 있었습니다. 인덱스중 title, content 2개를 가지고 B-Tree 인덱스를 생성하려 했다가 문제가 발생했습니다. 구체적인 상황 (like DB, 코드 구조) 해축갤의 게시글 테이블의 구조는 다음과 같습니다. 주의해서 봐야 하는 부분은 content 가 varchar(1000) 라는 겁니다. 제가 사용하는 MySQL 버전은 8.0.36 이고 입력한 명령어는 다음과 같습니다. CREATE INDEX idx_title_content ON post (title(100), content(100)); 문제 위 쿼리..
2024.03.25 -
실시간 MySQL 데이터 복구: Master-Slave 구성과 MHA로 완성하는 고가용성 백업 전략
예전에 1. DB가 부러졌고 2. 부러진지도 몰랐고 3. 알고난 이후에는 복구하려고 갖은 방법을 써봤지만 결국에는 복구를 하지 못하고 지우고 새롭게 설치를 했었습니다. 백업 및 복구 실패 글 링크 : https://xpmxf4.tistory.com/93 MySQL 데이터베이스 복구 실패: 실험에서 배운 교훈과 데이터베이스 관리 전략 ? DB 가 죽어버렸다. 껐다 켜면 되겠지라는 생각으로 다음 명령어를 쳤는데 brew services restart mysql 여전히 안된다. 원인 분석 그래서 로그를 확인하기 위해 ‘/usr/local/mysql/data/mysqld.local.err’ 을 까 xpmxf4.tistory.com 그래서 미리미리 백업을 해야한다는 것과, 복구 시스템을 갖춰야 함을 뼈저리게 느껴..
2024.03.04 -
카타르 아시안컵 16강날 해축갤 트래픽 분석 : 인기 게시물의 파워
예전에 쿼리 튜닝을 한 상황의 가정은 다음과 같았습니다. 손흥민이 월드컵에서 골을 넣으면 해축갤에 미친 듯한 드립(게시물)이 올라오고 퍼갈 것이다. 이때 '%흥민%' 이라는 키워드로 검색이 많이 일어날 것이다. 그래서 게시물에 약 1억 건의 데이터를 넣고 느려진 게시물 조회 쿼리를 개선을 했었습니다. (4분20초 -> 0.0019초) 2024.01.29 - [Project 해축갤/데이터베이스] - 1억 데이터 쿼리 최적화: 풀텍스트 인덱스의 한계와 LIKE 절의 귀환 1억 데이터 쿼리 최적화: 풀텍스트 인덱스의 한계와 LIKE 절의 귀환 배경 최근 데이터를 200만 개에서 1억 개로 늘리고 난 뒤 기존 API의 성능이 얼마나 나오는지 궁금해 쿼리를 한번 테스트해 봤습니다. 정신 나갔다,,, 쿼리 응답시간..
2024.02.01 -
Pure Java 프로젝트 의존성 포함법 : Shadow Plugin
1. 문제의 시작: 해축갤 인기 게시물 트래픽 추적 중 에러 해외축구갤러리의 인기 게시물 트래픽을 추적하기 위해 Java 프로그램을 개발하고 Gradle 빌드 시스템을 사용하여 빌드한 후 실행했습니다. 그러나 "java.lang.NoClassDefFoundError: org/jsoup/Jsoup"라는 Gradle 빌드 관련 에러가 발생했습니다. 이는 Spring Boot 프로젝트에서는 경험하지 못한 문제였습니다. Spring Boot 는 jar 파일 빌드시 기본적으로 모든 dependency를 포함하기 때문입니다. 2. Gradle의 기본 동작 이해하기 이 문제를 해결하기 위해 Gradle 커뮤니티의 토론을 참고했습니다. First of all, the default jar that Gradle prod..
2024.01.29 -
MySQL 데이터베이스 복구 실패: 실험에서 배운 교훈과 데이터베이스 관리 전략
? DB 가 죽어버렸다. 껐다 켜면 되겠지라는 생각으로 다음 명령어를 쳤는데 brew services restart mysql 여전히 안된다. 원인 분석 그래서 로그를 확인하기 위해 ‘/usr/local/mysql/data/mysqld.local.err’ 을 까보기로 마음을 먹었다. 근데 파일이 자그마치 12MB 나 되는 파일을 일일이 읽는다는 건 비효율적이 판단했다. ERROR 관련 키워드(ex. ‘ERROR’, “Assertion Failure’, ‘crash’) 만 따로 추출해 분석해 보기로 했다. # 로그 파일에서 특정 키워드를 포함하는 부분을 찾아냅니다. keywords = ["ERROR", "Assertion failure", "crash"] matching_lines = [] for line..
2024.01.23 -
Gradle에서 조건부 Jacoco 적용하기: CI/CD 파이프라인 최적화
최근에 우테크 블로그를 읽고, 코드의 품질을 관리하기 위해 Jacoco라는 도구를 도입했습니다. Jacoco는 코드 커버리지를 측정하는 도구로, 제가 작성한 테스트가 얼마나 코드를 잘 커버하는지 알려줍니다. 이를 통해 놓친 테스트 케이스를 찾아내고, 더 견고한 코드를 작성할 수 있었죠. 하지만, 실제 업무 중 급박한 상황을 겪으며 '긴급할 때는 코드 커버리지를 잠시 무시하고 버그부터 고쳐야 한다'는 생각이 들었습니다. 그래서 Jacoco 검사를 상황에 따라 선택적으로 실행하도록 설정하는 방법을 모색했습니다. Jacoco 설정 과정과 브랜치 변경 1. 첫 시도 - 우테크 블로그의 기본 설정: test { finalizedBy 'jacocoTestReport' } 설명: 이 설정은 Gradle의 test 태..
2024.01.10 -
JaCoCo와 애노테이션: 자바 테스트 커버리지의 한계 이해하기
JaCoCo 란? JaCoCo는 Java 코드의 커버리지를 체크하는 라이브러리입니다. 여기서 코드의 커버리지란 내 테스트 코드가 내 코드의 몇 퍼센트를 보증하냐!라고 생각하시면 편합니다. 테스트코드를 돌리고 그 커버리지 결과를 눈으로 보기 좋도록 html이나 xml, csv 같은 리포트로 생성합니다. 그리고 테스트 결과가 내가 설정한 커버리지 기준을 만족하는지 확인하는 기능도 있습니다. 최근 이러한 JaCoCo를 활용해 코드의 품질을 높이려는 노력을 하던 와중에 특이한 점을 찾았습니다. 특이점 JaCoCo 를 통해 테스트의 커버리지를 측정하던 와중 테스트 코드를 작성했는데도 커버리지가 카운팅이 되지 않는 부분을 발견했습니다. 다음은 문제의 코드입니다. @Test @DisplayName("updatePo..
2024.01.08 -
JUnit5 테스트 메서드는 왜 public 이면 안될까?
최근 코드 품질을 올리고 싶어 IDE에 SonarLint을 설치했더니 다음과 같은 경고를 받게 됐다. 요는 테스트 메서드에서 public 접근 제어자를 없애라라는 경고이다. 필자가 아는 지식은 JUnit 이 실행시에 테스트 메서드를 Reflection API로 뜨기 위해서 public 접근 제어자가 필수라고 알고 있었다. JUnit 5 제작자 왈 public 일 필요는 없지만, private 이면 안된다! 일반적으로 public 제어자는 기술적인 모종의 이유가 아닌 이상 쓰지 말아라 [출처] : https://junit.org/junit5/docs/current/user-guide/#writing-tests-classes-and-methods 요약하자면 우리 JUnit 5 팀은 "Less is more"..
2024.01.08 -
EC2 메모리 문제 해결과 Elastic IP 적용: 인스턴스 유형 변경 후 IP 문제 극복기
상황 어제 EC2에 Spring Boot와 MySQL을 실행시키려 하니 다음과 같은 에러가 나왔습니다. 이유는 OOM(Out Of Memery) Killer 가 mysql.service를 죽였다는 것. 사실 이럴만도 한 게 기존에 쓰던 EC2의 스펙이 t4g.nano였습니다. 이 EC2 인스턴스의 스펙은 대략 다음과 같습니다 AWS Gravition Processor(CPU) 2 개와 메모리 500MB짜리입니다. 여기서 주요 문제는 메모리 용량입니다. 현재 지금 돌아가고 있는 EC2의 RSS(실제 사용하는 물리 메모리양)를 보면 mysql 은 396MB, Spring Boot는 222MB 인걸 확인할 수 있습니다. (상황 종료 후의 spring boot, mysql을 확인한 것입니다.) 심지어 mysql..
2023.12.20