큰 하나의 데이터베이스(Monolithic)를 여러개의 데이터베이스(MSA)로 구조를 개선하면서  
발생하는 이슈에 좀 더 쉽게 대응하기 위하여 MSR을 도입한 사례에 대해서 간략하게 설명하겠습니다.

소개

저희 IT전략팀은 사람인의 계속적인 서비스 확장에 따른 개발 복장성 증가 및 서비스 간 강한 결합으로 인한 각 개발팀간 병렬 작업에 따르는 복잡한 상호 의존을 제거하기 위하여, 기존 Legacy 시스템을 MSA(Microservice Architecture)로 전환 및 고도화하는 프로젝트를 담당하고 있습니다.


도입 이유

그 중 개발의 편의 및 관리를 용이하게 하기 위해 Monolithic 로 구현 된 환경을 Microservice 로 일부 서비스에 대하여 전환을 진행하며, 하나의 거대한 Database 시스템을 서비스 단위로 분리하는 작업을 진행했습니다. 하지만 서비스 및 DB를 분리하였음에도 불구하고, 내부 시스템에서 필요로하는 데이터 동기화 요구, 메인 데이터베이스 참조에 따른 문제, 지표를 보기 위해 SQL로 쉽게 JOIN 및 데이터 추출이 필요해야 한다면, 배치 작업으로 DB간 데이터를 복사하거나, 큰 시스템에 복원해서 작업해야 하는 이슈가 있습니다.


구현

아래 그림은 기본적인 MySQL Master/Slave Replication 구성 방법입니다.

위와 같이 Master(쓰기)는 1대를 사용하며, Slave(읽기)는 n대를 사용하여 부하를 분산합니다.

개발 및 관리의 편의와 같은 목적으로 시작 된 Monolithic 으로 구현 된 환경은 사업이 확장하고 사용자가 증가함에 따라서 자연스럽게 부하 및 트래픽이 증가됩니다. 또한 작은 장애가 전체 시스템의 장애로 이어집니다. 이에 장애를 최소화 하고 부하 및 트래픽을 분산하기 위하여 개발과 같이 Microservice 로 전환하면 또 다른 문제가 발생합니다.

각 서비스 별 장애는 최소화 되었으며, 부하 및 트래픽도 분산되었지만, 서비스가 작은 단위로 이루어져 관리 및 모니터링이 불편합니다. 또한 데이터 분석 및 내부 시스템을 활용해야하는 부분에서 여러 기술이 사용되어지게 됩니다. 실시산으로 데이터 동기화가 필요한 시스템은 CDC, 준 실시간 및 일 단위 등의 데이터가 필요한 시스템은 ETL 및 Shell Script로 데이터를 동기화하며, Elasticsearch같은 빅데이터 등 DW 를 위한 데이터 동기화를 위한 Logstash 같은 여러 어플리케이션을 활용하게 됩니다.

그렇지만 MSR 기술을 사용해 다중의 마스터를 하나의 슬레이브로 복제 할 수 있도록 시스템을 구축한다면 ?

MySQL MSR은 기본 Replication구조에서 확장 된 개념으로 Binary Log를 기본으로 하여 각각의 마스터를 CHANNEL로 연결하여 Replicate하는 구조입니다. 각각의 CHANNEL을 통해 Master / Slave간 연결을 하고, 이 CHANNEL은 Replication 연결에 사용되는 Thread(IO, SQL, Worker 및 Coordinator 등)들을 관리합니다.

예를 들어서 어떤 시스템이 공통DB, 메인DB, 로그DB로 구성되어 있고 로그DB는 여러개로 샤딩(Sharding)되어 물리적으로 다른 장비에서 서비스를 하고있다고 생각해 볼 수 있습니다.
그런데 어떤 지표를 보기 위해서 모든 DB에서 한방에 쿼리를 해서 join 을 걸어야 한다면, 예전에는 batch 작업으로 특정시점에 데이터를 모두 백업해서, 커다란 장비에 복원해야 했습니다. 엄청 오래걸리고 까다롭습니다.
MySQL의 복원은 특히 오래 걸립니다. 그런데, MSR이 사용된다면? 그냥 큰 디스크가 존재하는 장비하나에 모든 DB의 Slave 로 Channel로 구성 할 수 있습니다. 예전처럼 여러 벤더사의 Third Party Tool을 사용하지 않고, MySQL의 자체 기능을 사용하여 관리하기 용이한 시스템을 구축 할 수 있습니다.

MSR 구성 방법

  • 필수 설정
mysql> show variables like '%repository%';
+---------------------------+-------+
| Variable_name             | Value |
+---------------------------+-------+
| master_info_repository    | TABLE |
| relay_log_info_repository | TABLE |
+---------------------------+-------+
2 rows in set (0.25 sec)

-> MSR 설정을 위해서는 Repository를 FILE이 아닌 TABLE에 저장해야 합니다.

  • 그 외 다른 문법
mysql>  CHANGE MASTER TO
    ->  MASTER_HOST='XXX.XXX.X.001',
    ->  MASTER_USER='xxxxxxxx',
    ->  MASTER_PASSWORD='xxxxxxxx,
    ->  MASTER_LOG_FILE='mysql-bin.000001',
    ->  MASTER_LOG_POS=919
    ->  FOR CHANNEL 'sri-xxxxxx_1';
Query OK, 0 rows affected, 2 warnings (0.06 sec)

mysql>  CHANGE MASTER TO
    ->  MASTER_HOST='XXX.XXX.X.002',
    ->  MASTER_USER='xxxxxxxx',
    ->  MASTER_PASSWORD='xxxxxxxx,
    ->  MASTER_LOG_FILE='mysql-bin.000002',
    ->  MASTER_LOG_POS=275
    ->  FOR CHANNEL 'sri-xxxxxx_2';
Query OK, 0 rows affected, 2 warnings (0.02 sec)

mysql>  CHANGE MASTER TO
    ->  MASTER_HOST='XXX.XXX.X.003',
    ->  MASTER_USER='xxxxxxxx',
    ->  MASTER_PASSWORD='xxxxxxxx,
    ->  MASTER_LOG_FILE='mysql-bin.000003',
    ->  MASTER_LOG_POS=101
    ->  FOR CHANNEL 'sri-xxxxxx_3';
Query OK, 0 rows affected, 2 warnings (0.05 sec)
START SLAVE FOR CHANNEL 'sri-xxxxxx_1';
STOP SLAVE FOR CHANNEL 'sri-xxxxxx_1';
START SLAVE FOR CHANNEL 'sri-xxxxxx_2';
STOP SLAVE FOR CHANNEL 'sri-xxxxxx_2';
START SLAVE FOR CHANNEL 'sri-xxxxxx_3';
STOP SLAVE FOR CHANNEL 'sri-xxxxxx_3';
mysql> show slave status for channel 'sri-xxxxxx_1'\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
~~~
                  Master_User: xxxxxxxx
                  Master_Port: 3306
~~~
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
~~~
        Seconds_Behind_Master: 0
~~~
             Master_Info_File: mysql.slave_master_info
~~~
                 Channel_Name: sri-xxxxxx_1
~~~
1 row in set (0.00 sec)

문제

※ MySQL Replication 복제 시 지연을 생각하지 않을 수 없는데 MSR은 어떨까요?
실제 서비스 운영 시, Master / Slave 간 Replication Delay는 0.1초 미만으로 지연되게끔 구현하고 있습니다.
그렇다면 MSR의 CHANNEL은 지연이 언제 생기는 것인가 ?

-> 일반적으로 Replication 지연이 발생될만한 상황에선 MSR도 동일하게 지연이 발생됩니다.

​ (대용량 CTAS, 대용량 ALTER TABLE 등)

확인 된 이슈 사항

3개의 Master DB에 총 10개의 테이블에 순차적으로 100만건 Insert 작업 시, Replication 이 구성 된 Slave에서는 IO_Running 및 SQL_Running이 정상 동작. Multi Source Replication으로 구성 된 Slave에서는 SQL_Running은 정상 동작하지만 IO_Running이 끊어지며 자동으로 Reconnect 되지만, Replication Delay가 끊어진 시간만큼 발생합니다.

3개의 Master DB에 총 2개의 테이블에 순차적으로 100만건 Insert 작업 시 위와 같은 문제는 발생하지 않않습니다.

(대량 작업 시 MSR Slave는 Replication이 일시적으로 끊어질 수 있음을 의미합니다.)

mysql> show slave status\G;
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
        Seconds_Behind_Master: 0
                 Channel_Name: sri-xxxxxx_1
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
        Seconds_Behind_Master: 0
                 Channel_Name: sri-xxxxxx_2
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
             Slave_IO_Running: Reconnect
            Slave_SQL_Running: Yes
        Seconds_Behind_Master: 0
                 Channel_Name: sri-xxxxxx_3
3 row in set (0.00 sec)

3개의 Master DB에 각각의 CTAS 작업 수행 시 3개 전부 동시에 수행됨을 확인(Multi Thread Replication이 정상 동작됨을 확인)

한 마디로 대량의 트랜잭션이 들어온다면 MSR은 일부 CHANNEL을 스스로 일시적으로 동기화를 중단합니다. I/O Thread가 중단되므로 실제 일부 CHANNEL은 Master에서 Binary Log를 더이상 읽어오지 않습니다. (이 때, Master의 Binary Log가 지워진다면 Slave는 Master의 데이터를 복제 할 수 없습니다.)

제 경우엔 3개의 CHANNEL 중, C라는 CHANNEL에서 트랜잭션을 길게 사용하는 부분이 있었는데, Master / Slave간에는 전혀 Replication 지연이 발생하지 않지만, MSR에서 해당 CHANNEL을 동기화 중단하고 다시 연결하는 현상을 발견했습니다.

※ 예상 되는 부분으로는 Semi-Synchronous Replication 동작 중, Master까지 ACK를 주는 부분에서 큰 트랜잭션에 대한 부분이 다른 채널에서 사용중이라 대기하고 있는 현상으로 보여집니다.

SET global rpl_semi_sync_slave_enabled=OFF;

실제 MSR에서 해당 파라메터 변경 시, 더이상의 지연은 발생되지 않습니다.
(하지만 이런 설정은 문제가 존재합니다. Semi-Sync Replication의 ACK 부분이 문제가 됩니다.)

이에 해당하는 트랜잭션을 하나의 큰 트랜잭션이 아닌 작은 단위의 트랜잭션으로 분리 후 해결하였습니다.

pt-online-schema-change 사용에도 MSR의 Channel을 Lag 를 감지하지 못 하고 오류가 발생하는 부분도 존재하였으며,
(정상적으로 수행은되나 Lag delay현상을 감지하지 못 하고 무시하고 수행 됨)
특정 버젼 이상에서 정상적으로 사용 가능한 것으로 확인되었습니다.

참고 URL : https://jira.percona.com/browse/PT-1502

현재 저희가 사용하는 MSR 시스템은 내부 관리시스템, 백업, 빅데이터 및 ETL/CDC 등을 위한 용도로만 사용하고 있습니다.


후기

현재로선 내부시스템 용도로 만족스럽게 사용하고 있습니다.
사실 더 안정적이었다면 메인 서비스로 고려도 해보겠지만, 딜레이 이슈 및 Semi-Sync의 장점을 가져가지 못 한다는 부분에서 내부 서비스로만 사용하고 있습니다.
현재도 문제가 발견되고 있지만 이러한 문제를 계속적으로 해결하여 잘 사용 할 수 있도록 도와주고 지원해주신 IT전략팀 및 DA팀원 분들께 감사드립니다.