전체 글121 MySQL Replication 적용하기 MySQL Replication 데이터베이스를 사용하고 운영할 때 가장 중요한 두 가지 요소는 확장성(Scalability)과 가용성(Availability)이다. 이 두 가지 요소를 위해 가장 일반적으로 사용되는 기술인 MySQL 복제는 소스 서버의 데이터를 하나 이상의 레플리카 서버로 복제하여 읽기 작업을 분산시켜 성능을 향상시키는 것을 말한다. 원본 데이터를 가진 서버를 소스(Source) 서버, 복제된 데이터를 가지는 서버를 레플리카(Replica) 서버라고 부른다. 소스 서버에서 데이터 및 스키마에 대한 변경이 최초로 발생하며, 레플리카 서버에서는 이러한 변경 내역을 소스 서버로부터 전달받아 자신이 가지고 있는 데이터에 반영함으로써 소스 서버에 저장된 데이터와 동기화시킨다. 복제 장점 복제를 통.. 2024. 1. 15. CAP 이론으로 보는 RDBMS vs NoSQL RDBMS vs NoSQL 이 글에서는 RDB와 NoSQL에 대해 알아보기 전에 CAP 이론을 살펴보고, CAP 이론을 통해 RDB와 NoSQL에서는 어떤 속성을 희생했는지에 대해서 살펴보자. CAP 이론 RDBMS와 NoSQL를 살펴볼 때 CAP이론을 살펴보면 좋다. CAP 이론은 분산 시스템에서 위 3가지 속성인 일관성(Consistency), 가용성(Availability), 분할 내성(Partition Tolerance) 중 두 가지만 동시에 보장할 수 있다는 이론이다. 즉, 완벽한 일관성, 가용성, 분할 허용성을 모두 동시에 보장하는 것은 불가능하며 다음 3가지 속성의 특징을 통해 어떠한 상황에서 속성을 희생해야 하는지에 대한 고려를 제공해준다. 하지만 완벽한 CP, AP 시스템은 사용할 수 없.. 2024. 1. 9. 분산 락 사용 시 상위 트랜잭션이 있으면 안되는 이유 분산 락 사용 시 상위 트랜잭션이 있으면 안되는 이유 주문 기능 중 재고 차감을 데이터 정합성을 위해 비관적 락으로 먼저 구현하고, 다음으로 Redisson을 사용하여 분산 락으로 구현하려고 했지만 주문 트랜잭션에서 상위 트랜잭션이 있는 경우에는 적용하지 못해 그 이유에 대해 작성해보고자 한다. Redisson을 사용한 분산 락 Redisson은 pub/sub 기반으로 Lock 구현을 제공한다. 채널을 하나 만들고 Lock을 점유중인 스레드가 Lock을 획득하려고 하는 스레드들에게 해제를 알려주고 안내를 받은 스레드가 Lock 획득 시도하는 방식으로 스핀락을 통해 계속해서 락을 획득할 수 있는지 요청해야 하는 Lettuce의 경우보다 부하를 덜 줄 수 있다. boolean tryLock(long wait.. 2024. 1. 7. 데이터 타입 문자열(CHAR와 VARCHAR) 문자열 컬럼을 사용할 는 우선 CHAR와 VARCHAR 타입 중 어떤 타입을 사용할지 결정해야 한다. 우선 저장 공간과 비교 방식의 관점에서 CHAR와 VARCHAR를 비교해보고, MySQL 내부적으로 어떤 차이가 있는지도 한 번 살펴보자. 저장 공간 우선 CHAR와 VARCHAR의 공통점은 문자열을 저장할 수 있는 데이터 타입이라는 점이고, 가장 큰 차이는 고정 길이냐 가변 길이냐이다. CHAR 타입은 이미 저장 공간의 크기가 고정적이다. 실제 저장된 값의 유효 크기가 얼마인지 별도로 저장할 필요가 없으므로 추가로 공간이 필요하지 않다. VARCHAR 타입은 최대로 저장할 수 있는 값의 길이는 제한돼 있지만, 그 이하 크기의 값이 저장되면 그만큼 저장 공간이 줄어든다... 2024. 1. 1. 쿼리 성능과 최적화 (2/2) INSERT 일반적으로 온라인 트랜잭션 서비스(OLTP)에서 INSERT 문장은 대부분 1건 또는 소량의 레코드를 INSERT하는 형태이므로 그다지 성능에 대해서 고려할 부분이 많지 않다. 오히려 많은 INSERT 문장이 동시에 실행되는 경우 INSERT 문장 자체보다는 테이블의 구조가 성능에 더 큰 영향을 미친다. 하지만 동시에 INSERT 성능과 SELECT 성능을 빠르게 만들 수 있는 구조는 없기 때문에 어느 정도 타협하면서 테이블 구조를 설계해야 한다. 고급 옵션 SELECT 문장만큼 다양하지는 않지만 INSERT 문장에도 사용할 수 있는 유용한 기능이 있다. 대표적으로 INSERT INGORE 옵션과 INSERT ... ON DUPLICATE KEY UPDATE 옵션을 살펴보자. 두 옵션 모두 .. 2023. 12. 28. 페이징 성능 개선: offset vs no offset vs covering index 페이징 성능 개선: offset vs no offset vs covering index 웹 서비스에서 페이징은 아주 흔하게 사용되는 기능이다. 일반적으로 페이징은 구현한다면 LIMIT ... OFFSET ...; 와 같은 패턴으로 OFFSET을 사용하는데 이는 점차 데이터가 많아짐에 따라 수십초 ~ 수분까지 조회가 느려질 수도 있다. 따라서 No offset과 Covering index를 통해서 페이징 기능을 개선하는 방법에 대해서 살펴보자. product 테이블에 대략 1,572만 건 상품 데이터가 있다. OFFSET LIMIT 쿼리는 결과에서 지정된 순서에 위치한 레코드만 가져오고자 할 때 사용된다. 위 쿼리는 다음과 같은 순서로 실행된다. ORDER BY id DESC: 일반적으로 최신에서 과거순으.. 2023. 12. 25. synchronized vs Pessimistic Lock vs Distributed Lock synchronized vs Pessimistic Lock vs Distributed Lock DB의 무결성을 보장하기 위해서는 다양한 방법이 있다. 물론 synchronized는 적합한 방법은 아니지만 왜 적합하지 않은지에 대해 살펴보고, 그 뒤 비관적 락(Pessimistic Lock)과 분산락(Distributed Lock)을 통해 성능 비교를 해보자. 재고 차감 로직을 통한 DB 부정합 문제 살펴보기 위 ProductService는 주문 관련 비즈니스 로직 중 하나로 "상품 조회 -> 상품의 재고 차감 가능 여부 확인 -> 재고 차감"의 순서로 이루어지는 로직이다. 해당 비즈니스 로직을 통해서 어떻게 DB 부정합 문제가 발생하게 되는지 테스트 코드를 작성해보자. 위 테스트 코드는 한 번에 100개.. 2023. 12. 21. Nginx와 WAS의 로깅 식별자(request_id) 공유하기 Nginx와 WAS의 로깅 식별자(request_id) 공유하기 현재 프로젝트의 서비스 환경은 위 그림과 같다. WAS만 사용하는 것이 아니라 Nginx와 같은 Web Server를 앞단에 두고 사용하고 있다. 따라서 Nginx 로그와 WAS 로그를 함께 봐야하는 경우가 많은데, 이때 Nginx와 WAS가 동일한 request_id를 공유하면 로그 파악이 매우 용이해진다. Nginx 설정 Nginx에서는 제공하는 변수 중 하나로 $request_id가 있다. 이 변수는 각 HTTP 요청에 대해 고유한 식별자를 생성하여 주로 로깅이나 디버깅 목적으로 사용된다. 이 변수는 ngx_http_core_module 모듈에서 제공되며 32개의 16진수 문자열로 각 HTTP 요청이 도착하면 자동으로 할당된다. Log.. 2023. 12. 17. Blue/Green 방식으로 서비스 중단없이 배포하기 Blue/Green 방식으로 서비스 중단없이 배포하기 어플리케이션을 배포하는데 있어 Rolling 배포, Blue/Green 배포, 그리고 Canary 배포와 같은 다양한 배포 전략들이 있다. 각 전략의 특징과 장담점을 살펴보고 프로젝트에 어떤 전략을 선택할지 고민해보려고 한다. Rolling 배포 롤링 배포는 각 서버를 한 개씩 새로운 버전으로 (점진적) 배포하는 방법을 말한다. 즉, 위 그림처럼 기존 버전에서 새 버전으로 서비스를 전환하는 과정을 순차적으로 진행한다. 서비스 중인 인스턴스 하나를 로드밸런서에 라우팅하지 않도록 한 뒤 새 버전을 적용하여 다시 라우팅하는 방식으로 구성된 자원을 그대로 유지한 채로 무중단 배포가 가능하므로 관리가 편하다는 장점이 있지만 배포가 진행되는 동안 구버전과 신버전.. 2023. 12. 17. 이전 1 2 3 4 5 ··· 14 다음