블로그 이미지

ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • MySQL DB Replication 이론편
    카테고리 없음 2022. 10. 24. 22:29

    Replication 이란?

    한 DB서버에서 다른 DB서버로 데이터가 동기화되는 것

    원본 데이터를 가진 DB서버를 Source 서버, 복제된 데이터를 가지는 DB서버를 Replica 서버라고 한다.


    Replication 을 왜 해야할까

    Scale Out

    사용자가 늘어나다 보면 서버의 트래픽이 증가한다. 속닥속닥의 경우 WAS를 이중화하여 nginx 를 통해 로드밸런싱을 하고 있다. 그런데, WAS는 로드밸런싱을 해 부하가 분산되지만 DB 서버는 두 WAS 모두의 요청을 받으면서 결국 WAS가 한개일때와 같은 부하를 받게 된다. 결국 DB서버 또한 트래픽을 분산시켜주어 서버에 과부하가 걸리지 않도록 해야한다. DB Replication을 통해 DB서버를 다중화해 트래픽을 분산할 수 있다.

    백업

    DB 서버에 저장되는 데이터는 매우 중요하다. 개발자의 실수나 천재지변으로 인해 DB 서버에 문제가 생기면서 데이터가 손실된다면 그 서비스는 사용자들에게 더이상 신뢰받지 못할것이다. DB Replication 을 통해 Source DB가 문제가 생겨도 Replica DB를 Source DB로 승격시켜 복구할 수 있다.

    지리적 분산

    WAS에서 데이터를 DB에 요청할 때, WAS와 DB의 거리가 멀면 그만큼 통신 속도가 느려지게 된다. 기존의 WAS와 DB 서버가 멀 경우에 DB 서버 자체의 위치를 옮기는 것 대신, 복제를 통해 WAS와 DB 서버를 가깝게 위치시킬 수 있다.


    Replication Thread

    DB Replication은 세 개의 스레드를 통해 동작한다. Binary Log Dump Thread (소스 서버의 스레드), Replication I/O Thread (복제 서버의 스레드), Replication SQL Thread (복제 서버의 스레드) 세 개의 스레드를 통해 동작한다.

    Binary Log Dump Thread

    복제 서버가 소스 서버에 바이너리 로그 정보를 요청할 때, 두 서버가 연결되면 소스 서버에서 Binary Log Dump Thread 가 생성되어 바이너리 로그의 내용을 복제 서버로 전송한다.

    복제 서버로 바이너리 로그를 보낼때는 일시적으로 바이너리 로그에 잠금을 수행하고, 완료되면 잠금을 해제한다.

    Replication I/O Thread

    START SLAVE 명령을 통해 복제가 시작되는 시점에 복제서버에 Replication I/O Thread가 시작된다. 이 스레드는 소스 서버에 바이너리 로그를 요청하여 받아오고, 릴레이 로그 파일로 저장하는 말 그대로 I/O 역할을 수행하는 스레드이다.

    Screen Shot 2022-10-24 at 5 35 19 PM

    show slave status\G 명령을 통해 이 스레드의 상태를 확인할 수 있다. 현재는 릴레이 로그 파일에 모든 이벤트를 처리했으니, I/O 스레드가 새로운 이벤트를 기다리고 있다는 뜻이다.

    Replication SQL Thread

    Replication I/O Thread에 의해 작성된 릴레이 로그 파일의 이벤트들을 읽고 실행하는 역할이다.


    Replication 타입

    바이너리 로그 파일 Position 기반 복제

    복제 서버에서 소스 서버의 바이너리 로그 파일명과 파일내의 position 으로 이벤트를 식별해 복제를 진행하는 방식이다.

    각 DB 서버마다 시스템 설정 변수로 server_id 값을 설정해주어야 하는데, 바이너리 로그 파일에 기록된 이벤트(소스서버에서 읽어온 파일의 이벤트) 가 복제서버에 설정된 server_id와 같은 값을 가지는 경우 복제서버는 해당 이벤트를 적용하지 않고 무시한다. 자신의 서버에서 발생한 이벤트라고 간주해버리기 때문이다.

    글로벌 트랜잭션 아이디(GTID) 기반 복제

    GTID는 각 트랜잭션과 연결된 고유 식별자로, 해당 트랜잭션이 발생한 서버에서 고유할 뿐만 아니라 복제 아키텍처 내의 모든 서버에서 고유한 식별자이다. SELECT 쿼리 혹은 sql_log_bin 설정이 비활성화 되어 있는 상태에서 발생한 트랜잭션은 바이너리에 기록되지 않기 때문에 GTID가 할당되지 않는다.

    소스 아이디와 트랜잭션 아이디 값의 조합으로 생성된다.


    복제 아키텍처

    일반적으로 사용되는 복제 아키텍처를 살펴보자.

    싱글 레플리카 구성

    Screen Shot 2022-10-24 at 9 49 25 PM

    가장 기본적인 형태이다. 이 형태에서는 WAS 서버가 보통 소스 서버에만 직접 요청을 하고, 복제 서버는 백업용 DB 서버 역할을 하는 경우가 많다. 이처럼 복제서버가 하나인 경우에 복제서버로 읽기 쿼리를 실행하게 설정한다면, 복제서버에 문제가 발생했을 경우에 장애 상황이 일어나게 된다.

    복제서버가 하나로 구성된 경우에는 복제서버를 예비용 서버로 두는것이 적합하다.

    멀티 레플리카 구성

    Screen Shot 2022-10-24 at 10 14 21 PM

    싱글 레플리카 구성에서 추가적인 용도를 위해 하나의 복제 서버를 더 추가한 형태이다. 이 구성은 소스서버가 모든 트래픽을 다 받기에는 부담이 되기 때문에 스케일 아웃 목적으로 복제서버를 하나 더 두어서 조회 요청에 대한 트래픽을 소스서버와 같이 감당하도록 한다. 조회 요청을 처리하게된 복제서버는 소스서버 만큼이나 중요해진다. 이 때도 복제서버 하나는 백업용으로 남겨두어 복제서버 혹은 소스서버가 장애가 났을 경우 역할을 대신할 수 있도록 해야한다.


    다음편에서는 속닥속닥 프로젝트에 직접 DB Replication을 적용한 이야기를 써보도록 하겠다.


    참고: Real MySQL 8.0 2권

    댓글

Designed by Tistory.