1. DB Replication
- 데이터베이스 이중화 방식 중 하나로 하나의 Master DB와 여러대의 Slave DB로 구성.
Master DB에 데이터의 변경이 감지되면 Master DB의 로그를 기반으로 Slave DB에 복제 합니다.
- 서비스 사용자의 증가로 트래픽이 늘어날 경우 DB에 부하가 생겨 속도 저하, time out 에러가 발생할 수 있습니다.
- Replication을 통해 select요청은 Slave DB(읽기전용)에서 처리, CUD는 Master DB에서 처리할 수 있도록 분리하여 트래픽을 분산되도록 합니다.
Spring의 @Transactional 설정에 따라 설정하는 DB가 달라지게 됩니다.
@Transactional(readOnly = true) 인 경우는 Slave DB 접근
@Transactional(readOnly = false) 인 경우에는 Master DB 접근
2. application.yml 설정
spring:
datasource:
master:
url:
driver-class-name:
username:
password:
slave:
url:
driver-class-name:
username:
password:
기본 형식은 spring.datasource.url 과 같은 형태로 진행되지만 Replication된 DB를 사용해야하므로 master, slave를 개별 설정합니다. (커스텀한다고 생각...)
3.datasource bean 등록
@Configuration
public class DatabaseConfig {
@Primary
@Bean(name = "masterDataSource")
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "slaveDataSource")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource() {
return DataSourceBuilder.create().build();
}
}
@ConfigurationProperties를 통해 yml에 지정한 설정을 입력하여 DataSource를 생성합니다.
@Primary는 같은 bean이 여러개일 경우 우선적으로 등록될 bean을 설정한다고 합니다.
4. AbstractRoutingDataSource 구현
public class ReplicationRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
boolean isReadOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly();
if(isReadOnly) {
return "slave";
} else {
return "master";
}
}
AbstractRoutingDataSource는 key 기반으로 등록된 Datasource 중 하나를 호출을 하게 해줍니다.
이를 상속받아 determineCurrentLookupKey() 을 오버라이드하여 어떤 ContextHolder를 통해서 값을 매칭시킬지 구현하면 됩니다.
5. AbstractRoutingDataSource Bean 등록
@Configuration
public class DatabaseConfig {
...
@Bean(name = "routingDataSource")
public DataSource routingDataSource(@Qualifier("masterDataSource") DataSource masterDataSource, @Qualifier("slaveDataSource") DataSource slaveDataSource) {
ReplicationRoutingDataSource routingDataSource = new ReplicationRoutingDataSource();
Map<Object, Object> dataSourceMap = new HashMap<>();
dataSourceMap.put("master", masterDataSource);
dataSourceMap.put("slave", slaveDataSource);
routingDataSource.setTargetDataSources(dataSourceMap);
routingDataSource.setDefaultTargetDataSource(masterDataSource);
return routingDataSource;
}
}
위의 AbstractRoutingDataSource를 상속받아 구현한 메소드를 Bean으로 생성합니다.
Replication의 장단점
장점
- 성능향상 효과가 있습니다. (read와 write를 분리하여 부하를 줄여줍니다)
- master DB에 오류가 발생했을 경우, 분리하여 slave 기준으로 복구할 수 있습니다.(스냅샷으로 복구 가능하나, slave 기준으로 복구시 정합성이 더 높음)
단점
- 쓰기지연에 따라 master와 slave 데이터가 정확히 일치하지 않을 수 있습니다.
- master DB 오류 발생시, fail over하여 slave DB를 사용할 수 없습니다.
데이터 정합성을 향상시키기 위해
지연 쿼리의 성능을 향상, 데이터 분리, 하드웨어 scale up을 시킬수 있으며 select더라도 실시간으로 제공해야하는 data의 경우는 master를 활용하도록 처리합니다.
참조 블로그
aws DB replication 관련
'IT > Spring' 카테고리의 다른 글
Spring Profile 설정법 (0) | 2022.01.07 |
---|---|
Springboot에서 h2 Database 설정 (399) | 2021.12.10 |
Spring Security 기본 API, filter (0) | 2021.07.08 |
XML to JSON 변환하기 (java) (386) | 2021.06.08 |
Spring Boot 프로젝트 만들기 (with. 이클립스 Maven) (441) | 2018.06.07 |
댓글