RDS for MySql 사용
서비스 초기 개발시 DBA가 있거나, DBA 역할을 담당할 수 있는 적합한 인력이 없었습니다.
AWS에서는 RDS라는 Pass 형태의 DB 서비스를 제공하고 있습니다. RDS는 HA, Backup & Recovery 구성을 몇 번의 클릭만으로 손쉽게 구성이 가능하여, 서비스 시작 단계에 신속하게 DB를 구성하여 테스트를 해 볼 수 있는 이점이 있습니다. 그래서 테스트 및 상용 환경까지 RDS for MySql(이하 RDS)을 사용하게 되었습니다.
뚱땡이 Table 탄생
서비스 시작 시점에서는 서비스가 커질 경우에 대한 미래에 대한 고민 보다는 현재에 집중하여 서비스 기능 개발과 글로벌 인프라 구성을 우선시 하였습니다.
그러나 서비스는 생각 보다 빠르게 성장 하였습니다. 출시 1년만에 가입자는 천 만명을 넘었고, 2년이 되어 갈쯤 거의 3천만에 도달 하였습니다. (올해 가입자는 작년 보다 50% 이상 성장 할 것으로 예상하고 있습니다.)
서비스 성장 자체는 매우 좋은 일이나, 서비스가 커 가는 거 만큼 내실을 충실히 다지지 못 하였습니다. 특히, DB가 큰 문제였습니다.
RDS Storage는 500GB에서 시작하여 현재 3TB(1,200 IOPS)까지 증가하였고, I/O 성능을 위해서 Provisioned IOPS를 사용하였습니다. 또한 RDS Instance Type도 m3.large에서 r3.4xlarge까지 scale up을 하였습니다.
더 불어 가입자가 급격하게 증가하다 보니, 특정 table이 비대하게 커지게 되었습니다. 커진 Table의 경우 Row가 거의 10억 건에 육박하였습니다.
이로 인해 서비스 초기 전혀 문제가 되지 않았던 query에서 slow query가 빈번하게 발생되었습니다. 몇 가지는 query 튜닝하여 처리 하였으나, 비대하게 커진 table에 index가 적용되어야만 성능이 해결되는 근본 적인 이슈가 있었습니다.
뚱땡이 Table에 Index 적용
RDMS 특성상 Row 수가 많은 경우 index를 타지 않으면, 성능이 극악하게 떨어 질 수 밖에 없습니다. 그래서 내부 논의 끝에 비대하게 커진 table에 index를 적용하기로 하였습니다. 그래서 아래와 같은 2가지 방법으로 진행하였습니다.
첫 번째 시도
조사를 통해 percona on line schema change(이하 PTOSC)를 확인 하였습니다. 그래서 이 toolkit으로 테스트를 해 보았습니다. 결과적으로 RDS를 단순하게(?) 사용하는 경우에는 별 무리 없이 적용 가능할 것으로 확인 하였습니다.
그러나 저희는 master - replica(1대) - replica(2대) 이와 같은 구조를 가지고 있으며, replica를 두 단계로 적용 했던 이유는 master에 replication 부하를 완화 하기 위해 replication 전용 replica를 두었습니다. 또한 비용 절감을 위해서 replica는 master보다 사양을 낮게 구성하였습니다.(AWS에서는 가급적 master와 동일 사양의 replica 구성을 추천합니다.)
이런 구조를 가지고 있다 보니, PTOSC로 index나 table에 column을 추가 할 때 최 하단 replica에서 data 정합성이 깨지는 이슈가 있었습니다. 이 방법으로 index 추가가 불가능 했습니다.
두 번째 시도
master - replica 구조에서 replica에 replication 잠시 중단하고 필요한 index와 column을 추가하고, 다시 master와 replication sync를 맞추기를 여러차례 진행합니다. 원하는 모든 작업을 완료하고 replication이 master 를 다 따라 잡게 되면 master 로 들어 오는 트래픽을 모두 차단시킵니다.
이후에 replica 를 master로 승격 시키고, 기존 master로 유입하던 트래픽을 새로게 승격된 replica로 유입 시킵니다.
즉, index와 column이 추가된 새로운 master를 만들어, 잠시 서비스 중단을 가지고 새롭게 만든 master로 교체를 하는 것입니다.
DBA가 없는 상태에서 선택하기 쉽지 않은 작업 방법이었으나, 이 방법에 대해서 여러차례 테스트 하여 이상이 없다는 것을 확인 후 실제 index를 추가 하기로 결정했습니다.
뚱땡이 Table에 Index 적용 하면서 발생된 이슈
RDS는 replica에 multi-az을 설정할 수 없습니다.
위 두번째 방법으로 새롭게 master를 교체한 후 고 가용성을 위해 multi-az을 설정 하였고, 이로 인해서 서비스 장애를 겪게 되었습니다. 아주 쫀득쫀득 한 시간이었습니다.
RDS는 내부적으로 EBS를 사용하고 있습니다.
multi-az 구성은 백그라운드에서 진행이 되는데, EBS가 느리게 로딩되어 RDS가 제 성능을 발휘하지 못하게 됩니다.
이로 인해 전체적인 서비스 성능 저하가 유발되었습니다.(느리게 로딩되는 대신 바로 사용이 가능합니다.) (http://docs.aws.amazon.com/ko_kr/AWSEC2/latest/UserGuide/ebs-restoring-volume.html)
이 당시 DB Storage는 2TB 정도 였는데, 한참 후에나 DB 사용이 원활 했습니다.
Index 및 Column 추가하는데 많은 테스트를 진행하였으나, Multi-AZ 적용시 EBS 로딩에 이정도의 시간이 소요 될지 전혀 예상하지 못 하였습니다. Multi-AZ 적용은 비용 이슈와 AWS 지원 사항이라 생각하고 테스트에 전혀 고려하지 않았던 것이 큰 문제였습니다.
교훈
본 작업을 통해서 사소한 것 하나라도 놓치지 않기 위해 더 많이 노력(외부 자문 및 내부 동료들과 논의 등)해야 한다는 것을 글로벌 서비스 장애를 겪은 후 더 깊게 느끼게 되었습니다.
또한 중요 이벤트시 신속한 이슈 대응을 위해 AWS Support를 통해서 미리 지원을 받을 수 있는 체계를 갖추어야 할 것입니다. 뿐만 아니라 중요한 사항은 미리 지원을 받아서 테스트를 하는 것도 중요해 보입니다.
처음부터 모든 사항을 고려해서 개발하는 것은 그 정도나 수준을 정하기 어렵습니다. 앞으로 신규 서비스를 런칭 및 운영을 하더라도 이와 유사한 이슈는 또 발생될 거라 생각 합니다.
이와 같은 유사한 작업을 또 진행 해야 한다면, Multi-AZ 이슈를 피하기 위해 AWS DMS를 이용 할 것입니다.
AWS DMS는 replica가 아닌 multi-az이 적용된 별도의 RDS에 replication을 진행할 수 있습니다.(DMS는 replication 성능을 위해 가급적 Multi-AZ을 권장하지는 않습니다.) 이때 DMS에서 지원하는 기능을 활용하여 index 및 column등을 추가하면 소기의 목적을 달성할 수 있을 것으로 보입니다. 단, 충분히 테스트를 해야 한다는 가정하에서...
'AWS' 카테고리의 다른 글
CIDR 표기법 (0) | 2017.03.06 |
---|---|
다른 계정 S3에 접근하기 (0) | 2016.11.08 |
AWS SLA 관련 해서 (0) | 2016.10.19 |
AWS Cloud 2016 발표 후기 (0) | 2016.01.11 |
AWS Region 선택의 중요성 (0) | 2016.01.11 |