Database를 Master/Slave 구성해야 하는 이유, Application에서는 어떻게 활용해야하는지에 관하여 정리해보려 한다.
Database Replication의 동작원리나 Database의 구성형태에 대해서는 다루지 않는다. (사실 잘 모른다.)
- 왜 Database를 Master/Slave로 나누었을까?
- Application에서는 Master/Slave DB을 활용하기 위해 어떻게 구현을 했으며 어떤 고민들이 있었을까?
Master Database만 구성하였을 때의 한계점
나의 첫번째 회사는 B2B서비스를 제공하는 회사였다. 그러다보니 시스템 사용자수는 한정되어(국내/해외 법인)있었고 트래픽이 증가할일이 거의 없었다.
그렇기 때문에 Application 구성도가 굉장히 단순했다. (극단적으로 단순하게 그려봄)
위와 같이 하나의 서버와 하나의 Database로 구성되어있었고 하나의 Database에서 CRUD 작업을 모두 수행했던걸로 기억한다. 하지만 본능적으로 느껴질 것이다. 위험해보인다..
만약 여기서 트래픽이 폭발적으로 증가하게되면 어떻게 될까? 아무리 Database서버가 고성능이라 하더라도 웹 서버로부터 오는 모든 트래픽을 견뎌내기란 불가능하다.
- 트래픽으로 인해 데이터베이스장애 발생확률이 높아지고 그로인하여 운영중인 애플리케이션에 바로 타격이 갈 수 있다. ->
가용성의 문제
- 트래픽으로 인해 쿼리 수행(수행시간이 비교적 긴 쿼리/쓰기 작업)빈도가 높아지면 작업 병목이 발생할 수 있다. ->
부하분산의 문제
- 애플리케이션단에서는 DB Connection을 얻기위해 대기하다가 TimeOut 발생
이러한 이유들로 아래와 같이 Master DB를 복제(Replication)한 Slave DB를 하나더 구성하게 되는 것이다.
안 궁금하겠지만 내 두번째, 세번째(현재) 회사는 모두 이런식으로 DB를 제공해주고 있다.
- Master DB에서 복제하는 기법은 여러개 존재함.
기억해야할 점은 Slave DB는 Master DB를 복제하여 만들어지기 때문에 약간의 복제지연(gap)이 생길 수 있다는 것이다. 대부분 1초 이내라고 생각하면 된다. (가끔 초과하는 경우도 존재)
Replication을 구성하였을 때의 장점
1. 가용성이 높아진다.
Master DB가 장애로 죽을 경우, 슬레이브 서버를 마스터로 승격시켜 서비스를 빠르게 복구할 수 있다.
2. 부하분산이 가능하다.
Master DB에서는 WRITE(Insert, Update, Delete)
작업을 Slave DB에서는 READ(Select)
작업을 처리하게하여 부하를 분산시킬 수 있다.
인덱스가 걸려있는 테이블의 WRITE 작업은 READ 작업보다 상대적으로 더 많은 시간이 걸릴 뿐더라, 웹 서비스는 일반적으로 WRITE 보다 READ의 작업비중이 높다. 그렇기 때문에 WRITE/READ를 분리하여 처리하게된다면 부하를 분산시키는데 효과만점이다.
-> Slave DB는 보통 ReadOnly 설정을 해두는 것이 일반적이다.
Application에서 Master/Slave DB를 활용하기위한 고민
Replication DB의 필요성을 깨달았고 DBA님이 Master/Slave DB를 구성해준 상태라고 생각해보자.
흠 기존 애플리케이션을 어떻게 변경하지? 처음 이 문제를 맞닥뜨렸을 때 나는 단순히 이렇게 생각을 했다.
아!! SQL 수행 단위로 나눠야 겠다. Insert/Update/Delete 쿼리는 Master DB에서 실행을 Select 쿼리는 Slave DB에서 실행을 하면 되지 않을까?? 음 근데 그렇다면 한 트랜잭션내에서 여러 DataSource에 접근해서 쿼리를 실행해도 문제가 없을까?
뚜둔 결론은 불가능하다. 위에서 Slave DB의 복제지연(gap)에 대해 언급했다. SQL 단위로 Master/Slave DB로 붙게한다면 아래와 같은 문제점이 발생할 수 있다.
- 트랜잭션 범위 지정에 대한 문제(한 트랜잭션안에서 각기 다른 DataSource를 사용할 때의 문제)
- 한 트랜잭션내에서의 Insert 후 Select 수행한다면 Master DB에 commit이 되지 않은 상태이기 때문에 Slave DB에는 데이터가 존재하지 않는다.
- 다중 DataSource를 하나의 트랜잭션으로 만들 수 있는 기법이 존재하는 것 같긴한데.. 굳이?란 생각으로 찾아보지는 않음
- 복제지연의 문제
- Update 직 후 동일 row를 Select 하였을 때, 노드 복제 지연으로 인하여 오래된 데이터가 읽힐 수 있다.
정리하자면 단순히 Insert/Update/Delete, Select 문으로 사용할 DB를 선택하게되면 문제가 있을 수 있다. 따라서 대용량 범위 단순 Select/데이터 추출같은 경우에만 Slave DB를 이용할 수 있게 해야한다.
그렇다면 이제 구현하는 방법만 남았다. 나는 Spring에서 제공해주는 AbstractRoutingDataSource를 이용하여 DataSource Routing을 구현하였는데 이 방법을 사용하기로한 이유에 대해서는 다음 포스팅에서 정리하도록 하겠다.
2022.04.03 - [프로그래밍 노트/SPRING] - Master/Slave DB 라우팅/이용하기(feat. AbstractRoutingDataSource)
'데이터베이스 노트 > 데이터베이스' 카테고리의 다른 글
DBMS와 실행 계획_2 (0) | 2018.10.23 |
---|---|
DBMS와 실행 계획_1 (0) | 2018.10.23 |
DBMS와 버퍼 (0) | 2018.10.05 |
DBMS 아키텍처 (0) | 2018.10.05 |
SQL 튜닝 (조인방법) (0) | 2018.08.22 |