개발

Mac에서 docker-compose로 maria replication (master slave) 설정하기

escser 2023. 4. 10. 01:25

DB 이중화 작업을 해야하는 이유는 하나, 안전성이다.

트래픽에 따라 늘어나는 부하를 줄이기 위해 역할을 분리해준다.

master: 쓰기/수정/삭제

slave: 읽기 처리

 

Mysql 의 Replication은 비동기 복제 방식을 사용하고 있다.

간단히 말해 master에서 변경사항을 기록한 Binary Log를 비동기적으로 Slave에 전송

 

[master] 변경사항 (Binary Log) 을 slave에 비동기적 전송

[slave] Relay Log에 기록

[slave] Apply

(동작원리 : http://cloudrain21.com/mysql-replication)

 

도커로 mysql 서버 replication 설정하기

아주아주 심플 주의

 

도커 설정을 저장할 폴더를 만든다.

거기에 파일 네 개를 작성(docker 설정, master, slave 설정, 실행파일)

 

docker-cmopose.yml

코드만 (더보기)

더보기

version: "3.3"

services:
  db_master:
    image: mariadb:10.6.3-focal
    container_name: db_master
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mariadb_root_password
    ports:
      - "3306:3306"
    secrets:
      - mariadb_root_password

  db_slave:
    image: mariadb:10.6.3-focal
    container_name: db_slave
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mariadb_root_password
    ports:
      - "3307:3306"
    depends_on:
      - db_master
    secrets:
      - mariadb_root_password

secrets:
  mariadb_root_password:
    file: ./mariadb_root_password.txt

 

# mariadb image 를 통해서 master-slave db container를 생성합니다.
version: "3.3"

services:
  db_master:
    image: mariadb:10.6.3-focal
    container_name: db_master
    # 컨테이너가 다운됐을 때 설정
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mariadb_root_password
    ports:
      - "3306:3306"
    secrets:
      - mariadb_root_password
    # 컨테이너에서 사용하는 볼륨 설정
    # volumes:
    #   - ./master/data:/var/lib/mysql
    #   - ./master/config/:/etc/mysql/conf.d
    #   - ./master/mysql-init-files/:/docker-entrypoint-initdb.d/

  db_slave:
    image: mariadb:10.6.3-focal
    container_name: db_slave
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/mariadb_root_password
    # "" 필수. 없는경우 시간으로 판단 
    ports:
      - "3307:3306"
    depends_on:
      - db_master
    secrets:
      - mariadb_root_password
    # volumes:
    #   - ./slave/data:/var/lib/mysql
    #   - ./slave/config/:/etc/mysql/conf.d
    #   - ./slave/mysql-init-files/:/docker-entrypoint-initdb.d/

secrets:
  mariadb_root_password:
    file: ./mariadb_root_password.txt

 

enviroment 자체를 파일로 사용할 수 있다.

env_file 옵션

env_file:
 - ./mysql_env.txt
 
 
 # ./mysql_env.txt
 MYSQL_ROOT_PASSWORD=1234
 MYSQL_DATABASE=test_db

 

[MASTER]

$ docker exec -it db_master bash

# apt update; apt install vim -y;

# vi /etc/mysql/my.cnf

 

[mysqld]

log-bin = mysql-bin 
server-id = 1 
binlog_format = row 
expire_logs_days = 2

저장

# exit

$ docker restart db_master

$ docker exec -it db_master bash

# mysql -u root -p

grant replication slave on *.* to 'repl_user'@'%' identified by 'p@ssw0rd';
show master status;

 

 

[SALVE]

$ docker exec -it db_master bash

# apt update; apt install vim -y;

# vi /etc/mysql/my.cnf

[mysqld]

log-bin = mysql-bin
server-id = 2
binlog_format = row
expire_logs_days = 2

read_only = 1

저장

# exit

$ docker restart db-slave

 

 

* 마스터 서버 접근 정보 설정

[SLAVE]

$ docker exec -it db_salve bash

# mysql -u root -p

CHANGE MASTER TO MASTER_HOST = '172.24.0.2'
    , MASTER_PORT=3306
    , MASTER_USER='repl_user'
    , MASTER_PASSWORD='p@ssw0rd'
    , MASTER_LOG_FILE='mysql-bin.000001'  
    , MASTER_LOG_POS=523
    , MASTER_CONNECT_RETRY=10;

MASTER_HOST, _PORT: master 컨테이너의 ip, port

MASTER_USER, _PASSWORD: master mysql 에서 만든 계정정보

MASTER_LOG_FILE, _POS: master mysql의 상태정보

 

start slave;

아까 docker-compose 를 백그라운드로 안 돌리고 로그를 볼 수 있다면 

마운트된 로그가 찍힌다.

show slave status;

 

* TEST

[MASTER] 데이터 생성

create database db_test;
use db_test;

-- db_test.users definition

CREATE TABLE `users` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` char(10) DEFAULT NULL,
  `created_at` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

insert into users (name) value ('sample')
;
insert into users (name) value ('sample2')
;

select * from users;

[SLAVE]

master에서 생성한 정보를 확인할 수 있다.

show databases;
use db_test;
show tables;

select * from users;

 

 

 

 

참고

https://onethejay.tistory.com/m/182

https://waytothem.com/blog/181/