Master-Slave Replication 이란
MySQL Master-Slave Replication 은 데이터베이스의 한 인스턴스에서 다른 인스턴스로 데이터베이스를 복제하는 하나의 방식이다.
Master-Slave Replication 을 통해 3가지의 이점을 얻을 수 있다.
- 데이터의 일관성을 유지
- 데이터 백업
- 시스템의 부하 분산
Amazon RDS, Google Cloud SQL, Azure Database for MySQL 등에서도 이러한 기능을 제공해주고 있다.
Docker & Docker Compose 이란
Docker와 Docker Compose는 이러한 Replication 를 설정하고 관리하는 데 사용할 수 있는 오케스트레이션 도구이다.
MySQL Master-Slave Replication with Docker
이러한 조합으로 단일 마스터 서버로 사용되던 것을 간단하게 Slave 서버를 만들 수 있으며 master/slave 별로
.env, my.conf 필요하다.
version: "3"
services:
mysql-master:
image: mysql:latest
container_name: mysql-master
restart: always
env_file: ./master/.env.master
cap_add:
- all
volumes:
- ./master/data:/var/lib/mysql
- ./master/my.cnf:/etc/my.cnf
environment:
- MYSQL_USER:${MYSQL_USER}
- MYSQL_PASSWORD:${MYSQL_PASSWORD}
- MYSQL_ROOT_PASSWORD:${MYSQL_PASSWORD}
mysql-slave:
image: mysql:latest
container_name: mysql-slave
restart: always
env_file: ./slave/.env.slave
cap_add:
- all
volumes:
- ./slave/data:/var/lib/mysql
- ./slave/my.cnf:/etc/my.cnf
environment:
- MYSQL_USER:${MYSQL_USER}
- MYSQL_PASSWORD:${MYSQL_PASSWORD}
- MYSQL_ROOT_PASSWORD:${MYSQL_ROOT_PASSWORD}
필요한 폴더 및 env
mkdir master && mkdir slave
touch master/.env.master && touch slave/.env.slave
cat <<EOF >> ~/master/.env.master
MYSQL_USER=admin
MYSQL_PASSWORD=password
MYSQL_PORT=3306
MYSQL_ROOT_PASSWORD=password
EOF
cat <<EOF >> ~/master/.env.slave
MYSQL_USER=admin
MYSQL_PASSWORD=password
MYSQL_PORT=3306
MYSQL_ROOT_PASSWORD=password
EOF
my.conf 파일은 길어서 접었다.
maser/my.conf
[mysqladmin]
user=admin
[mysqld]
skip_name_resolve
explicit_defaults_for_timestamp
basedir=/opt/bitnami/mysql
port=3306
tmpdir=/opt/bitnami/mysql/tmp
socket=/opt/bitnami/mysql/tmp/mysql.sock
pid_file=/opt/bitnami/mysql/tmp/mysqld.pid
max_allowed_packet=16M
bind_address=0.0.0.0
log_error=/opt/bitnami/mysql/logs/mysqld.log
character_set_server=utf8
collation_server=utf8_general_ci
plugin_dir=/opt/bitnami/mysql/lib/plugin
server-id=1
binlog_format=ROW
log-bin
[client]
port=3306
socket=/opt/bitnami/mysql/tmp/mysql.sock
default_character_set=UTF8
plugin_dir=/opt/bitnami/mysql/lib/plugin
[manager]
port=3306
socket=/opt/bitnami/mysql/tmp/mysql.sock
pid_file=/opt/bitnami/mysql/tmp/mysqld.pid
!include /opt/bitnami/mysql/conf/bitnami/my_custom.cnf
slave/my.conf
[mysqladmin]
user=admin
[mysqld]
skip_name_resolve
explicit_defaults_for_timestamp
basedir=/opt/bitnami/mysql
port=3306
tmpdir=/opt/bitnami/mysql/tmp
socket=/opt/bitnami/mysql/tmp/mysql.sock
pid_file=/opt/bitnami/mysql/tmp/mysqld.pid
max_allowed_packet=16M
bind_address=0.0.0.0
log_error=/opt/bitnami/mysql/logs/mysqld.log
character_set_server=utf8
collation_server=utf8_general_ci
plugin_dir=/opt/bitnami/mysql/lib/plugin
server-id=2
binlog_format=ROW
log-bin
[client]
port=3306
socket=/opt/bitnami/mysql/tmp/mysql.sock
default_character_set=UTF8
plugin_dir=/opt/bitnami/mysql/lib/plugin
[manager]
port=3306
socket=/opt/bitnami/mysql/tmp/mysql.sock
pid_file=/opt/bitnami/mysql/tmp/mysqld.pid
!include /opt/bitnami/mysql/conf/bitnami/my_custom.cnf
이제 docker-compose 을 실행할 준비를 완료 했으면 MySQL 에 접속하여 계정 생성 및 리플리케이션 설정 작업을 해야한다.
$ docker exec -it mysql-master mysql -u root -p
mysql> CREATE USER 'replication'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%';
mysql> SHOW MASTER STATUS\G
```
File : ~~.bin.0003 -- slave 에서 replication 등록할 때 필요하다.
Postion : 300 -- MASTER_LOG_POS 이다.
...
```
$ docker exec -it mysql-slave mysql -u root -p
mysql> CHANGE MASTER TO
MASTER_HOST='mysql-master', -- docker host
MASTER_USER='replication',
MASTER_PASSWORD='password',
MASTER_LOG_FILE='~~.bin.0003',
MASTER_LOG_POS=300; --
mysql> START SLAVE;
mysql> SHOW SLAVE STATUS\G
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
...
회고
여러 사이드프로젝트에서 사용할 MySQL 데이터베이스를 적은 리소스로 좋은 효율을 내기 위해 Master-Slave Replication 작업을 하게 되었다.
이러한 작업을 수동으로 해야한다는 것이 아쉬웠지만 쉘스크립트를 이용하면 자동화 할 수 있겠다라는 생각이 든다.
하지만 프러덕션 레벨에서는 자동화하여 나도 모르는 Master-Slave 생성하기 보단 보수적인 관점으로 최대한 수동으로 작업을 진행해야 할 것 같다. 혹은 더 많은 비용을 지불해서라도 Amazon RDS, Google Cloud SQL, Azure Database for MySQL 을 이용하는 것이 좋겠다. 인스턴스 비용이 2배로 나가겠지만 관리 포인트가 줄어든다는 점에서는 좋은 방향인 것 같다.
하지만 이러한 방법으로 Master-Slave 을 관리할 경우의 이점도 좋다고 느낀다.
- 인스턴스 확장
- 업데이트 및 롤백
- 격리
- 단일 호스트에 설치가 가능하다는 점 (하지만 장애 대응을 위해서라면 다른 리전에 하는게 맞다.)
Host 1 — Host 2
master A 3306 — slave A 3306
master A 3307 — slave B 3307
master A 3308 — slave B 3308
'Database > RDBMS' 카테고리의 다른 글
데이터베이스 인덱스(클러스터드, 세컨더리, 커버링) (0) | 2024.04.18 |
---|---|
MySQL 로그 종류 알아보기 (0) | 2024.03.02 |
MySQL CDC Replication with Kafka (0) | 2024.02.14 |
DB 동시성 문제를 해결하는 방법 (이벤트 처리, 콘서트 예매 등) (0) | 2024.02.09 |
[MySQL 8 접속 에러] - caching_sha2_password (0) | 2024.02.09 |