[Computer Science] Replication

김상현·2023년 9월 10일
0

CS

목록 보기
5/10
post-thumbnail

🎥 [10분 테코톡] ✌️ 영이의 Replication

📌 Replication이란?

Replication이란 한 서버에서 다른 서버로 데이터를 동기화 하는 것을 의미한다. 다시 말하자면 원본 데이터를 가지고 있는 소스 서버가 존재하고 소스 서버에 존재하는 데이터를 복제하여 가지고 있는 서버를 레플리카 서버라고 한다.

📌 Replication을 사용하는 이유?

레플리케이션 서버를 사용하는 이유는 데이터베이스의 부하를 줄이기 위해서 사용한다고 생각하지만 단순히 데이터베이스의 부하를 줄이기 위해서 만은 아니다. 이 외에도 레플리케이션 서버를 사용해야 하는 다양한 이유들이 있다.

스케일 아웃

스케일 아웃(scale out)은 서버를 여러 대 추가하여 시스템을 확장하는 것을 말한다.수 많은 요청이 발생하여 현재 구동중인 서버 만으로는 감당하기 어려울 때 서버를 추가하여 각 서버에 할당되는 요청을 줄이기 위해서 사용한다. 레플리케이션 서버를 추가한다면 갑자기 늘어나는 트래픽을 유연하게 대응할 수 있게 된다.

데이터 백업

서비스를 소스 서버 하나로만 구성하여 소스 서버에서 데이터 백업을 수행할 경우 실제 수행중인 쿼리들이 영향을 받을 수 있다. 최악의 경우 쿼리의 처리 속도가 느려져 서비스에 문제가 발생할 수 있다. 앞선 문제들을 해결하기 위해서 레플리케이션 서버를 생성한 후 레플리케이션 서버에서 데이터 백업을 실행한다면 소스 서버에서는 서비스에서 발생하는 쿼리에만 집중할 수 있게 된다.

데이터 분석

데이터 분석을 위한 쿼리는 대량의 데이터를 조회하는 경우가 많고 대량의 데이터를 조회하는 쿼리는 서버에 부담을 많이 발생시킬 수 밖에 없다. 따라서 데이터 분석만을 위한 레플리케이션 서버를 생성한 후 해당 서버에서 데이터 분석을 진행하는 것이 좋다.

데이터의 지리적 분산

데이터베이스와 애플리케이션 서버가 멀리 떨어져 있다면 요청에 대한 응답이 늦어질 수 밖에 없다. 빠른 응답을 위해서는 애플리케이션 서버와 가깝게 데이터베이스 서버를 구축하는 것이 좋다. CDN(Content Delivery Network )이 이와 같은 케이스라고 볼 수 있다.

정리하자면 레플리케이션 서버를 생성하는 이유는 서비스 업무를 수행해야 하는 소스 서버에서 수행하기 부담스러운 업무들을 처리하기 위해서라고 볼 수 있다.

📌 Replication 동작 원리?

바이너리 로그(binary log)란 MySQL 서버에서 발생하는 모든 변경사항(데이터의 변경, 데이터베이스 및 테이블의 구조 변경, 계정 및 권한 변경)을 별도의 로그 파일에 순서대로 저장된 것을 말한다.

MySQL의 레플리카는 바이너리 로그를 기반으로 구현되어 있다. 소스 서버에서 생성된 바이너리 로그가 레플리카 서버로 전송되고 레플리카 서버에서는 해당 내용을 로컬 디스크에 저장한 뒤 자신이 가진 데이터에 반영함으로써 소스 서버와 레플리카 서버 간에 데이터 동기화가 이루어진다.

MySQL에서 소스 서버를 레플리카 서버로 복제하는 과정은 Binary Log Dump Thread, Replication I/O Thread, Replication SQL Thread 3개의 쓰레드에 의해 수행된다.

        Source Server
┏ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ┓
┃ ⚙️ Binary Log Dump Thread  ┃
┗ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ┛
 
       Replica Server
┏ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ┓
┃ ⚙️ Replication I/O Thread  ┃
┃ ⚙️ Replication SQL Thread  ┃
┗ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ━ ┛ 

Binary Log Dump Thread

Binary Log Dump Thread는 소스 서버의 바이너리 로그를 레플리카 서버로 전송하는 쓰레드이다. 레플리카 서버가 소스 서버에 연결되면 소스 서버에서 내부적으로 Binary Log Dump Thread를 생성하게 된다.

Replication I/O Thread

Replication I/O Thread는 Binary Log Dump Thread가 전송한 바이너리 로그 읽어 레플리카 서버의 릴레이 로그로 저장하는 쓰레드이다. 복제가 시작되면 쓰레드가 생성되고 복제가 멈추면 쓰레드는 종료된다. 즉, Replication I/O Thread는 소스 서버의 Binary Log Dump Thread가 바이너리 로그를 전송할 경우에만 동작하는 쓰레드이다.

Replication SQL Thread

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

📌 변경 내용 식별 방법?

바이너리 로그 변경 내역을 찾는 방식은 바이너리 로그 파일 위치 기반 방법과 글로벌 트랜잭션 ID 기반(GTID) 방법이 있다.

바이너리 로그 파일 위치 기반 방법은 레플리카 서버에서 소스 서버의 바이너리 로그 파일명과 파일 내에서의 위치로 바이너리 로그 이벤트를 비교한 후 변경 사항이 있을 경우 해당 이벤트를 실행한다. 바이너리 로그 파일 위치 기반 방법으로 변경 내용을 식별할 때 단점이 있는데, 변경 사항을 식별하는 과정이 소스 서버에서만 유효하다는 점이다. 소스 서버에서 발생한 이벤트가 레플리카 서버에서 동일한 위치와 동일한 파일명으로 저장된다는 보장이 없기 때문이다. 동일한 이벤트에서 서로 다른 식별값을 가지는 경우가 발생할 수도 있다는 것이다.

이러한 문제를 해결하기 위해 만들어진 방법이 글로벌 트랜잭션 ID 기반(GTID) 식별 방법이다. 글로벌 트랜잭션 ID 기반(GTID)은 각 이벤트들이 복제에 참여한 모든 MySQL 서버들에서 동일한 고유 식별 값을 가지도록 하는 방법이다. 즉, 하나의 이벤트에서 생성된 식별값을 모든 MySQL 서버에서 공유하는 것이다.

📌 바이너리 로그의 형식?

Statement

Statement 형식은 SQL문을 바이너리 로그에 그대로 기록하는 방식이다. 바이너리 로그의 형식을 Statement 형식으로 사용할 때 주의할 점은 트랜잭션의 격리 수준이 REPEATABLE-READ 이상이어야 한다. REPEATABLE-READ 이하 방식에서는 하나의 트랜잭션 내에서도 각 쿼리가 실행되는 시점마다 스냅샷이 달라질 수 있는데 이로 인해 복제시 소스 서버와 레플리카 서버의 데이터가 일치하지 않을 수 있기 때문에 바이너리 로그를 Statement 형식으로 사용하기 위해서는 반드시 트랜잭션의 격리 수준이 REPEATABLE-READ 이상으로 맞춰줘야 한다.

Row

Row 형식은 데이터 변경이 발생했을 때 변경된 데이터 값 자체를 기록하는 방식이다. 소스 서버의 어떠한 데이터의 변경이 발생하던지 상관 없이 소스 서버와 레플리카 서버의 데이터를 일관되게 유지하는 가장 안전한 방식이다. 하지만, 변경 데이터가 전부 기록되기 때문에 바이너리 로그 파일이 단시간에 매우 커진다는 단점이 있다. 또한 소스 서버에서 발생한 쿼리들을 레플리카 서버에서는 알 수 없다.

Mixed

Mixed 형식은 Statement 형식과 Row 형식을 혼합한 방식이다. Mixed 형식은 Statement 형식과 Row 형식의 장단점을 서로 보완하기 위해 사용한다. 만약 실행된 쿼리가 Statement 포맷으로 기록되어 복제되었을 때 문제가 될 가능성이 있는 안전하지 못한 쿼리라면 Row 형식으로 로그를 기록한다. 이외의 상황에서는 Statement 형식으로 로그를 기록한다.

📌 복제 동기화 방식

MySQL에서는 비동기 복제, 반동기 복제 2가지 복제 동기화 방식을 제공합니다.

비동기 복제

비동기 복제는 소스 서버가 레플리카 서버에 전달한 변경 이벤트가 정상적으로 전달 되었는지 확인하지 않는다. 소스 서버는 레플리카 서버에 변경 이벤트가 잘 적용되었는지 알지 못하게 되고 소스 서버에 장애가 발생하면 소스 서버에서 최근까지 적용된 트랜잭션이 레플리카 서버로 전송되지 않을 수 있다. UDP와 유사하다고 볼 수 있다.

반동기 복제

반동기 복제는 소스 서버가 레플리카 서버로 전달한 변경 이벤트가 정상적으로 전달 되었는지 레플리카 서버로 부터 확인 응답을 받게되면 그 때 트랜잭션을 완전히 커밋한다. 다시 말하자면 소스 서버에서 전송한 바이너리 로그와 레플리카 서버에서 받은 바이너리 로그가 일치하는 것을 보장한다는 뜻이다. 하지만 소스 서버와 레플리카 서버의 바이너리 로그가 일치하는 것은 보장하지만, 소스 서버와 레플리카 서버의 바이너리 로그를 통해 발생한 데이터의 변경이 일치한다는 것에 대한 것은 보장하지 않는다. 즉, 소스 서버와 레플리카 서버의 데이터 동기화를 보장하지 않는다는 것이다.

📌 소스 서버와 레플리카 서버 구성 방식

싱글 레플리카

싱글 레플리카 구성은 하나의 소스 서버에 하나의 레플리카 서버만 연결되어 있는 복제 형태이다. 이 경우 소스 서버에 문제가 발생하였을 때 예비 서버 및 데이터 백업 수행을 위한 용도로 사용한다.

멀티 레플리카 복제

멀티 레플리카 복제 구성은 하나의 소스 서버에 2개 이상의 레플리카 서버를 연결한 복제 형태이다. 싱글 레플리카와 마찬가지로 하나의 레플리카 서버는 예비용으로 구성하고 나머지 레플리카 서버는 읽기(READ) 요청 처리를 분산하는 용도로 사용한다.

체인 복제

체인 복제 구성은 하나의 소스 서버에 연결된 레플리카 서버수가 많다면 바이너리 로그를 읽고 전달하는 작업 자체가 소스 서버에 부담이 될 수 있는데 이를 해결하기 위해 사용하는 방식이다. 소스 서버가 해야할 바이너리 로그 배포 역할을 다른 레플리카 서버로 넘기는 방식이다.

듀얼 소스 복제

듀얼 소스 복제는 2개의 서버가 서로 소스 서버이자 레플리카 서버로 구성되어 있는 형태이다. 두 서버 모두 쓰기가 가능하다는 것이 특징이며 각 서버에서 변경한 데이터는 복제를 통해 다시 각 서버에 적용되므로 양쪽에서 쓰기가 발생한다는 단점이 있지만 두 서버는 서로 동일한 데이터를 갖게 된다. 싱글 레플리카 구성과 유사하지만 듀얼 소스 복제 구성은 1개의 서버에 오류가 발생할 경우 다른 서버로 전환을 바로 가져갈 수 있다는 차이점이 있다.

멀티 소스 복제

멀티 소스 복제는 2개 이상의 소스 서버를 갖는 형태를 의미한다. 여러 서버에 존재하는 다른 데이터를 하나의 서버로 통합하거나, 샤딩되어 있는 테이블 데이터를 하나의 테이블로 통합할 때 사용할 수 있다.

profile
목적 있는 글쓰기

0개의 댓글