목록 전체 글 (277)

소개 DB에 데이터가 쌓였을 때 조회 성능과 개선 포인트를 확인했다. DB 쿼리 빈도를 줄여 조회 성능을 개선하는 캐싱이나 DB 부하 분산은 다루지 않는다. 대신 데이터를 만드는 방법부터 DB 엔진에 넣는 데 걸리는 시간, 인덱스나 쿼리 수정 고민 과정을 적어볼 생각이다. 튜닝 키워드는 아래와 같다. 1. 더미 데이터를 추가하고 쿼리 조회 성능을 확인한다.2. 인덱스/커버링 인덱스를 적용한다.3. 실행 계획으로 인덱스 튜닝 결과를 확인한다.4. OFFSET 기반 페이지네이션의 문제를 확인하고 개선한다. 천만 개 더미데이터 삽입테스트 환경으로 1000명 유저, 각 유저는 20개의 앨범을 소유, 각 앨범에는 500개의 사진 정보를 가정한다. 총 천개의 Member 데이터, 2만 개의 Album 데이터, 천만..

두 번의 갱신 분실 문제 발생유저가 파일을 업로드하면 사용 가능 공간을 확인하고 현재 사용 중인 공간을 업데이트한다. 업로드 동시 요청이 발생하는 경우, 마지막에 수행되는 커밋의 결과만 반영되어 의도하지 않은 값이 저장된다. 이렇게 여러 트랜잭션에서 동일한 데이터를 동시에 수정하려할 때, 마지막으로 수행한 수정만 반영되는 경우를 두 번의 갱신 분실 문제라고 한다.# 두개의 스레드에서, 동시에 5MB 파일을 업로드할 때Thread 1 - 현재 스토리지 사용량 조회 0MBThread 2 - 현재 스토리지 사용량 조회 0MBThread 1 - 스토리지 사용량 기록 5MBThread 2 - 스토리지 사용량 기록 5MB 낙관적 락낙관적 락은 조회와 수정에 버전을 함께 확인하여 충돌 여부를 파악한다. 엔티티 버전을..

Mysql InnoDB 의 RepeatableRead Mysql 의 기본 Transaction isolate 수준은 RepeatableRead 이다. RepeatableRead 는 트랜잭션이 시작된 시점 이후로 여러 번 Select Row 를 확인해도 동일한 값을 갖는다는 것이다. Mysql 은 SnapShot을 사용해서 이를 보장한다. 트랜잭션마다 별도의 스냅샷을 기록하여 다른 트랜잭션이 값을 변경하고 Commit 해도 이 스냅샷을 이용해서 동일한 값을 읽게 되는 것이다. Phantom read 문제Repeatable Read 는 데이터의 추가, 삭제의 변경은 막지 못해 Phantom read 문제가 발생한다. 한 트랜잭션 내에서 전과 다른 조회 결과 row 수를 조회하게 된다는 것이다. InnoD..

이전 글 - 리버스 프록시 개념과 Nginx, ELB 로 로드밸런싱 실습리버스 프록시 개념이 처음이거나 Nginx config 를 처음 다뤄본다면 이전 글을 먼저 보고 오는 것을 추천한다. 해당 글에선 리버스 프록시와 로드 밸런싱 개념, 다중 WAS에서 Sesstion 관리, Nginx 와 AWS ALB로 로드밸런싱 실습을 다뤘다.Rate limit, Ip white list프로젝트를 배포할 때마다 무서운 것들이 있다. 악의적인 과도한 요청, 접속해선 안될 곳에 접근이 가능, 암호화되지 않은 데이터... 특히 가장 먼저 서버를 보여주는 주변 사람들이 웹 개발자가 많아서 더 무섭다. 이 사람들은 일반 사용자랑 달리 아주 자연스럽게 서버를 테스트할 테니 말이다. 그리고 실제로 꼼꼼하게 방어하지 않았다가 악의..

GC와 Stop the world JVM의 가비지컬렉터는 힙 영역의 메모리에서 더 이상 사용되지 않는 자원을 정리하는 역할을 한다. 이때 사용되지 않는다란 다른 지역 변수, static 변수, 파라미터, JNI의 객체, 다른 힙 영역의 객체 등에서 더 이상 참조되지 않는 것을 말한다. 아래 그림에서 빨간색으로 표시된 Unreachable objects는 GC의 대상이 된다. 이때 자원을 정리하는 과정에서 새로운 객체가 할당되거나 객체 간 연결이 생길 경우를 방지하기 위해, GC를 위한 스레드를 제외한 모든 스레드의 작업이 중단된다. 이런 GC를 위한 애플리케이션 전체 중단 시간을 Stop the world라고 한다. ( 보다 자세한 STW가 필요한 이유 ) 두가지 GC와 처리 영역들 Stop the wo..

0. AS IS 기존에는 이 메인 / 백업 스토리지 업로드를 동기로 처리했다. 400KB의 이미지를 업로드할 때 main 33ms, backup 1680ms 정도가 필요했고, 사용자 응답은 이 둘을 더한 값 + ⍺ 가 될 것이다. 이미지 업로드 시에 각 스토리지 업로드를 비동기로 처리하되 모든 업로드가 정상일 경우에만 사용자에게 정상으로 응답하고자 한다. 그리고 동시에 비동기식 업로드 과정에서 생길 수 있는 더미 파일을 사용자 흐름에 포함하지 않고 처리하고자 한다. 이 글에선 위 요구 사항을 만족하기 위한 작업 과정을 소개한다. 목차는 다음과 같다. 1. 단순 비동기 처리 2. Future로 비동기 / 블록킹 방식으로 처리하는 경우, 그 문제점 3. CompletableFuture으로 쉽게 구현하는 다양..

Mysql DB Multi source replication지난 글에선 데이터 백업, 쿼리 분산을 위한 Mysql replication 을 소개했다. DB 서버 하나에 데이터를 넣어두는 것이 위험하다고 생각해 복제용 DB를 만들어 데이터를 백업했고, 이를 읽기 전용 서버로 생각하여 백업과 부하 분산 두 가지를 잡을 수 있었다. 이번엔 새로운 니즈가 생겼다. 지금 프로젝트 배포를 개인 홈 서버에 하고 있는데 물리적인 문제가 생겨 데이터가 날아가면 어쩌지 하는 생각이다. (혹시 불이라도 나거나 SSD가 고장나면 어째..) 원하는 구조는 아래와 같다. Api 서버별로 다른 DB 서버로부터 Cloud server 에 하나의 Mysql DB 를 띄워 단순 복제하는 것이다. 여러 소스로부터 복제한다고 해서 이를 M..
Mysql db replication DB를 백업하기 위해서 replication 을 사용한다. 백업을 위함도 클 것이고, 쿼리 부하 분산, 지역화의 이점도 얻을 수 있을 것이다. 이 글에선 아래 네가지 키워드를 다룬다. - Mysql이 제공하는 Replication 방식과 각 장단점- 비동기 복제의 정합성 문제- Spring boot에서 읽기와 쓰기 Datasource 분기하기 복제 종류 Mysql 의 복제 방식은 '동기', '비동기', '반동기'가 대표적이다. 동기 방식은 한 노드에 요청된 쿼리를 트랜잭션 내에서 다른 노드들에 전달하고 모든 노드들이 동기화되면 트랜잭션의 결과를 반환한다. 마스터(또는 첫 요청을 받은 노드)가 다른 노드들에 쿼리를 전달하는 식으로 진행된다. 모든 노드에서 동일한 요청..