만약 Replication을 모를 경우 이 글을참고해보면 된다. (프로젝트 할때 작성한 wiki입니다.)
위의 그림같이 DB Replication을 적용했다. CRUD에 해당하는 부분에서 CUD는 소스 서버로 가고 R은 레플리카 서버로 분기하여 부하 분산을 통해 성능 향상 및 소스 DB가 장애가 나더라도 해당 서비스의 조회는 가능하도록 했습니다.
그러나 적용하고 나서 의문이 드는 부분이 있었다. 만약에 실시간으로 생성하는 로직이 있고 바로 조회하는 환경이라면 데이터의 동기화 시점 이전에 조회해서 해당 부분을 조회 못하는 문제가 발생한다는 문제였다.
이러한 문제는 어찌 해결을 해야할까?
먼저 복제 동기화 방식에 알 필요가 있다. 복제 방식에는 두 가지가 있는데 비동기 복제(Asynchronous replication)방식과 반동기 복제(Semi-synchronous replication) 방식이 존재한다.
Asynchronous replication은 소스 DB는 Transaction 수행 중 레플리카 DB로 인한 추가적인 동작을 수행하지 않는다. Replication은 Transaction과 별도로 진행된다. 따라서 소스 DB는 레플리카 DB로 인한 성능 저하가 거의 발생하지 않는다. Async 방식이기 때문에 소스 DB에서 Transaction이 완료된 DB 변경 내용이더라도 레플리카 DB에는 바로 반영되지 않는다. 이는 소스 DB의 갑작스러운 장애가 Data 손실로 이어질 수 있다는 의미이다. 레플리카 DB의 장애는 소스 DB의 Transaction에 아무런 영향을 주지 않는다.
이처럼 비동기 복제 방식일때 레플리카 DB에 바로 반영되지 않아서 문제가 발생하는거면 반동기 방식일 경우 해결되는 것일까?
Semi-synchronous Replication 과정을 나타내고 있다. Semi-synchronous Replication은 소스 DB가 레플리카 DB로부터 Relay Log 기록이 완료되었다는 ACK를 받고 Transaction을 진행하는 방식이다. 따라서 Async Replication 방식에 비해서 좀 더 많은 DB 성능 저하가 발생하지만, 소스, 레플리카 DB 사이의 동기화를 좀 더 보장해 준다. Semi-sync Replicaiton 방식에는 소스 DB가 레플리카 DB에게 DB 변경 내용을 언제 전달하냐에 따라서 AFTER_SYNC, AFTER_COMMIT 2가지 방식으로 구분된다.
위에 설명대로 라면 문제가 다 해결되는 것일까? 데이터 정합성 문제는 해결된다. 하지만 Replication을 도입한 이유를 다시 한번 생각해봐야한다.
우리가 Replication 도입한 이유는 CUD와 R을 분리와 소스 서버에 문제가 발생했을 경우 레플리카로 읽기만이라도 가능하게 만드는 것이었는데 반동기로 변경할 경우 레플리카 DB가 소스 DB에게 영향을 줄 수 있다. 이렇게 될 경우 주객전도되는 상황이 발생한다.
그렇다면 어찌해야 할까? 추구하는 바에 따라 다를 것 같아 서비스의 안정성이 더 중요하다고 생각하면 지금처럼 비동기 방식을 유지하고 다른 방법을 생각하는 게 더 좋아 보인다. 실제로 사용자가 느끼는 데이터 정합성 문제가 미비하고 이러한 데이터 정합성이 중요할 경우 다른 방식으로 풀어가는 게 더 좋을 것 같다. 예를 들어 데이터 정합성이 중요할 경우 소스 DB에서 조회하도록 하는 방법이 있을 것 같다.