Featured image of post 16.6 복제 - 복제 토폴로지

16.6 복제 - 복제 토폴로지

Real MySQL 8.0

싱글 레플리카 복제 구성

flowchart LR
    a([웹 서버])
    b[(소스 서버)]
    c[(레플리카 서버)]

    a-. 읽기 + 쓰기 .-> b
    a-. 읽기 .-> c
    b-->c

하나의 소스 서버에 하나의 레플리카 서버반 연결돼 있는 복제 형태를 말한다.

가장 기본적인 형태로, 보통 애플리케이션 서버는 소스 서버에만 직접적으로 접근해 사용하고 레플리카 서버에는 접근하지 않으며, 레플리카 서버는 소스 서버에서 장애가 발생했을 때 사용될 수 있는 예비 서버 및 데이터 백업 수행을 위한 용도로 많이 사용된다.

이 같은 형태에서 애플리케이션 서버가 레플리카 서버에서도 서비스용 읽기 쿼리를 실행한다고 하면 레플리카 서버에 문제가 발생한 경우 서비스 장애 상황이 도래할 수 있다.

이렇게 소스 서버와 레플리카 서버가 일대일로 구성된 형태에서는 레플리카 서버를 정말 예비용 서버로서만 사용하는 게 제일 적합하다.

멀티 레플리카 복제 구성

flowchart LR
    a([웹 서버])
    b[(소스 서버)]
    c[(레플리카 서버 1)]
    d[(레플리카 서버 2)]

    a-. 읽기 + 쓰기 .-> b
    a-. 읽기 .-> d
    b-->c
    b-->d

멀티 레플리카 복제는 하나의 소스 서버에 2개 이상의 레플리카 서버를 연결한 복제 형태로, 보통 싱글 레플리카 복제 구성에서 추가적인 용도를 위해 여분의 레플리카 서버가 필요해졌을 때 자주 사용되는 형태다.

새로 오픈될 서비스에서 사용할 MySQL 서버를 설정할 때는 유입되는 쿼리 요청이 적기 때문에 보통 싱글 레플리카 복제 구성으로 구축하지만, 서비스의 트래픽이 크게 증가하면 소스 서버 한 대에서만 쿼리 요청을 처리하기에는 벅찰 수 있다.

이렇게 증가된 쿼리 요청은 대부분의 경우 쓰기보다는 읽기 요청이 더 많으므로 사용자는 멀티 레플리카 형태로 복제 구성을 전환해 읽기 요청 처리를 분산시킬 수 있다.

서비스의 읽기 요청 처리를 분산하는 용도로 사용하는 경우 레플리카 서버 한 대는 예비용으로 남겨두는 것이 좋다.

체인 복제 구성

flowchart LR
    a([웹 서버])
    b[(소스 서버 1)]
    c[(레플리카 서버 1-1)]
    d[(레플리카 서버 1-2)]
    e[(레플리카 서버 1-3 / 소스 서버 2)]
    f([배치/분석 서버])
    g[(레플리카 서버 2-1)]
    h[(레플리카 서버 2-2)]

    a-. 읽기 + 쓰기 .-> b
    a-. 읽기 .-> d
    b-->c
    b-->d
    b-->e
    e-->g
    e-->h
    f-. 읽기 .-> h

멀티 레플리카 복제 구성에서 레플리카 서버가 너무 많아 소스 서버의 성능에 악영향이 예상된다면 1:N:M 구조의 체인 복제 구성을 고려해 볼 수 있다.

MySQL 복제에서 소스 서버는 레플리카 서버가 요청할 때마다 계속 바이너리 로그를 읽어서 전달해야 한다.

따라서 만약 하나의 소스 서버에 연결된 레플리카 서버 수가 많다면 바이너리 로그를 읽고 전달하는 작업 자체가 부하가 될 수도 있다.

이러한 경우 레플리카 서버 1-3 / 소스 서버 2 형태로 소스 서버가 해야 할 바이너리 로그 배포 역할을 새로운 MySQL 서버로 넘길 수 있다.

체인 복제 구성을 이용한 서버 교체

이 복제 형태는 MySQL 서버를 업그레이드하거나 장비를 일괄 교체할 때도 사용될 수 있다.

flowchart
    subgraph 구 장비
        direction LR
        a([웹 서버])
        b[(소스 서버 1)]
        c[(레플리카 서버 1-1)]
        d[(레플리카 서버 1-2)]
        a-. 읽기 + 쓰기 .-> b
        a-. 읽기 .-> d
        b-->c
        b-->d
    end

위와 같은 구 장비를 신 장비로 교체하기 위해 아래와 같이 새로운 장비를 구성한다.

flowchart LR
    subgraph 구 장비
        direction LR
        a([웹 서버])
        b[(소스 서버 1)]
        c[(레플리카 서버 1-1)]
        d[(레플리카 서버 1-2)]
        a-. 읽기 + 쓰기 .-> b
        a-. 읽기 .-> d
        b-->c
        b-->d
        b-->e
    end

    subgraph 신 장비
        direction LR
        e[(레플리카 서버 1-3 / 소스 서버 2)]
        f[(레플리카 서버 2-1)]
        g[(레플리카 서버 2-2)]
        e-->f
        e-->g
    end

위와 같이 복제를 구성하여 기존 구 장비에서 진행되는 복제를 통해 같이 동기화 될 수 있게 구성한다.

flowchart LR
    subgraph 구 장비
        direction LR
        a([웹 서버])
        b[(소스 서버 1)]
        c[(레플리카 서버 1-1)]
        d[(레플리카 서버 1-2)]
        a-. 읽기 + 쓰기 (변경 전) .-> b
        a-. 읽기 .-> d
        b-->c
        b-->d
        b-->e
    end

    subgraph 신 장비
        direction LR
        e[(레플리카 서버 1-3 / 소스 서버 2)]
        f[(레플리카 서버 2-1)]
        g[(레플리카 서버 2-2)]
        a-. 읽기 + 쓰기 (변경 후) .-> e
        e-->f
        e-->g
    end

복제가 완료되면 구 장비 그룹 서버를 모두 복제 그룹에서 제외시킨다.

flowchart LR
    subgraph 신 장비
        direction LR
        a([웹 서버])
        e[(레플리카 서버 1-3 / 소스 서버 2)]
        f[(레플리카 서버 2-1)]
        g[(레플리카 서버 2-2)]
        a-. 읽기 + 쓰기 .-> e
        a-. 읽기 + 쓰기 .-> f
        e-->f
        e-->g
    end
  • 체인 형태의 복제를 구성하려면 중간 계층에서 레플리카 서버이면서 동시에 소스 서버 역할을 하는 서버에서 바이너리 로그와 log_slave_updates 시스템 변수가 반드시 활성화 되어 있어야 한다.
  • 체인 복제 구성을 사용할 때는 중간 계층의 서버에서 장애가 발생하는 경우 하위 계층의 레플리카 서버들도 복제가 중단되므로 장애 처리시 복잡도가 조금 더 높을 수 있다.

듀얼 소스 복제 구성

듀얼 소스 복제 구성은 두 개의 MySQL 서버가 서로 소스 서버이자 레플리카 서버로 구성되어 있는 형태이다.

flowchart LR
    a([웹 서버])
    b[(소스/레플리카 서버 1)]
    c[(소스/레플리카 서버 2)]
    a-. 읽기 + 쓰기 .-> b
    a-. 읽기 + 쓰기 .-> c   
    b<-->c

듀얼 소스 구성은 두 MySQL 서버 모두 쓰기가 가능하다는 것이 큰 특징이다.

  • 각 서버에서 변경한 데이터는 복제를 통해 다시 각 서버에 적용되므로 양쪽에서 쓰기가 발생하지만 두 서버는 서로 동일한 데이터를 갖는다.
  • 목적에 따라 ACTIVE-PASSIVE 또는 ACTIVE-ACTIVE 형태로 사용할 수 있다.

ACTIVE-PASSIVE

하나의 MySQL 서버에서만 쓰기 작업이 수행되는 형태이다.

  • 싱글 레플리카 구성과 다른점은 예비 서버인 다른 MySQL 서버가 바로 쓰기 작업이 가능한 상태이므로 작업이 수행되고 있는 서버에서 문제 발생 시 별도의 설정 변경 없이 바로 예비용 서버로 쓰기 작업을 전환할 수 있다.
  • 한 서버에서 다른 서버로 바로 쓰기가 전활될 수 있는 환경이 필요한 경우 사용된다.

ACTIVE-ACTIVE

두 서버 모두에 쓰기 작업을 수행하는 형태이다.

  • 주로 지리적으로 매우 떨어진 위치에서 유입되는 쓰기 요청도 원활하게 처리하기 위해 사용된다.
  • 각 지역에 위치한 MySQL 서버로 수행되게 끔 구현하여 처리하며, 최종적으로 같은 데이터들을 갖게 된다.
  • 하지만 복제를 통해 다른 지역의 서버로부터 넘어온 트랜잭션이 적용되기까지는 다소 시간이 걸려 적용 전까지 일관되지 않은 데이터를 가질 수 있다.

주의사항

  • 동일한 데이터를 각 서버에서 변경
    • 두 서버 모두에서 쓰기가 발행하는 ACTIVE-ACTIVE 형태
    • 동일한 데이터에 대한 변경 트랜잭션이 서버에 동시점에 유입되는 경우 나중에 처리된 트랜잭션의 내용이 최종적으로 반영함
    • 이러한 경우 예상하지 못한 방향으로 데이터가 처리될 수 있음
  • 테이블에서 Auto-Increment 사용
    • 거의 동일한 시점에 새로운 데이터가 각 서버로 유입되었을 때 같은 키 값을 가질 수 있다.

ACTIVE-ACTIVE 형태에서는 동시점에 동일한 데이터를 변경하는 트랜잭션이 있어서는 안되며, 테이블의 Auto-Increment 키 사용을 지양하고 애플리케이션 단에서 글로벌하게 값을 생성해서 사용하는 것이 좋다.

ACTIVE-PASSIVE 형태라도동시에 쓰기 요청이 유입된다면 발생한다.

멀티 소스 복제 구성

멀티 소스 복제 구성은 하나의 레플리카 서버가 둘 이상의 소스 서버를 갖는 형태를 말한다.

flowchart TD
    a[(소스 서버 1)]
    b[(소스 서버 2)]
    c[(소스 서버 3)]
    d[(소스 서버 4)]
    e[(레플리카 서버)]

    a-->e
    b-->e
    c-->e
    d-->e

멀티 소스 복제 기능은 MySQL 5.7.6 버전에서 처음 도입되었으며, 다음과 같은 목적으로 사용된다.

  • 여러 MySQL 서버에 존재하는 각기 다른 데이터를 하나의 MySQL 서버로 통합
    • 데이터 분석 같은 경우 조금 더 빠르고 편리하게 분석을 수행하고자 할 때 멀티 소스 복제 형태를 사용하면 효과적이다.
  • 여러 MySQL 서버에 샤딩돼 있는 테이블 데이터를 하나의 테이블로 통합
    • 늘어날 서비스 트래픽에 대비해 서버들을 동일한 테이블 스키마 구조를 가지는 샤드 형태로 구성했지만 트래픽이 유입되지 않은 경우 멀티 소스 복제를 구성하여 샤딩된 테이블들의 데이터를 통합해 MySQL 서버 수를 줄일 수 있다.
  • 여러 MySQL 서버에 데이터들을 모아 하나의 MySQL 서버에서 백업을 수행
    • 다수의 서버의 데이터를 하나의 서버에서 백업하고자 할 때도 멀티 소스 복제 구성을 통해 손쉽게 구현할 수 있다.

멀티 소스 복제 형태를 사용할 때는 각 소스 서버로부터 유입되는 변경 이벤트들이 레플리카 서버로 복제되었을 때 서로 충돌을 일으킬 만한 부분이 없는지 사전에 충분한 검토가 필요하다.

멀티 소스 복제의 레플리카 서버는 각 소스 서버들의 대체 서버로 사용하기에는 어려움이 있으므로 장애 대비용 레플리카 서버는 멀티 소스가 아닌 각 소스 서버와 일대일 복제로 연결된 별도의 서버로 구축하는 것이 좋다.

멀티 소스 복제 동작

멀티 소스 복제에서 레플리카 서버는 자신과 연결된 소스 서버들의 변경 이벤트들을 동시점에 병렬로 동기화한다.

각 소스 서버들에 대한 복제가 독립적으로 처리되는 것을 의미하며, 각각의 독립된 복제 처리를 채널(Channel)이라고 한다.

각 복제 채널은 개별적인 레플리케이션 I/O 스레드, 릴레이 로그, 레플리케이션 SQL 스레드를 가지며, 채널의 이름은 어느 소스 서버와의 복제연결인지를 구별할 수 있는 식별자 역할을 한다.

최대 256개 복제 채널을 이용할 수 있다.

멀티 소스 복제 구축

기존의 단일 소스 복제와 달리 구축하는 과정에 큰 차이가 있는 것은 아니다.

복제를 연결하기 위해 소스 서버들의 백업 데이터를 레플리카 서버로 적재해야 하는데, 기존과 달리 여러 대의 소스 서버의 백업 데이터를 가져와야 하므로 이부분의 작업이 조금 번거롭고 까다롭게 느껴질 수 있다.