상세 컨텐츠

본문 제목

MariaDB 이중화구성방법

Database

by 범쥰 2023. 3. 9. 20:01

본문

구성방법 종류

MariaDB의 이중화 구성 방법에는 크게 2가지가 있다.

  1. 복제 기반 이중화
  • 복제 기반 이중화는 Master 서버에서 변경된 데이터를 Slave 서버로 비동기적으로 복제하여 이중화 구성을 구현하는 방법이다.
  • 이 방법은 Master와 Slave 서버를 물리적으로 분리하여 이중화 구성을 할 수 있기 때문에 데이터의 가용성과 신뢰성을 높일 수 있다.
  • 복제 기반 이중화의 대표적인 방법으로는 Master-Slave Replication 방식이 있다.
  1. 클러스터 기반 이중화
  • 클러스터 기반 이중화는 Master와 Slave 서버를 여러 대 두어 하나의 클러스터를 구성하여 이중화 구성을 구현하는 방법이다.
  • 이 방법은 여러 대의 서버를 묶어서 하나의 시스템처럼 사용할 수 있기 때문에 성능과 가용성을 높일 수 있다.
  • 클러스터 기반 이중화의 대표적인 방법으로는 Galera Cluster 방식이 있다.

각각의 MariaDB 이중화 구성 방법의 특징과 장단점은 다음과 같습니다.

  1. 복제 기반 이중화
  • 특징:
    • Master 서버와 Slave 서버를 물리적으로 분리하여 이중화 구성이 가능하다.
    • 비동기적인 복제 방식을 사용하기 때문에 빠른 응답 속도를 보장할 수 있다.
    • Master 서버에서 변경된 데이터를 Slave 서버로 비동기적으로 복제하기 때문에, 복제 지연이 발생할 수 있다.
  • 장단점:
    • 데이터의 가용성과 신뢰성을 높일 수 있다.
    • Master 서버와 Slave 서버를 물리적으로 분리하기 때문에, 하나의 서버에 장애가 발생하더라도 다른 서버에서 이중화된 데이터를 사용할 수 있다.
    • Slave 서버가 Master 서버에 비해 데이터 지연이 발생할 수 있으므로, 일부의 데이터 불일치가 발생할 수 있다.
  1. 클러스터 기반 이중화
  • 특징:
    • 여러 대의 서버를 묶어 하나의 시스템처럼 사용할 수 있으므로, 성능과 가용성을 높일 수 있다.
    • 스토리지 엔진과 함께 사용하면 데이터 복제와 분산 저장을 동시에 수행할 수 있다.
    • 모든 노드에 동일한 데이터가 저장되기 때문에, 데이터 일관성을 보장할 수 있다.
  • 장단점:
    • 클러스터링 기술을 사용하기 때문에 구성이 복잡하고, 운영 비용이 높을 수 있다.
    • 복제 기반 이중화보다 처리 속도가 느리기 때문에, 고성능 환경에서는 적합하지 않을 수 있다.
    • 노드의 개수가 많아질수록 복잡도와 관리 부담이 커질 수 있다.

속도가 빠르고 구성이 간단하여 관리 부담 측면에서 어려움이 없는 Master-Slave 방법으로 택함.

 

Master-Slave 구성 방법

주의사항

  1. Slave 서버의 DB 버전은 Master 서버보다 높거나 같아야한다.
  2. Master와 Slave 서버의 DB는 동일한 port 를 사용해야한다. (기본 3306)
  3. Master와 Slave의 데이터베이스 스키마가 동일해야한다. 스키마가 다르면 데이터 복제가 실패할 수 있다.
  4. Master 서버의 바이너리 로그(binlog) 설정이 올바르게 구성되어야한다. 바이너리 로그가 올바르게 활성화되지 않으면 Slave가 Master로부터 데이터를 복제하지 못할 수 있다.
  5. Master 서버의 방화벽 설정을 검토하여 Slave가 Master 서버에 연결할 수 있도록 허용되는지 확인해야한다.
  6. Slave는 Master 서버에 대한 읽기 전용 연결을 사용해야한다. Slave에서 데이터를 수정하려고 시도하면 복제가 중단될 수 있다.
  7. 데이터베이스의 크기 및 트래픽 양을 고려하여 Slave 서버의 리소스를 충분히 할당해야한다.
  8. Master 서버와 Slave 서버 간의 네트워크 대역폭이 충분해야한다. 대역폭이 부족하면 데이터 전송 지연이 발생할 수 있으며, 복제가 지연되거나 실패할 수 있다.
  9. Slave 서버의 복제 상태를 주기적으로 모니터링하고 복제가 중단되면 적시에 조치를 취해야한다.
  10. Slave 서버의 데이터베이스를 백업해야한다. Slave 서버에서 데이터가 손실되면 Master 서버로부터 데이터를 복제 할 수 없다.

※ 특이사항

  1. Master 와 Slave 서버의 3옥텟이 다르면 네트워크 환경에 의해 연결에 실패할 수 있다.
    1. 해당 문제로 인한 Slave에서 Master로 연결 실패 시 발생하는 에러 메시지 (하지만 아래 에러메시지는 원인이 다양해서 해당 문제로만 한정지을순 없음. password 에러 및 port에러도 포함됨)
    2. Access denied for user 'repl_user'@'xxx.xxx.xxx.xxx' (using password: YES)

 

구성 절차

아래 동작은 Windows 기준 MariaDB Command Prompt 로 수행한다.

 

1. Master와 Slave 서버 cmd - Mysql root 계정 접속

mysql -u root -p
-- 패스워드입력
enter password

2. Master와 Slave 서버 DB 설정

Master와 Slave 서버를 각각 설정한다.
1) 동일한 이름의 database 생성

create database dbName;

 

2) 동일한 이름의 복제 user 계정 생성 및 권한 부여

 

grant replication slave on *.* to 'repl_user'@'%' identified by 'password';
flush privileges;
create user 'repl_user'@'%' identified by ‘password';

 

 

3. Master 서버의 이중화 설정

  • Master 서버에서는 이중화 설정을 위한 server_id, log_bin(이중화 로그 사용) 등의 설정이 필요하다.
    • Master 서버 my.ini (경로: $MariaDB 설치파일경로/data/my.ini)

log-bin : master의 binary log file 명으로 자유롭게 설정가능

 

  • Master 서버 DB 재시작 후 Master Status 확인

position: master에서 동작한 로그의 position 값

 

 

 

4. Slave 서버의 이중화 설정

  • Slave 서버에서 이중화 설정을 위한 server_id,log_bin(이중화 로그 사용),relay-log, relay-log-index 등의 설정이 필요하다. (필수는 server_id, log_bin)
  • log_bin은 master와 동일한 log_bin 이름
  • server_id 는 유니크 값으로 master와 다른 값으로 지정
  • Slave서버 my.ini (경로: $MariaDB 설치파일경로/data/my.ini)

  • Slave 서버 재시작 후 Slave Status 확인
    • 아직 master와 연결 전이라 status 는 Empty set 로 나와야한다.
    • Empty Set 으로 나오지 않는다면, `$MariaDB 설치파일경로/data/` 경로의 master.info 파일을 삭제하고 재시작 후 해당 절차를 다시 시행한다.

Empty Set

 

 

 

5. Slave 서버에서 Master 서버 정보 지정 및 연결

  • Slave 서버에서 Master 서버의 정보를 지정하여 Master 서버와 연결한다.
  • 이를 위해서는 MariaDB에서 CHANGE MASTER TO 문을 사용하여 Master 서버와 연결한다.
    • master_host : Master 서버의 host 명
    • master_user : 복제 계정 아이디
    • master_password : 복제 계정 비밀번호
    • master_log_file : Master 서버에서 show master status 로 했을때 보이는 log file 명
    • master_log_pos : Master 서버에서 show master status 로 했을때 보이는 log Position
change master to master_host='xxx.xxx.xxx.xxx',master_user='repl_user',master_password='password!',master_port=3306,master_log_file='mysql-bin.000004',master_log_pos=342;
  • 해당 절차 진행 중 `Could not initialize master info structure for ''; more error messages can be found in the MariaDB error log` 에러 발생시, 아래 stop slave; reset slave; 후 진행한다. 
stop slave;
reset slave;
  • 그래도 해당 과정이 진행이 안된다면, data directory 에 mysql-bin.00000x 파일들 , mysql-bin.index,master-info,relay-log-info 까지 직접 지우고 재시작 후 해당 과정 재 진행

6. Slave 서버에서 이중화 시작

  • Slave 서버에서 이중화를 시작한다.
  • 이를 위해서는 MariaDB에서 START SLAVE 문을 사용하여 이중화를 시작한다.

  • Slave 서버의 상태를 확인한다.

<연결 성공>
Slave_IO_State : Waiting for master to send event
Slave_IO_Running : Yes
Slave_SQL_Running: Yes

 

7. Master 서버와 Slave 서버에서 이중화 확인

  • Master 에서 DB 에 변화를 주고 Slave 에서 복제되었는지 확인한다.

이러한 방법으로 마리아DB의 이중화 구성을 설정하면 Master 서버에서 변경된 데이터가 Slave 서버로 자동으로 복제되어, 데이터의 가용성과 신뢰성을 높일 수 있다.

 

 


 

Spring 에서 이중화 DB로 연결


`spring.datasource.url` 프로퍼티를 사용하여 한 번에 이중화 DB에 연결하는 방법이 있다. 이 방법은 Spring Boot에서 지원하는 기능 중 하나인 **RoutingDataSource**를 사용하여 구현된다.

`RoutingDataSource`는 실제 데이터베이스 연결을 관리하는 여러 개의 `DataSource`를 가지고 있으며, 각 `DataSource`에 대한 연결을 알맞게 분배하여 사용한다. 이를 통해 다수의 데이터베이스에 대한 연결을 투명하게 처리할 수 있다.

아래는 `RoutingDataSource`를 사용하여 `spring.datasource.url` 프로퍼티를 통해 이중화 DB에 연결하는 예시다.

@Configuration
public class DataSourceConfig {
 
    @Bean
    @Primary
    public DataSource dataSource() {
        DriverManagerDataSource dataSource1 = new DriverManagerDataSource();
        dataSource1.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource1.setUrl("jdbc:mysql://db1.example.com:3306/mydatabase");
        dataSource1.setUsername("user1");
        dataSource1.setPassword("password1");
 
        DriverManagerDataSource dataSource2 = new DriverManagerDataSource();
        dataSource2.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource2.setUrl("jdbc:mysql://db2.example.com:3306/mydatabase");
        dataSource2.setUsername("user2");
        dataSource2.setPassword("password2");
 
        Map<Object, Object> targetDataSources = new HashMap<>();
        targetDataSources.put("dataSource1", dataSource1);
        targetDataSources.put("dataSource2", dataSource2);
 
        RoutingDataSource routingDataSource = new RoutingDataSource();
        routingDataSource.setTargetDataSources(targetDataSources);
        routingDataSource.setDefaultTargetDataSource(dataSource1);
 
        return routingDataSource;
    }
 
    @Bean
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(dataSource());
    }
}

위의 예시에서 `RoutingDataSource` 객체를 생성하고, `setTargetDataSources()` 메서드를 사용하여 각 데이터베이스에 대한 `DataSource`를 설정한다. `setDefaultTargetDataSource()` 메서드를 사용하여 기본적으로 사용할 `DataSource`를 설정한다.

그리고 `JdbcTemplate`를 생성할 때 `dataSource()` 메서드를 사용하여 `RoutingDataSource` 객체를 전달하면 된다. 이렇게 구성하면 `JdbcTemplate`는 내부적으로 `RoutingDataSource`를 사용하여 이중화 DB에 연결한다.

 


Spring Boot 에서 이중화 DB로 연결


Spring Boot에서 MariaDB 이중화를 구성하는 방법에 관한 소개이다

  1. MariaDB 드라이버 의존성 추가:pom.xml 파일에 MariaDB 드라이버 의존성을 추가해야한다. 아래와 같은 코드를 추가한다.
xmlCopy code
<dependency>
    <groupId>org.mariadb.jdbc</groupId>
    <artifactId>mariadb-java-client</artifactId>
    <version>${mariadb.version}</version>
</dependency>

여기서 ${mariadb.version}은 사용하려는 MariaDB 버전에 따라 변경된다.

  1. application.properties 설정:application.properties 파일에 다음과 같은 설정을 추가한다.
xmlCopy code
<dependency>
    <groupId>org.mariadb.jdbc</groupId>
    <artifactId>mariadb-java-client</artifactId>
    <version>${mariadb.version}</version>
</dependency>

 

여기서 [host1], [host2], [database], [username], [password]는 각각 사용자가 지정해야 하는 값.

  • [host1], [host2]: MariaDB 이중화된 서버 IP 주소
  • [database]: 사용할 데이터베이스 이름
  • [username], [password]: 데이터베이스에 액세스하기 위한 사용자 이름과 비밀번호

  2. replication 설정MariaDB의 이중화 기능을 사용하려면 마스터-슬레이브 복제 구성이 필요하다. 이를 위해 다음과 같은 구성을 추가한다.

propertiesCopy code
# 마스터 구성
spring.datasource.master.url=jdbc:mariadb://[master_host]/[database]
spring.datasource.master.username=[username]
spring.datasource.master.password=[password]
spring.datasource.master.driver-class-name=org.mariadb.jdbc.Driver

# 슬레이브 구성
spring.datasource.slave.url=jdbc:mariadb://[slave_host]/[database]
spring.datasource.slave.username=[username]
spring.datasource.slave.password=[password]
spring.datasource.slave.driver-class-name=org.mariadb.jdbc.Driver

# 읽기 전용 인 경우 슬레이브에만 쓰도록 설정
spring.datasource.tomcat.initial-size=5
spring.datasource.tomcat.max-active=15
spring.datasource.tomcat.max-idle=10
spring.datasource.tomcat.min-idle=5
spring.datasource.tomcat.default-auto-commit=false
spring.datasource.tomcat.test-while-idle=true
spring.datasource.tomcat.test-on-borrow=true
spring.datasource.tomcat.validation-query=SELECT 1

# MariaDB 이중화 설정
spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb:replication://[master_host],[slave_host]/[database]?useSSL=false
spring.datasource.replication=true
spring.datasource.read-only=true
spring.datasource.validation-query=SELECT 1
spring.datasource.validation-interval=10000
spring.datasource.test-on-borrow=true
spring.datasource.test-while-idle=true
spring.datasource.test-on-return=false
spring.datasource.time-between-eviction-runs-millis=30000
spring.datasource.min-evictable-idle-time-millis=60000
spring.datasource.remove-abandoned=true
spring.datasource.remove-abandoned-timeout=60
spring.datasource.log-abandoned=true

 

굳이 tomcat 라이브러리를 쓰지않고 단순히 properties만 변경하여 쓰는 방법도 있다.

spring.datasource.driverClassName=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb:loadbalance://[master_host]/,[slave_host]/[database]?autoReconnect=true&failoverDelay=5000&allowMultiQueries=true
spring.datasource.maximum-pool-size = 4
spring.datasource.username=[username]
spring.datasource.password=[password]

이 외에도, master.url / slave.url 등 다양한 방법이 있으니 본인 프로젝트 환경에 맞는 방법을 구성하여서 사용하면 될 듯하다.