[졸업프로젝트-3] DataBase replication

진행 중인 졸업프로젝트 github Organization주소입니다.

https://github.com/smu-graduation-project

제 졸업프로젝트 명은 "센서 데이터 수집 기반의 모니터링 시스템 개발" 입니다.

진행 상황

lora gateway의 mariaDB에서 DummyNode의 데이터를 받아오는 것은 확인되었습니다.

하지만 해당 DB와 Spring을 연결하여 데이터를 실시간으로 계속 받아오는 것에는 여러 문제가 있었습니다.

  1. gateway의 성능문제

    데이터를 실시간으로 받아와야하는 서버 환경에서 성능이 부족한 라즈베리파이만으로 database를 운영하기엔 문제가 있다고 판단

  1. gateway의 외부 접속 허용 문제

    gateway로 사용하는 라즈베리파이가 서버와 랜선으로 연결되어 있어 외부에서 해당 DB에 접속하기 위해서는 포트포워딩을 비롯한 설정을 해야 하기 때문에 문제가 있다고 판단


이를 한번에 해결하기 위해 방안을 찾던 중,

서버에 있는 MySQL로 라즈베리파이의 DB데이터를 복제하는 것을 생각해 냈습니다.

하지만 외부 프로그램의 개입을 통한 데이터 복사는 실시간으로 진행하기 어려운 문제가 있었습니다.


때문에 이를 해결할 수 있는 실시간 처리 방법을 찾다가

Database replication을 알게 되었습니다.

Replication의 목적은 Database를 분산화하기 위한 것으로, 원론적인 목적은 다를 수 있지만,
현재 저희 팀에서 직면한 문제를 해결하기에는 가장 좋은 방법이라고 생각했습니다.


Replication의 원리는 DB를 Master, Slave로 구분하여,
Master DB의 데이터 로그파일을 Slave DB로 전달, 이를 적용하는 방식입니다.


적용 방법은 아래와 같습니다.

Matser DB 설정

1. 설정파일 수정

sudo vi /etc/my.cnf

etc 폴더의 my.cnf를 아래와 같이 수정합니다.

log-bin = mysql-bin 	# 로그파일 명, 
server-id = 1 			# slave와 master가 달라야함
binlog_format = row 	# log 데이터 포맷
expire_logs_days = 2 	# log를 저장할 기간

윈도우의 경우 cmd를 관리자모드로 열고,
해당 폴더(보통 C://ProgramData/MySQL/"MySQL Server 8.0"/)에 가서

notepad my.ini

로 my.ini를 수정하면 됩니다.

2. Mysql 재시작

sudo service mysql resetart

윈도우의 경우, 서비스를 검색해서

위의 서비스를 다시시작하면 됩니다.

3. 계정 생성

이후 mysql로 접속해서 slave가 접속시 사용할 계정을 생성합니다.

Mysql(master) > grant replication slave on .'아이디'@'%' identified by '비밀번호';

4. Status(Position) 확인

Mysql(master) > show master status;

해당 값은 Slave설정시 사용해야 하기 때문에 기억해두면 좋습니다.


Slave DB 설정

1. 설정파일 수정

sudo vi /etc/my.cnf

etc 폴더의 my.cnf를 아래와 같이 수정해준다.

log-bin = mysql-bin 	# 로그파일 명(master와 동일하게)
server-id = 2 			# slave와 master가 달라야함
binlog_format = row 	# log 데이터 포맷
expire_logs_days = 2 	# log를 저장할 기간
report-host = winServer	# Mastere에서 slave를 구분하기 위한 값

2. Mysql 재시작

sudo service mysql resetart

3. Master 설정

mysql(slave) > CHANGE MASTER TO 
        MASTER_HOST=“마스터DB의 ip 주소”, 
        MASTER_USER='아이디', 
        MASTER_PASSWORD='비밀번호', 
        MASTER_PORT=3306, 
        MASTER_LOG_FILE= 'Master의 FILE명', 
        MASTER_LOG_POS= Master의 Position;

여기서 File명과 postion은 앞서
show master status로 확인 한 값으로, show master status를 통해 확인 할 수 있고, 아래 이미지처럼 나오게 됩니다.

4. Slave 시작

mysql(slave) > start slave;

해당 명령어로 실행시키면, Master의 log를 기반으로 slave에 데이터가 복제되게 됩니다.

5. 실행 확인

mysql(slave) show slave status\G;

해당 명령어를 사용하면, 현재 slave의 설정값과 Error를 확인 할 수 있습니다.

여기서

Slave_IO_Running : yes
Slave_SQL_Running : yes

라면, 정상적으로 동작 하는 것이라고 볼 수 있습니다.

만약 Connectiong... 이라면, port, ip주소, 방화벽 등을 확인해 열어두면 된다.
난 port 문제로 하루 날렸다... port 정보는 my.cnf 에서 확인 가능하다.

다음으로

Last_IO_Errno :
Last_IO_Erro :
Last_SQL_Errno :
Last_SQL_Error :

에 해당하는 부분에서 Error에 대한 정보를 확인할 수 있는데

처음 Slave_IO(SQL)_Running은 정상이었지만
Master에 쿼리를 날리고 나면, 에러가 발생하는 경우

아래와 같은 방법으로 해결 할 수 있습니다.


Error 해결

여기에 나는 추가적인 설정을 더 주었는데, 특정 테이블만 필요한 것이기 때문에 전체 DB를 복제할 필요가 없었고,
해당 DB를 계속해서 다른 용도로도 사용해야 했기 때문에 Slave로 설정된 DB에 추가적인 CRUD 작업이 가능해야 했습니다.

때문에 복제할 DB를 지정해주는 설정과, Error발생을 무시하는 설정을 추가하였습니다.

binlog_do_db = lora_custommer.appdata	# DBName.TableName 구조이다. 여러 Table을 복제하고 싶으면 여러줄을 추가하면 된다.
slave-skip-errors = 1049, 1146			#Error 번호는 상황에 따라 다르다.

Error의 번호는 이 이전까지의 설정을 마무리한 이후

show slave status\G

를 통해 확인 할 수 있습니다.


추가설정(Table 정보 복사)

Replication은 log파일을 기반으로 데이터를 복제하는 것이기 때문에,
Replicatioin설정 이전에 만든 DataBase 혹은 테이블을 그대로 가져오지 않았습니다.

하지만, 같은 Table이 존재해야, 값이 복사되는 만큼, 테이블을 동일한 형태로 만들어야합니다.

이때 한가지 방법으로, MasterDB에서 테이블의 정보를 가져와 해당 정보를 기반으로 slave에 테이블을 만들 수 있습니다.

mysql(master) SHOW CREATE TABLE DBName.TableName;

해당 명령어를 사용하면, 해당 Table과 같은 Table을 만들 수 있는 값을 주는데

이를 복사해서 SlaveDB에 똑같은 Table을 만든다면, 정상적으로 replication이 동작하는 것을 확인 할 수 있습니다.

좋은 웹페이지 즐겨찾기