- Read Write Query 분리2021년 11월 28일 21시 32분 33초에 업로드 된 글입니다.작성자: jCurve728x90반응형
프로젝트를 진행하는 과정에서 MySQL DB를 replication을 진행했는데 이는 추후 서버 증설을 가정했을 때 가용성이나 다수의 서버가 한 대의 데이터베이스를 바라보는 구조에서 트래픽이 한 개의 DB에 몰릴 때 해당 DB가 죽어버리면 앞단의 모든 서버까지 다 죽을 위험이 있기 때문이다.
요청당 스레드가 서버의 cpu,메모리, db connection 등을 가지고 요청을 보내는데 뒷단에 DB가 죽었으니 time out으로 에러가 발생할때까지 대기하게 되고 이 과정에서 서버에 동시 접속자 수가 늘어나고 요청의 수가 많아지면 서버의 자원을 계속해서 잡아먹으며 무조건 실패하게될 요청을 죽은 DB로 보내게 되므로 서킷 브레이커를 붙여주거나 replication으로 다중화를 해주는게 좋다고 생각했다.
밑에 구조에서는 DB 한 대가 SPOF로 위에서 말한 상황이 발생할 수 있다.
그래서 해당 구조를 아래와 같이 바꾼 것을 이전에 진행했습니다.
이제 각 서버에서 요청별로 read , write query를 분류하여 실제 DB 요청시에 master와 slave를 선택해서 작업을 수행하면 되는데 spring에서 이 작업을 수행할 때 datesource routing을 통해 구현할 수 있습니다.
AbstractRoutingDataSource 클래스를 확장하는 RoutingDataSource 클래스 구현체를 만들고 TransactionSynchronizationManager가 트랜잭션을 사용하는 시점에 해당 트랜잭션이 read ony일 경우 slave DB로 요청을 보내고 write query일 경우 master DB로 요청을 보내게 됩니다.
이제 위에서 만든 클래스를 빈으로 등록하고 스프링에서 제공하는 LazyConnectionDataSourceProxy를 DataSource 빈으로 등록해줍니다.
이걸 등록해주는 이유는 스프링이 트랜잭션 시작시에 커넥션을 실제 사용 여부와 관계없이 커넥션을 확보하게되는데요, 이러면 어떤 DB와의 커넥션을 가져갈지 Runtime에 개발자가 결정할 수 없이 이미 가져가 버리기 때문에 LazyConnection으로 실제 사용 시점에 커넥션을 확보하게되면 앞서 등록한 RoutingDataSource로 트랜잭션의 메타 정보를 바탕으로 Master DB 와 Slave DB를 선택해서 동적으로 처리할 수 있게 해줍니다.
반응형'Spring' 카테고리의 다른 글
Spring RestDoc (0) 2022.03.12 Spring Swagger - API 문서화 (0) 2021.10.11 JPA 반복문 쿼리 vs Batch Insert (0) 2021.10.10 Spring Session Redis (0) 2021.10.09 Spring HandleMethodArgumentResolver로 반복적인 Session 연산 처리 (0) 2021.10.08 댓글