서버 분산 처리 환경에서 MySQL을 Master/Slave로 이중화하기

devdo·2022년 5월 30일
0

Project

목록 보기
7/11
post-thumbnail

Scale-out시, 프로젝트 에서는 평소에는 서버 트래픽은 잠잠하지만 갑자기 read 할 request 양이 많아 대용량 트래픽이 있을 수 있다고 말씀드렸습니다.

https://velog.io/@mooh2jj/서버분산시스템-서버-확장은-어떻게-하나

이외에도 다른 관점에서 트래픽이 모이는 현상이 있습니다.
read, write, update 등의 모든 연산이 하나의 DB에서 일어난다면 트래픽이 늘어남에 따라 자연스럽게 병목 현상 이 생기는 것입니다.

이런 문제를 극복하기 위해 DB 구성을 이중화하는 작업을 합니다.

바로 Master/Slave 구조의 Replication 방식입니다.

write는 원본 서버인 Master 에서만 수행하게 하고 read 기능은 원본의 복제 서버인 Slave 에서 한다면

쓰기의 기능과 읽기의 기능을 완전히 독립시켜 병목 없이 부하 분산을 할 수 있게 됩니다.

Master -> write
Slave -> read

이런 방식은 데이터의 보안에도 긍정적으로 작용합니다.
Replication(복제)를 하기 때문에 원본 이외에 복제본에서 백업 서비스를 작동시키는게 가능해지는 겁니다.

만약, 원본 데이터가 손상이 되는 상황이 발생된다면, 복제본에 복사하는 일을 일시정지 시켜 데이터 손상의 백업을 할 수 있습니다.

이는 SlaveMaster로 승격해 데이터의 대한 복구를 빠르게 진행할 수 있기 때문입니다.

그러나 MySQL Replication은 비동기 방식으로 진행하기 때문에 Slave로 복사 되는 시간을 온전히 기다려 주지 않습니다. 때문에 데이터가 완벽하게 복사가 되지 않을 수도 있다는 단점은 존재합니다.


Master/Slave Replication 동작 과정

  1. 클라이언트가 Insert/Update/Delete 을 누르면 먼저 Master 서버에 존재하는 Binary log 에 변경사항을 모두 기록합니다.
  2. Master Thread 는 비동기적 으로(복사되는 시간을 기다려주지 않습니다.) Binary log를 읽어 Slave 서버로 전송합니다.
  3. Slave 의 I/O Thread 는 Master로 부터 받은 변경 데이터들을 Relay log 에 기록을 합니다.
  4. Slave의 SQL Thread 는 Replay log의 기록들을 읽어 자신의 스토리지 엔진에 최종 적용합니다.

☘ Binary Log란?

binarylog는 binlog라고도 부르고 있습니다.
MySQL에서 발생하는 모든 내역을 기록하는 Log File이고, 이것은 기본적으로 비활성화되어 있는데, conf 파일에서 수정해서 이를 활성화 시켜주어야 합니다.

❗ 주의사항

호환성을 위해 Replication을 이용하는 모든 DBMS는 동일한 환경으로 구성하는 것을 추천합니다.

Replication을 이용하는 DBMS Version이 각기 다른 경우 Slave Server가 Master Server보다 상위 Version이여야 합니다.

Replication 기동 시 Master Server부터 올리고, Slave를 올려야 합니다.

또한, Replication을 이용하게 되면 계속적으로 Binary Log가 쌓이게 되고, 이는 결국 Storage 용량을 잡아먹는 원인이 되요. 그렇기 때문에 Cron을 이용해서 정리를 주기적으로 하거나, my.cnf에 expire_logs_days에 Log에 대한 유효기간을 지정해 주어야 합니다.

Replication 과정에서 Error가 발생하면 Slave는 Error Log를 작성하게 됩니다.
나중에 Server 관리자 등이 Error를 추적하여 Binary Log를 분석하여 유실된 자료를 복구할 수 있도록 할 수 있답니다.


실제 구현

AWS EC2 instance (micro size)
Ubuntu 20.04
MySQL8.0

mysql 설치

sudo apt-get update
sudo apt-get install -y mysql-server

mysql running 확인

sudo systemctl status mysql

mysql 접속

sudo mysql -u root -p

master 서버 slave 서버 각각 설치합니다.

등록된 ip 서버 확인은

ip addr

Master 서버 설정

1) master 서버 mysql.cnf 수정

sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

파일을 열어 master 서버에 대한 수정을 진행합니다.
이는 slave에서 읽어갈 로그 파일을 지정해 주는 것입니다.

[mysqld]
bind-address            = 0.0.0.0 

server-id = 1
log_bin   = /var/log/mysql/mysql-bin.log
expire_logs_days = 90

MySQL을 한번 재시작합니다. 설정파일을 건드릴 때는 항상 재시작을 해주어야 합니다.

sudo systemctl restart mysql

2) slave서버 user 정보를 등록

master서버의 mysql 접속후,
slave서버 ip주소의 user 정보를 등록합니다. (아이디는 repl로 하겠습니다)

CREATE USER 'repl'@'172.31.8.143' IDENTIFIED BY '1234';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'172.31.8.143';

마스터의 status 정보를 조회

SHOW MASTER STATUS \G

아래 사진과 같이 나옵니다.

File
Position

정보를 기억해야 합니다. 나중에 slave 서버에서 master 서버 정보를 확인하기 위함입니다.


Slave 서버 설정

1) slave 서버 mysql.cnf 수정

master 서버 conf파일 수정처럼 똑같은 경로의 파일을 수정합니다.

[mysqld]
server-id = 2 # master server-id와 다른 번호를 주면 됨.

2) slave에 master 정보 입력하기

mysql 접속 후,

아까 show master status 때 보였던 정보들을
SOURCE_LOG_FILESOURCE_LOG_POS 에 각각 넣어주고 master의 공인IP 주소, 패스워드 등 정보를 입력해줍니다.

CHANGE REPLICATION SOURCE TO SOURCE_HOST='172.31.13.18', SOURCE_LOG_FILE='mysql-bin.000001', SOURCE_LOG_POS=1223, SOURCE_SSL=1;

slave 서버를 시작합니다.

START REPLICA USER='repl' PASSWORD='1234';

연동 확인

slave서버에서,

SHOW REPLICA STATUS \G

아래 사진처럼 나옵니다. master 서버 정보의 LOG_FILELOG_POS이 맞는지 확인합니다.

그리고
Replica_IO_Running: Yes, Replica_SQL_Running: Yes가 뜬다면 연동이 성공적으로 이루어진 것입니다.


실제로 연동이 되는지 더 확인해보겠습니다.

master 서버에서 데이터베이스를 만들어보겠습니다.

create database ward_study;

slave서버에서 확인해보면, 실제로 데이터베이스에 Table이 연동됐음을 확인할 수 있었습니다!

show databases;



참고

profile
배운 것을 기록합니다.

0개의 댓글