참고한 블로그
MySQL RDS 읽기전용 replica 적용
간단한 읽기 전용 replica
velog.io
DB 생성부분은 빼고 Spring 적용부분부터 진행
Spring 프로젝트에 적용
DataSourceConfiguration
@Slf4j
@Configuration
public class DataSourceConfiguration {
private static final String MASTER_SERVER = "MASTER"; // 마스터 서버를 나타내는 상수 문자열입니다.
private static final String REPLICA_SERVER = "REPLICA"; // 복제 서버를 나타내는 상수 문자열입니다.
@Bean
@Qualifier(MASTER_SERVER)
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
// 'spring.datasource.master'로 시작하는 구성 속성을 사용하여 DataSource를 작성합니다.
return DataSourceBuilder.create()
.build();
}
@Bean
@Qualifier(REPLICA_SERVER)
@ConfigurationProperties(prefix = "spring.datasource.replica")
public DataSource replicaDataSource() {
// 'spring.datasource.replica'로 시작하는 구성 속성을 사용하여 DataSource를 작성합니다.
return DataSourceBuilder.create()
.build();
}
@Bean
public DataSource routingDataSource(
@Qualifier(MASTER_SERVER) DataSource masterDataSource,
@Qualifier(REPLICA_SERVER) DataSource replicaDataSource
) {
// 사용자 정의 RoutingDataSource 인스턴스를 생성합니다.
RoutingDataSource routingDataSource = new RoutingDataSource();
// 데이터 소스를 보관할 맵을 생성합니다.
HashMap<Object, Object> dataSourceMap = new HashMap<>();
// "master" 키로 마스터 DataSource를 맵에 넣습니다.
dataSourceMap.put("master", masterDataSource);
// "replica" 키로 복제 DataSource를 맵에 넣습니다.
dataSourceMap.put("replica", replicaDataSource);
// 라우팅을 위한 대상 데이터 소스를 설정합니다.
routingDataSource.setTargetDataSources(dataSourceMap);
// 기본 대상 데이터 소스를 마스터 DataSource로 설정합니다.
routingDataSource.setDefaultTargetDataSource(masterDataSource);
// routingDataSource를 반환합니다.
return routingDataSource;
}
@Bean
@Primary
public DataSource dataSource() {
// 라우팅 로직을 기반으로 적절한 DataSource를 결정합니다.
DataSource determinedDataSource = routingDataSource(masterDataSource(), replicaDataSource());
// 지연 연결 DataSource 프록시를 반환합니다.
return new LazyConnectionDataSourceProxy(determinedDataSource);
}
}
RoutingDataSource
@Slf4j
public class RoutingDataSource extends AbstractRoutingDataSource {
@Nullable
@Override
protected Object determineCurrentLookupKey() {
String lookupKey = TransactionSynchronizationManager.isCurrentTransactionReadOnly() ? "replica" : "master";
log.info("Current DataSource is {}", lookupKey);
return lookupKey;
}
}
위 DataSourceConfiguration 에서 만든 RoutingDataSource를 정의하는 클래스
AbstractRoutingDataSource 를 추상화하고 있다
isCurrentTransactionReadOnly 이 메서드로 트랜젝션이 readOnly=true일 때는 replica를 반환
application.properties
메소드에 적용하기
메소드에 적용 전
메소드 적용 전에 실행하면 Current DataSource is master 라고 나온다
메소드에 적용 후
값을 읽어오는 서비스에
@Transactional(readOnly = true) 애노테이션을 적용시켰다
적용시킨 후에는
Current DataSource is replica 라고 출력이 된다
MySQL RDS 읽기 전용 복제를 설정하면 좋은 점
읽기 부하 분산
데이터베이스에 정보를 요청하는 일을 복제 데이터베이스가 나눠서 처리함으로써, 주 데이터베이스에 가해지는 부담을 줄일 수 있다. 이렇게하면 주 데이터베이스가 다른 중요한 일에 더 집중할 수 있다
가용성 향상
만약 주 데이터베이스에 문제가 생기더라도 읽기 전용의 복제 데이터베이스가 데이터를 제공할 수 있다
읽기 성능 향상
데이터를 요청하는 일을 복제 데이터베이스가 처리하게 함으로써, 더 빠르게 처리할 수 있다
백업 및 복구 용이성
데이터베이스 복제본을 만들어두면, 주 데이터베이스에 문제가 생겼을 때 빠르게 원래대로 복구할 수 있다
'프로젝트' 카테고리의 다른 글
파이널 프로젝트_Caffeine Cache(로컬 캐시) 적용하기 (0) | 2024.05.14 |
---|---|
파이널 프로젝트_ShedLock을 이용한 스케쥴 중복실행 방지 (0) | 2024.05.09 |
파이널 프로젝트_Chart.Js를 활용한 대시보드 (0) | 2024.05.01 |
파이널 프로젝트_ @Scheduler를 활용한 통계 저장 기능 (0) | 2024.05.01 |
파이널 프로젝트_로그인, 로그아웃(Spring Boot, Session ) (0) | 2024.04.20 |