본문 바로가기
IT/Spring

DB Replication에 따른 Spring 설정

by eddie_factory 2021. 12. 10.
반응형

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를 활용하도록 처리합니다.

 

참조 블로그

https://k3068.tistory.com/102#AbstractRoutingDataSource%--Bean%--%EB%--%B-%EB%A-%-D%ED%--%--%EA%B-%B-

 

aws DB replication 관련

https://developer88.tistory.com/317

반응형

'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

댓글