> 관련 포스팅(서버 이중화)
요구사항 분석
최초에 원한 구조는 위와 같다.
클라이언트가 요청을 보내면 L4가 분산(Active-Active)시켜서 서버에 전달하는데, 이때 각 서버는 마찬가지로 이중화된 DB를 선택해서 접근할 것이다.
이때, 해당 DB는 최대한 실시간으로 연동되어 데이터 정합성을 유지할 수 있길 원한다
그렇다면 나는 mariaDB의 Replication을 어떻게 할지를 고민하면 된다.
MariaDB의 Replication 방식 고려하기
MriaDB에서 Replication 구성은 다양하다. 그 중 몇 가지만 대표적으로 보면 아래와 같다.
AP 서버가 Active-Active 이중화 구성 상태라는 것은
이러한 서버의 구성 상태를 더욱 정확히 파악해보자
- 부하 균등 분산: 트래픽이 두 서버에 균등하게 분산되고 있다
- 두 서버 모두 활성 상태: 두 서버 모두 데이터 읽기/쓰기 작업을 수행한다
이렇듯 '동시에' '쓰기' 작업이 일어날 수 있음을 유의하자.
+ Master/Master Replication
Active-Active 서버 상황에서 Master/Master 복제를 고려해보자. 양방향 복제로 두 DB가 서로의 데이터를 복제하며 최신 상태를 유지한다. 따라서 부하 분산과 동시에 지속적인 서비스가 가능할 것이다…로 끝나면 좋겠는데, 같은 시간대에 읽기/쓰기를 둘 다 해버리고 있으니 복잡한 트랜잭션이 존재할수록 데이터 충돌을 염려할 수 밖에 없다.
+ Master/Slave Replication
이번엔 Master-Slave를 생각해보자. 단순히 메인이 되는 Master DB만 활성화되고, 주기적으로 Master가 Slave로 데이터를 복제시키는 꼴이다. 두 DB가 모두 작업을 수행하는 게 아니므로 충돌 관리는 필요가 없다. 한다면 Master 서버의 장애 발생 시 Slave 서버를 활성화시키는 로직을 갖추게 해야한다.
Master/Master 구조의 DB 설정하기
나의 상황에서는 Master/Slave Replication이 맞다
하지만 경험상 Master/Master를 진행한다
1. MariaDB 설정 파일 수정
사전에 MariaDB 서버끼리 접근 가능하도록 만들어 둔 뒤 진행해야하며 이제 서버1과 서버2 각각의 config 파일에 접근하여 서버ID, 바이너리 로그, 자동증가 설정을 진행한다
경로 > /etc/my.cnf 혹은 etc/mysql/my.cnf
[mysqld]
server-id=1 # 서버의 고유 ID, 서버2은 2로
log_bin=mysql-bin # 바이너리 로그 파일 활성화, 파일 이름 접두사 설정
binlog_format=row # 바이너리 로그의 기록 형식
auto-increment-increment=2 # 테이블 내 자동 증가 값의 간격 설정
auto-increment-offset=1 # 테이블 내 자동 증가 오프셋 설정, 서버2는 2로
log_bin_trust_function_creators=1 # 사용자 정의 함수 생성 시 보안 제한 완화
[mariadb]
# 반동기식 복제 설정
rpl_semi_sync_master_enabled=ON # Master 서버에서 반동기식 복제 활성화
rpl_semi_sync_master_timeout=5000 # 반동기식 복제에서 Slave 서버 응답 시간 설정
rpl_semi_sync_master_wait_point=after_sync # 트랜잭션이 SLave 적용 이후에만 Commit 완료
rpl_semi_sync_slave_enabled=ON # slave 서버의 반동기식 복제 활성화 (확인 응답 가능)
# 복제 제외 테이블
replicate_wild_ignore_table=%__테이블명__%
각 설정값의 정보
- server-id : 복제 설정에서 각 서버를 고유하게 식별하기 위함
- log_bin: Database 변경사항을 바이너리 로그에 기록하며 변경 사항 전송 시/데이터 복구 시 이용
- binlog_format: 아래의 세 가지 기록 형식을 설정할 수 있음
- STATEMENT: 문장 기반 복제 (SQL문장 자체 로그 기록)
- ROW: 행 기반 복제 (각 개별 행의 변경 사항 로그 기록)
- MIXED: 상황에 따라 STATE와 ROW를 혼합하여 사용
- auto-increment-increment: Multi-Master 복제 환경에서 충돌을 막고자 사용
- auto-increment-offset=1: Multi-Master 복제 환경에서 각 서버가 다른 초기 값을 가지도록 설정
auto-increment에 대하여
auto-increment가 가지는 의의에 대해 짚고 넘어가자.
의도는 각 서버가 동일한 테이블에 대해 AUTO_INCREMENT 값을 생성할 때 충돌을 방지하려고 하는 설정이다. 따라서 각 Master의 시작값을 다르게 주고, 증가값은 서로 2씩 증가되므로 자동증가 값의 충돌이 막아졌다. 물론 이것이 유의미해질려면 Database 내 모든 테이블이 AUTO_INCREMENT 컬럼을 사용하는 게 옳다.
binlog_format에 대하여
- 로그 크기: STATEMENT < MIXED < ROW
- 정확성: STATEMENT < MIXED < ROW
즉, 정확성을 노린다면 ROW, 로그 크기가 걱정된다면 STATEMENT, 적절히를 원한다면 MIXED로 합의볼 수 있다
2. 복제 전용 계정 생성
# 계정 생성과 동시에 권한 부여
GRANT REPLICATION SLAVE ON *.* TO 'id'@'각_서버의_ip' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
위의 명령어로 서로가 서로의 SLAVE이자 MASTER로 임명하여 생성&권한 부여를 진행한다
3. DB 1의 최초의 Master DB 백업
./mariabackup --bakcup --target-dir={path}/backup -u root -p '{password}'
tar czvf /backup.tar {path}/backup
scp /backup.tar {DB2의 IP}:{path}
우선 DB 중 1번 DB 쪽에서 현재 데이터를 백업 시킨다
그 뒤 backup 파일을 DB 2번으로 전송시켜준다
4. DB 2번의 Master DB 복구
압축 파일을 들고 왔으니 DB2에서 적용시켜준다.
// DB 1의 데이터 복제 준비
tar xzvf {path}/backup.tar -C
./mariabackup --prepare --target-dir={path..}
// 기존 데이터는 삭제 후 복제 진행
rm -rf {path}/mariadb/data/*
./mariabackup --copy-back --target-dir={path}/backup --datadir={path}/mariadb/data --user=root --password='password'
// 필요 시 폴더 파일 권한 변경
chown -R mysql:mysql {path}/mariadb/data
// 재시작
sudo systemctl restart mariadb
5. GTID 설정 및 Replication 설정
DB1 -> DB2 Replication 설정하기
xtrabackup_binlog_info 파일을 열어보면 DB2의 GTID 정보를 확인할 수 있다
cat {path}/backup/xtracbackup_binlog_info
확인하였다면 DB1에서 MariaDB에 접속한 후 복제 설정을 구성한다
STOP SLAVE;
CHANGE MASTER TO MASTER_HOST='DB2_IP',
MASTER_USER='{user}',
MASTER_PASSWORD='{password}',
MASTER_PORT=3306,
MASTER_USE_GTID=slave_pos,
MASTER_LOG_FILE='binlog.000001', -- xtrabackup_binlog_info 파일의 내용
MASTER_LOG_POS=12345678; -- xtrabackup_binlog_info 파일의 내용
START SLAVE;
DB2 -> DB1 Replication 설정하기
이제 DB2에서도 마스터의 정보를 설정하는 복제 설정을 구성한다
// GTID 정보 확인
cat {path}/backup/xtrabackup_binlog_info
// MriaDB 접속 후 복제 섲렁
STOP SLAVE;
CHANGE MASTER TO MASTER_HOST='DB1_IP',
MASTER_USER='{user}',
MASTER_PASSWORD='{password}',
MASTER_PORT=3306,
MASTER_USE_GTID=slave_pos,
MASTER_LOG_FILE='binlog.000001', -- xtrabackup_binlog_info 파일의 내용
MASTER_LOG_POS=12345678; -- xtrabackup_binlog_info 파일의 내용
START SLAVE;
각 DB 서버에서 Replication 상태확인
SHOW SLAVE STATUS\G;
이후 Data를 임의로 insert하고 조회해보면 양쪽이 다 연동될 것을 볼 수 있다.