RESTful API 프로젝트는 아래와 같은 아키텍처를 가지고 있다.
가난한 나는 ec2 프리티어를 사용하고 있어서 하나의 서버에 백엔드, 젠킨스, DB가 전부 올라가 있는 상태다.
여기서 고민이 '만약에 DB 컨테이너에 갑자기 문제가 생긴다면?' 혹은 '데이터가 날아간다면?'
사실 DB 백업은 가장 먼저 고민했어야 하는 점인데... 그래서 지금이라도 백업을 통해 불상사를 대비하려고 한다.
백업은 cron을 통해서 주기적인 스케줄링을 진행한다. 나는 하루에 4번 데이터 백업을 진행한다.(6시간 간격)
또한, 5일이 지난 데이터는 삭제하도록 한다.(무분별한 백업 데이터가 쌓이지 않도록)
우선 아마존리눅스2는 기본적으로 cron이 설치되어 있지 않다. 그래서 아래 명령어로 설치를 진행.
sudo yum install cronie
설치 후 크론이 활성화가 됐는지 확인해 본다.
sudo systemctl status crond
만약에 여기서 inactive인가 이게 dead가 나온다면 서비스 활성화를 시켜줘야 한다.
sudo systemctl start crond
나는 ec2에 백업용 폴더를 하나 만들어뒀다.
mkdir db_backup
백업 폴더의 권한을 수정해 준다.
chmod 755 db_backup
그리고 동작시킬 sh 파일을 하나 내부에 만들어둔다.
vi db_backup/backup.sh
backup.sh 아래에는 다음과 같은 스크립트를 작성했다.
FILE_NAME=restapi_backup_$(date +"%Y%m%d%H%M%S")
BACKUP_DIR="/home/ec2-user/db_backup/"
sudo docker exec mysql-container sh -c 'exec mysqldump -u root --password=[비밀번호] [Schema이름]' > $BACKUP_DIR$FILE_NAME.sql
find $BACKUP_DIR -type f -ctime + 5 -exec rm -f {} \;
BACKUP_DIR의 경우 본인의 OS에 따라 경로가 다를 수 있으니 꼭 확인해 볼 것.
FILE_NAME의 경우 뒤에 현재 날짜와 시간을 통해 구분하도록 만들었다.
mysql-container로 들어가서 쉘 명령어를 수행한다. mysqldump 명령어를 쓰는데 이름, 비밀번호, 스키마를 지정해 둬서 해당 스키마를 백업하겠다는 의미.
find 명령어를 통해 디렉토리에서 5일이 지난 파일을 찾는다. 그리고 해당 파일을 강제 삭제를 진행한다.
이렇게 수행할 스크립트를 만들어놨으니 이제 cron에 등록해서 스케줄링을 해야 한다.
crontab -e
그러면 명령어를 등록할 창이 뜨는데 여기서 본인의 크론 명령어를 적어주면 된다.
0 0,6,12,18 * * * sudo /usr/bin/sh /home/ec2-user/db_backup/backup.sh >> /home/ec2-user/db_backup/log/backup.log 2>&1
나는 매일 6시간 간격으로 수행한다. 쉘 스크립트를 수행하는데 backup.sh를 수행. 이후 명령어의 출력과 로그를 log 폴더로 리다이렉트 한다.(log 폴더의 경우 미리 만들어두면 된다.)
미리 테스트를 진행해 봤다. 아래처럼 백업용 sql을 정상적으로 생성한 것 확인.
내부에 있는 데이터도 서버의 현재 최신 데이터와 일치하는 것을 확인.
이제 데이터 백업을 진행해 뒀으니 혹여나 mysql 데이터가 사라지더라도 백업을 진행할 수 있게 되었다.
그런데 한 가지 추가 문제가 발생. 만약에 ec2 컨테이너가 날아가거나 한다면? 백업용 데이터를 찾을 방법이 없다.
결국 백업용 데이터를 외부에 안전하게 보관해야 한다는 생각이 들었다.
그래서 S3에 백업 데이터를 저장해 놓기로 했다.
AWSCLI 설치는 아래에 자세하게 나와있다.
https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/getting-started-install.html
최신 버전의 AWS CLI설치 또는 업데이트 - AWS Command Line Interface
이전 버전에서 업데이트하는 경우 unzip 명령을 실행하면 기존 파일을 덮어쓸지 묻는 메시지가 표시됩니다. 스크립트 자동화와 같은 경우에 이러한 프롬프트를 건너뛰려면 unzip에 대한 -u 업데이
docs.aws.amazon.com
설치가 다 됐으면 아래 명령어를 통해 키를 입력해 준다.
aws configure
1. AccessKey -> IAM 사용자를 생성했을 때 받아두었던 Key
2. SecretKey -> 위와 동일.
3. Region -> 기본 지역 (서울 - ap-northease-2)
4. 출력 형식 -> json, text, table 선택
성공적으로 됐으면 아래 명령어를 통해 현재 s3의 버킷을 확인할 수 있다.
aws s3 ls
기존에 설정했던 backup.sh를 수정해줘야 한다.
# 백업 디렉토리 및 파일 이름
FILE_NAME=restapi_backup_$(date +"%Y%m%d%H%M%S")
BACKUP_DIR="/home/ec2-user/db_backup/"
# MySQL 데이터베이스 덤프
sudo docker exec mysql-container sh -c 'exec mysqldump -u root --password=[비밀번호] [스키마이름]' > $BACKUP_DIR$FILE_NAME.sql
# 백업 파일 S3에 업로드
aws s3 cp $BACKUP_DIR$FILE_NAME.sql s3://restapi-backup/$FILE_NAME.sql
find $BACKUP_DIR -type f -ctime + 5 -exec rm -f {} \;
S3에 업로드를 진행하는 스크립트를 추가해 주었다. 그리고 백업을 진행하고 바로 백업 sql을 삭제하려고 했지만 혹시나 s3에 업로드를 못할 수도 있으니 5일 뒤에 삭제를 진행한다.
그리고 테스트를 진행.
만약에 s3에 업로드를 진행하는데 권한이 없다고 나온다면 EC2의 IAM 역할을 연결해줘야 한다.
- AmazonS3FullAccess
- IAMReadOnlyAccess
두 개의 정책을 추가해서 IAM을 하나 연결하면 된다.
이렇게 MySQL의 데이터를 6시간마다 백업을 진행하고 S3에 업로드하도록 스크립트까지 작성했다.
데이터는 날아갈 수 있다. 그러나 최대한 복구를 진행하도록 하는 것이 중요하다.
설정해놓고 시간이 지나서 확인해보니 0, 6, 12, 18시에 매번 데이터 백업이 이루어지는 것을 확인할 수 있었다.
'프로젝트 > RESTAPI 추천 서비스' 카테고리의 다른 글
도커에 올려놓은 innodb 버퍼풀 사이즈 조정 (0) | 2024.07.15 |
---|---|
RestTemplate -> RestClient 변경이 필요할까?(Feat, 부하테스트) (0) | 2024.07.06 |
naver 소셜 로그인 추가하기(feat, 리팩토링) (0) | 2024.07.01 |
확장성이 좋은 oauth 코드로 리팩토링하기 (0) | 2024.06.27 |