티스토리 뷰
작년 말에 Aurora MySQL 5.7 버전의 지원 종료와 연장 지원 안내를 받았었다.
요약하면 권장 사항인 MySQL 8.0 대신 MySQL 5.7 버전을 계속 사용할 경우 돈을 더 내라는 내용이었다.
올해 전반기 내내 다사다난해서 지금껏 미뤘다가 이제서야 업데이트를 시작할 여유가 생겼다.
버전 업데이트에 앞서 문제 상황을 확인해보자.
1. 연장 지원 비용
비용이 저렴하다면 그냥 둬도 될 것 같다. 그런데 연장 지원 비용을 계산해보면 다음과 같다.
현재 1년차기 때문에 한달에 약 11만원(1380 × 0.12 × 24 × 30)의 추가 요금이 발생 중이다.
1년이면 120만원, 관리를 안한다면 계속 늘어난다. 거기다 개발서버도 따로있어서 × 2의 비용이 발생한다.
개선이 필요할 것 같았다.
2. 서비스 순단없이 업데이트가 가능한가?
현재 서비스는 AWS RDS Aurora MySQL 5.7 버전을 사용 중이다.
Multi AZ로 구성해놓았기 때문에, 별도의 고가용성을 위한 조치는 필요하지 않았다.
(진짜 모든 AWS의 AZ에 문제가 생기는 경우가 아니라면, 일시적인 인스턴스의 장애에도 강건할 것이라 예상됨)
다만 Aurora MySQL의 Multi AZ는 단일 DB 형태로 관리되기 때문에, slave 인스턴스를 따로 가지고 있지 않다.
이럴 경우 업데이트 과정이 아래와 같이 정리된다.
- 서비스 임시 중단 페이지 노출
- DB 복제본 생성 (장시간의 대기 시간이 필요)
- BE가 DB 복제본을 바라보게 재배포
- 서비스 재시작
테스트를 위한 dev DB는 크기가 비교적 작아서 복제본 생성 시간이 짧았지만
상용 DB에서 작업을 할 경우 복제본이 만들어질 때까지 장시간 기다려야 할 수 도 있다.
그리고 중간에 배포가 잘못된다던지, 잘못된 복제본을 다룬다던지 등의 휴먼에러가 발생한다면
서비스의 셧다운 시간은 하염없이 길어질 것이다.
이런 내용들이 우려되었는데, AWS RDS에서 최소한의 다운타임을 제공해준다는 Blue/Green 배포를 제공해줘서 이를 사용해봤다.
Blue/Green으로 분리된 DB가 제대로 동작하도록 만드는 것과 로그 트래킹을 하는 것 외에 배포 자체는 어렵지 않았다.
AWS RDS 블루-그린 배포란?
https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/blue-green-deployments.html
프로덕션 워크로드에 영향을 주지 않고 그린 환경에서 RDS DB 인스턴스를 변경할 수 있습니다. 예를 들어 메이저 또는 마이너 DB 엔진 버전을 업그레이드하거나 기본 파일 시스템 구성을 업그레이드하거나 스테이징 환경에서 데이터베이스 파라미터를 변경할 수 있습니다. 그린 환경의 변경 사항을 철저하게 테스트할 수 있습니다. 준비가 되면 환경을 전환하여 그린 환경을 새로운 프로덕션 환경으로 승격할 수 있습니다. 전환은 일반적으로 1분도 걸리지 않으며 데이터 손실이 발생하지 않고 애플리케이션을 변경할 필요도 없습니다.
AWS의 소개로는 장점 밖에 없다. 내가 아는 다른 방법들은 무결성을 위해 복제하는 시간에 모든 write를 막아야한다.
일단, 그럴 필요 없고 1분 이내의 짧은 순단 시간만 있으면 된다고해서 이 방식으로 진행해보고 싶었다.
구조
뭔가 그림이 길어서 어려워보이는데, 아래와 같이 요약할 수 있다.
블루 환경 : 상용 환경
그린 환경 : 스테이징 환경
1. 블루 데이터베이스의 레플리카로 그린 데이터베이스가 생김(모든 정보를 블루와 동일하게 사용)
2. 그린 데이터베이스는 기본적으로는 ReadOnly, Read로만 접근
3. 블루 데이터베이스에서 발생한 쓰기가 binary log로 전달
블루/그린 배포 생성 순서
1. MySQL 5.7에서 8.0으로 업그레이드하기 위한 사전 점검 목록을 확인
내용을 확인하고 서버와 데이터 베이스에 반영하자. 만약 제대로 반영이 되어 있지 않다면,
그린 데이터베이스로의 write가 정상 동작하지 않는다.
2. 파라미터 그룹 생성(권장)
나는 binlog_format만 설정해줬다. 블루 데이터베이스의 binlog_format만 MIXED여서 동일하게 설정했다.
경우에 따라서 캐릭터 셋 설정이 필요한 경우도 있고, 테이블 설정도 해야할 수 있다.
여기에서 확인(사전 점검에 있는 내용을 충분히 준비했다면 이정도 준비는 필요 없는 듯 하다)
3. 블루-그린 배포 생성
당연히 버전은 mysql 8 버전을 선택하고,
파라미터 그룹은 위에서 생성한 클러스터 파라미터 그룹, 인스턴스 파라미터 그룹은 디폴트를 사용했다.
블루-그린 업그레이드 중
완료 후
4. 로그 확인해가며 문제 수정
이벤트 : 로그 이벤트 > 이벤트
CloudWatch : 구성 > 그린 클러스터 클릭 > 오류 혹은 CloudWatch에서 로그 그룹 직접 검색
이벤트와 로그를 잘 모니터링해야한다... 처음에 로그가 남을 거란 생각은 했는데 위치를 찾지 못 했었다.
이벤트에서 그린 데이터베이스에 문제가 있다는 것을 확인하고, CloudWatch 로그를 통해 세부 사항을 알아낼 수 있었다.
5. 재부팅 후 안되면 삭제 후 재시작해서 변경 사항 반영
오래걸려도 삭제 후 재시작이 가장 깔끔하다.
GPT한테 질문하니까 Slave DB로 가서 DCL(Data Control Language)을 쓰라고 하는데, 별로 권장하니 않는다.
6. 전환
블루/그린 배포 선택 후 우측 상단 작업에서 전환 클릭한다.
전환 시에 설정에 문제가 있으면 이벤트에 실패 로그가 남고 진행이 자동 중단되니 걱정하지 않아도 된다.
그래도 만약을 위해서 스냅샷을 떠놓자.
타임아웃을 설정할 수 있다. 제한 시간은 블루/그린 전환이 5분 이상 되면 타임아웃되어 취소되도록 설정했다.
전환 중
전환 완료
블루-그린 스위칭에 약 2분 정도 소요됐다.
기존 블루 데이터 베이스의 이름에 자동으로 suffix로 -old가 붙는다.
전환이 예상보다 너무 짧았어서 write가 정말 막혀있나까진 테스트를 못 해봤다...
7. old blue 데이터베이스 삭제
블루/그린 배포를 삭제해도 새로운 블루 데이터베이스는 삭제되지 않는다.
클러스터는 하위 인스턴스를 삭제해야 삭제 가능하니 차근차근 삭제해준다.
완전히 삭제되면 전환이 완료된 것이다.
주의할 점
1. 그린 데이터베이스의 프로비저닝과 업데이트가 생각보다 오래걸린다.
업데이트까지 완전히 끝날 때까지 기다려야한다.
중간에 설정을 수정하면 무한 루프에 빠질 수 있으니 꼭 주의해야한다.
그린 클러스터를 만들 때 MySQL 8.0으로 지정하고 만드는데, 중간에 5.7로 복제본이 생성되는 과정을 거친다.
이 때 절대 수정하면 안된다.
블루 데이터베이스와 동일한 구성이 완전히 만들어진 후에 업데이트를 자동으로 해준다.
2. 작은 사이즈의 버스터블 인스턴스 t3 클래스는 MySQL 8.0 버전을 지원하지 않는다.
불행히도 dev 서버가 db.t3.small을 사용 중이어서 업데이트 전에 인스턴스부터 업그레이드 해야했다. db.t4g.medium
db.t3.small > db.t4g.medium 설정
DB 인스턴스 구성 분석
메모리 최적화 클래스 : 대량의 메모리를 필요로 하는 워크로드에서 높은 성능 제공
https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Concepts.DBInstanceClass.html#Concepts.DBInstanceClass.Types.memory
버스터블 클래스 : 기본적인 성능을 제공하면서 필요할 때 추가적인 CPU 성능을 버스트(일시적 증가)할 수 있습니다. 낮은 비용으로 일관된 성능이 필요하지 않은 워크로드에 적합합니다. t로 시작함
https://docs.aws.amazon.com/ko_kr/AmazonRDS/latest/UserGuide/Concepts.DBInstanceClass.html#Concepts.DBInstanceClass.Types.burstable
3. Green 데이터 베이스는 라이터 인스턴스도 Read-Only다.
억지로 read-only를 풀려고 하지말자.
(파라미터 그룹에서 옵션을 바꾸면 된다고해서, 시도 했으나 안풀렸다.. 글로벌로 막혀있나?)
억지로 풀고 write를 해버리면 전환 시 데이터 불일치로 오류가 발생할 수 있다고 한다.
binary-log로 어차피 블루 데이터에서 업데이트를 실시간으로 받아오고 있다.
4. bin_format이 blue와 green 모두 설정되어 있으면, blue에 변경사항이 green으로 넘어와야 한다.
write가 전달이 안될 경우, 아직 에러가 남아 있는 것이다. 내가 마주한 에러 중 하나는 CloudWatch에서 다음과 같다.
[ERROR] [MY-010584] [Repl] Replica SQL for channel '': Worker 1 failed executing transaction 'ANONYMOUS' at source log mysql-bin-changelog.000032, end_log_pos 78640823; Error 'You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'rank ..
이 에러는 현재 예약어 'rank'의 이름으로 컬럼명이 있어서 생긴 문제였다.
그 부분을 수정해줬는데, 위 에러가 똑같은 이름으로 한번 더 나왔다.
서브 쿼리의 alias도 예약어가 들어가면 안되서, 역시 rank라는 이름의 alias 백틱처리 해줬다. rank > `rank`
5. 이 에러는 반복되지 않으면 신경쓰지 않아도 된다.
[ERROR] Slave I/O for channel '': error connecting to master 'rdsrepladmin@10.7.15.0:3306' - retry-time: 60 retries: 1, Error_code: 2003
retry 시간이 짧아서 나는 에러라 retry 몇 번 하다가 에러가 더 이상 나타나지 않는다.
6. 시스템 다운 시간이 0은 아님
블루/그린 전환에 들어가면 두 데이터베이스 모두 write가 불가능한 상태가 된다.
서버 크기에 따라 다르겠지만, 이번과 같은 케이스에는 약 1~2분 정도 소요됐다.
7. 기존 블루는 지워주는게 좋다.
남겨둘 경우 지속적으로 요금이 부과된다. 기존 블루도 그린 데이터베이스처럼 read-only에 bin_log로 데이터를 전송 받는다.
마치며
회사에서 진행한 작업이라 DB 클러스터/인스턴스 이름을 공개하지 못해 아쉽다.
이름을 봐가면서 진행하면 구분하기 쉽기 때문이다.
사실상 관리자가 없는 상태로 작업해야해서, 어떤 상황이 잘 되고 있는 상황인지 파악하는 것부터 어려웠다.
여기어때 기술 블로그의 도움을 가장 크게 받았다.(정말 감사합니다 ㅠㅠ)
뭔가 안되는데 이유도 모르고 수정해도 반영이 안되서 참 답답했었는데,
재시작하면 반영된다는 것과 로그/이벤트를 보는 법을 알고 급진전됐던 작업.
순단시간은 생각보다 더 짧았다.
문제가 아예 없진 않은데, 그린 데이터 베이스를 프로비저닝하는데 제법 시간이 걸린다..
여러번 만들고 지우는데 제법 시간을 썼다.
'개발 > DB' 카테고리의 다른 글
데이터베이스 이중화 전략과 AWS Aurora RDS에서의 설정 (1) | 2024.06.18 |
---|---|
MySQL Auto Increment 값 재설정하기 (1) | 2024.02.16 |
스프링부트에 QueryDSL 적용기 - 2 (설치 및 사용법, Spring Data JPA와 함께 사용하기) (0) | 2023.08.28 |
스프링부트에 QueryDSL 적용기 - 1 (Mybatis vs JPA vs JOOQ vs QueryDSL 비교) (0) | 2023.08.25 |
The MySQL server is running with the --read-only option so it cannot execute this statement 에러와 @Transactional (1) | 2023.06.01 |
- Total
- Today
- Yesterday
- 스프링부트
- 람다
- EKS
- serverless
- docker
- Log
- java
- MySQL
- Kotlin
- AWS EC2
- 인프런
- ChatGPT
- cache
- OpenAI
- openAI API
- awskrug
- elasticsearch
- GIT
- AOP
- S3
- chat GPT
- JWT
- Spring
- OpenFeign
- AWS
- lambda
- terraform
- springboot
- Elastic cloud
- CloudFront
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |