본문 바로가기
개발 관련 강의 정리/10분 테코톡

[10분 테코톡] 앤지의 DB Replication 정리

by 코딩개발 2023. 5. 14.
728x90
반응형

목표
- DB Replication에 대해 이해한다.
- DB Replication과정에 대해 이해한다
- DB Replication topology에 대해 이해한다.
- 복제 과정 중 문제 발생 시 회복기법에 대한 이해를 한다.

*MySQL 8.0버전, lnnoDB 기준

 

 

데이터베이스 레플리케이션

- 데이터베이스를 복제하는 행위

 

 

왜 여러 개의 데이터베이스를 두는 걸까?
Case 1
사용자가 요청을 보냈는데 데이터베이스가 응답하지 않고 재가동도 되지 않는 상황

 

Case 2

서비스의 사용자가 늘어 데이터베이스 요청 트래픽이 증가한 상황
이 경우 데이터베이스를 스케일업 한다면 요청을 받을 수 있지만 스케일업에도 한계있다.

 

이러한 상황들을 해결하기 위해 데이터베이스 레플리케이션이 등장한다.

데이터베이스 레플리케이션 구조에서 원본 데이터를 가진 데이터베이스 서버를 소스서버, 복제된 데이터를 가지고 있는 데이터베이스 서버를 레플리카 서버라고 한다. 소스 서버에서 데이터에 변경이 일어나면 변경된 내용이 레플리카 서버 에도 동일하게 반영된다. 이러한 구조를 소스-레플리카 구조라고 한다.

앞서 본 Case 1의 경우 소스서버에 문제가 생기면 레플리카 서버를 소스서버로 승격시켜 사용할 수 있다.

 

Case 2의 경우 소스 서버를 Write DB로 레플리카 서버를 읽기전용인 Read DB로 사용해 부하를 해결할 수 있다.

 

소스서버의 어느 데이터를 기반으로 복제는 바이너리 로그를 기반으로 복제가 일어난다.

* 바이너리 로그 : 모든 변경사항이 로그파일에 순서대로 기록되는 것을 의미


즉 소스서버에 변경이 일어나서 바이너리 로그 이벤트가 기록이 되면 이벤트는 레플리카 서버가 자신의 로컬 디스크에 저장을 한 뒤 이벤트를 읽어 자신의 데이터 파일에 반영한다.

 

 

자세히 알아보자면 이 복제에 쓰레드는 총 세 가지 쓰레드가 사용되고 있다. 먼저 소스서버에 바이너리 로그의 이벤트가 변경이 일어나면 바이너리 로그 덤프 쓰레드가 이 이벤트를 읽어 레플리카 서버로 전송한다. 레플리카 서버의 I/O 쓰레드는 이 변경 이벤트를 자신의 로컬파일인 릴레이 로그에 저장한다. 아직 데이터의 변경이 레플리카 서버에는 반영되지 않았다.반영하기 위해 SQL 쓰레드가 변경 내용을 데이터 파일에 저장한다.

 

 

레플리카 서버는 소스 서버의 바이너리 로그이벤트를 어떻게 식별하여 반영할까?


두 가지 방식이 있다.

 

1) 바이너리 로그파일 위치기만 복제 방식

 


소스서버 바이너리 로그의 로그 파일명과 오프셋을 이용해 식별 한다.

 

 

하지만 이 방식은 소스 서버에서만 유용한 식별 방법 이라는 단점이 있다.
소스서버에 문제가 생겨 다른 레플리카 서버가 소스서버로 승격된 경우 복제에 참여하는 다른 데이터베이스 서버들은 이 위치를 다시 찾아야 하기 때문에 복구에 시간이 걸린다. 즉 동일한 이벤트가 레플리카 서버 에서도 동일한 파일은 동일한 위치에 저장된다는 보장이 없다는 단점이 있다.

 

 

2) 글로벌 트랜잭션 아이디 기반 복제


그래서 MySQL 5.6 버전부터는 그런 글로벌 트랜잭션 아이디 기반 복제를 기본 복제 방식으로 사용하고 있다.

 

 

 


글로벌 트랜잭션 아이디는 복제에 참여한 모든 데이터베이스들이 고유한 식별값을 가지고 있다. 이 값들은 모두 동일하기 때문에 동일한 이벤트에 대해서 동일한 글로벌 트랜잭션만 읽어보면 반영할 수 있다.

 

 

바이너리 로그의 포맷은 어떻게 되어 있을까?
1) Statement 기반 방식

2) Row 기반 방식

3) Mixed 기반 방식

 

 

Statement 기반 방식

위와 같이 실행된 SQL 문이 바이너리 로그에 그대로 저장되어 있는 방식이다.

 

장점

- 여러 개의 데이터를 수정하는 쿼리에도 바이너리 로그의 SQL문 딱 하나만 저장되기 때문에 저장 공간에 대한 부담 감소

-  빠른 처리가 가능

 

단점
- 실행할 때마다 결과값이 달라지는 비확정적 쿼리의 경우 데이터 동기화 문제 발생

- 하나의 특랜잭션 내에서도 각 쿼리가 실행되는 시점마다 데이터 스냇샷이 달라질 수 있음

- 트랜잭션 격리수준이 REPEATABLE-READ 이상만 사용이 가능

즉 일관되지 않은 데이터가 저장될 위험 존재

 

 

Row기반 현식

MySQL 5.7.7 버전부터는 Row기반 바이너리 로그 포맷을 기본으로 사용한다.

이 방식은 변경 값 자체가 바이너리 로그에 그대로 저장되어있는 형식이다.

 

장점

- 모든 트랜잭션 격리 수준에서 사용 가능

 

단점
- 데이터를 많이 변경하는 SQL문이 실행될 경우 바이너리 로그 파일의 크기가 커질 수 있음

  용량 최적화 방식 지원, 바이너리 로그 Row 이미지, 바이너리 로그 트랜잭션 압축

- 어떤 쿼리들이 넘어왔는지 육안으로 확인 불가능
그럼에도 불구하고 이와 같은 방식은 데이터를 일관되게 저장하는 가장 안전한 방식이다.

 

 

Mixed 방식

사용자가 커스텀하여 사용할 수 있다.

기본적으로 쿼리는 Statement 포맷으로 저장하되 비확정적 쿼리라면 Row 포맷으로 저장하는 방식을 사용할 수 있다.
소스 서버로부터 레플리카 서버 까지 복제가 잘 일어났는지 어떻게 확인할 수 있을까?

 

 

3-1) 비동기 복제
- 소스 서버가 레플리카 서버에서 변경 이벤트가 정상적으로 전달 됐는지 확인하지 않는다.

 

비동기복제 방식은 데이터 변경 요청이 들어왔을 때 바이너리 로그의 이벤트를 먼저 작성한 후, 바로 소스 서버에 스토리지 엔진에 커밋을 하게 된다. 그 이후에 변경 이벤트를 레플리카 서버로 전송한다. 이 방식의 경우 변경 이벤트를 레플리카 서버로부터 소스 서버로 확인 이벤트를 보내지 않는다. 그래서 성능은 빠르지만 동기화는 보장하지 않는다는 단점이 있다.

 

 

3-2) 반동기 복제

- 소스 서버는 레플리카 서버가 소스 서버로부터 전달 받은 변경 이벤트를 릴레이 로그에 기록 후 응답을 보내면 그때 트랜잭션을 완전히 커밋한다.

MySQL 5.5 버전부터는 반동기 복제 방식을 사용한다. 이 경우 데이터변경 요청이 소스 서버로 들어오면 바로 이벤트를 바이너리 로그에 기록한 후 변경 이벤트를 레플리카 서버로 전송한다. 레플리카 서버는 이 변경 이벤트를 잘 받았다는 응답을 보내게 되고 이 응답이 오고 난 이후에 소스서버는 변경 내역을 스토리지 엔진에 커밋한다. 이 방식에서 레플리카 서버가 보내는 응답은 변경 이벤트를 잘 받았다는 응답이지 이벤트가 레플리카 서버에 적용되었다는 응답을 보내는 것은 아니다.

 

 

소스서버와 레플리카 서버를 어떻게 구성할 수 있을까?

 


1) 싱글 레플리카

- 기본 형태이며 예비 서버 및 데이터 백업용으로 활용

 

 

소스서버 한대와 레플리카 서버를 한대 두는 싱글 레플리카 방식이 있다.
레플리카 서버는 예비 서버 및 데이터 백업 용으로 활용하고 있다.

 

 

2) 멀티 레플리카

- 싱글 레플리카 구조 + 레플리카 서버

- 레플리카1 : 쿼리 부하 분산 / 레플리카2 : 백업용


싱글 레플리카 구조에 레플리카 서버를 한대 더 둔 방식이다. 레플리카를 두 대 사용하는데 레플리카 첫번째는 쿼리 부하 분산용으로 두 번째 레플리카 서버는 백업 용으로 사용할 수 있다.

 

 

3) 체인 복제 형식

- 소스 서버의 복제 부하가 커진다면 고려

- MySQL 서버 업데이트 혹은 장비 교체 때 사용

 


이 경우 소스서버에 연결된 레플리카 서버가 많다면 소스 서버에 복제부하가 커지게 된다. 이런 경우 다른 레플리카 서버를 소스 서버로 활용해 복제 부하를 분산시키는데 사용할 수 있다. 또한 서버 업데이트 혹은 장비 교체 때도 이러한 체인 복제 구성을 사용할 수 있다.(파란색 : 옛날 서버, 빨간색 : New 서버)

 


4) 듀얼 소스 복제

- 두 서버 모두 쓰기 가능

- 서로 동일한 데이터

- 트랜잭션 충돌 -> 롤백, 복제 멈춤 현상

두 서버 모두 쓰기가 가능한 형태이고 서로 동일한 형태의 데이터를 가지고 있으며 트랜잭션 충돌이 일어날 경우 복제 멈춘 현상이 일어나기 때문에 잘 사용되지 않는 토폴로지이다.

 

 

5) 멀티 소스 복제 방식

- 하나의 레플리카 서버가 둘 이상의 소스서버를 가짐

- 데이터 분석 시 데이터를 모아 분석을 수행할 때 사용

레플리카 서버 한대에 소스 서버가 여러대 연결된 형태이다. 이같은 경우 소스서버에 흩어져 있는 데이터들을 한데 모아 데이터를 분석할 때 사용할 수 있다.

 


그렇다면 레플리카 서버가 소스서버에 데이터를 복제할 때 문제가 생긴다면 어떻게 다시 동기화를 이뤄낼까?
이런 경우 세이프 복제라는 방식을 제공하고 있다.

 

레플리카 서버는 I/O 쓰레드와 SQL 쓰레드를 이용하여 소스 서버에 바이너리 로그 이벤트 위치를 읽을 때와 트랜잭션 실행정보를 읽을 때 어디까지 읽었는지에 대한 포지션 정보를 로컬에 저장해 두게 된다. 그 다음 레플리카 서버에 문제가 생겨 다시 재가동했을 때 그 정보를 기반으로 다시 소스서버에 동기화를 이뤄낸다.

 

 

MySQL은 다양한 복제고급 설정을 제공하고 있다.

- 지연된 복제

- 멀티 스레드 복제

- 크레시 스레드 복제

- 필터링된 복제


참고

https://www.youtube.com/watch?v=NPVJQz_YF2A&ab_channel=%EC%9A%B0%EC%95%84%ED%95%9C%ED%85%8C%ED%81%AC 

728x90
반응형

댓글