안녕하세요, 힐링페이퍼에서 백엔드를 담당하고 있는 제이슨입니다! 사용자가 불편함 없이 빠르고 안정적으로 더 좋은 의료 서비스를 이용할 수 있도록 하는 역할을 하고 있습니다.

이번 글에서는 AWS RDS 에서 MySQL 기반의 wrtiable replica 를 이용해 데이터 분석용 DB 를 만든 이야기를 하려고 합니다.

Writable Replica?!

문제

여러분의 서비스는 DB 구성을 어떻게 사용하고 계시나요?

아마 문제 영역에 따라 1 개의 master 와 n 개의 read replica 를 만들어서 master 에서는 write 작업과 비교적 실시간성이 중요하고 가벼운 read 작업을, read replica 에서는 비교적 실시간성이 덜 중요하고 무거운 read 작업을 담당하게 하는 것이 일반적인 구성일 것입니다. 저희도 그렇게 사용하고 있었습니다.

그러다가 사내에서 데이터의 중요성이 점점 커지면서 많은 사람들이 read replica DB 를 통해 데이터 분석을 하기 시작했는데요. 이 상황에서 문제라고 생각되는 몇 가지 포인트가 있었습니다.

  • 데이터 분석용 쿼리의 퍼포먼스가 비효율적

    데이터 분석용 쿼리의 일반적인 특징은 무엇이 있을까요?
    일반 사용자에게 제공되는 어플리케이션에서는 현재를 나타내는 비교적 적은 데이터를 이용하는 반면, 데이터 분석을 할 때는 변하지 않는 과거의 대용량 데이터를 이용합니다. 또한, 1차 가공된 데이터들을 엮어 2차 데이터를 만드는데 이용하기도 합니다.
    그래서 raw 데이터를 매번 그대로 사용하기보다, 과거의 데이터들을 미리 가공된 형태로 저장해 두어서 나중에 빠르게 처리할 수 있도록 재사용성을 높이는 것이 일반적인데요. read replica 에서는 master 와 독립적인 데이터를 가질 수 없기 때문에 그런 것이 불가능했습니다.

  • 별도의 데이터를 추가로 적재하는 것이 master 에 부담을 줌

    1차 가공 데이터 말고도, 외부의 데이터나 외부 툴을 위한 데이터를 적재해야할 필요성이 있습니다. 예를 들면 AppsFlyer 같은 툴의 raw 데이터를 우리의 데이터와 결합해서 사용한다든지, Tableau 를 사용하기 위한 임시 데이터를 저장한다든지 하는 경우들이 있습니다. 이런 데이터들을 master 를 통해 적재하면 그것 자체로도 성능에 부담이 되지만, 서비스 운영과 관련없는 데이터로 인해 DB 에 문제가 생길 수 있는 가능성을 열어놓는 것도 큰 리스크입니다.
    더불어 데이터 분석 성능을 향상시킬 수 있는 table index 가 있더라도 서비스 운영에서는 필요하지 않는 것이라면 이 역시도 서비스 성능에 부하를 주기 때문에 사용하기에 애매했습니다.

  • 권한 분리가 되지 않음

    Read replica 는 master 와 데이터가 완전히 똑같기 때문에 사용자 권한도 똑같을 수밖에 없습니다. read replica 를 읽을 수 있는 권한을 주면 master 에도 접속해서 작업을 수행할 수 있습니다. read 할 수 있는 권한만 주면 데이터가 변조 되는 문제는 없겠지만, 실수로라도 master 에 접속해서 부하를 줄 수 있다는 문제가 있습니다.

  • 데이터를 다루기가 까다로움

    이 부분은 저희의 현재 상황에 따른 부가적인 부분인데요. 현재 저희는 MySQL 5.7 을 사용하고 있습니다. MySQL 5.7 까지는 아직 CTE(common table expression) 이 없어서 데이터 분석을 위한 복잡한 쿼리를 작성하기가 까다롭습니다. 하려면 다 할 수는 있지만 1차 가공 데이터를 저장할 수 있다면 훨씬 문제가 쉬워집니다.

탐구

위와 같은 문제를 해결하기 위해서는 어떻게 하는 것이 좋을까요?

제대로 된 Data Warehouse 를 별도로 구성할 수 있으면 좋겠지만, 데이터를 처음 제대로 분석하려고 할 때는 어떤 데이터가 어떻게 필요한지도 감이 안오기 때문에 바로 Data Warehouse 를 구성하는 것은 힘들기도 하고 비효율적인 경우도 많습니다.

그래서 이래저래 고민하다가 Database Replication 의 원리를 생각해보았을 때 굳이 write 가 불가능할 이유는 없을 것 같다는 생각이 들었습니다👀. 그래서 찾아보니 실제로 가능했습니다!

https://aws.amazon.com/premiumsupport/knowledge-center/rds-read-replica/
(Amazon Aurora 는 해당되지 않습니다)

이렇게 하면 위의 여러가지 문제가 해결됩니다.

  • 데이터 분석용 쿼리의 퍼포먼스가 비효율적 → 1차 가공 데이터를 적재하여 데이터 분석용 쿼리의 퍼포먼스가 향상
  • 별도의 데이터를 추가로 적재하는 것이 master 에 부담을 줌 → master 부담 없이 별도의 데이터를 추가 적재 가능
  • 권한 분리가 되지 않음 → 별도의 계정 생성해서 권한 분리 가능
  • 데이터를 다루기가 까다로움 → 1차 가공 데이터를 적재하여 좀 더 쉬운 데이터 처리 가능

기존보다 훨씬 나은 방법이었기 때문에 바로 적용을 해보았습니다.

구현

한 줄 요약: read replica 에서 parameter group 의 read_only 옵션을 false (0) 로 변경하면 writable replica 가 됩니다!

Amazon RDS - Parameter groups 을 눌러서

RDS 에서 기본으로 제공하는 paramter group 의 설정을 살펴보겠습니다.

read_only parameter 가 0, 1, {TrueIfReplica} 의 값을 가질 수 있고, 기본으로 {TrueIfReplica} 로 설정되어있는 것을 보실 수 있습니다. replica 인 경우에는 true 라는 의미겠죠. 즉, replica 는 기본적으로 read-only 속성을 가집니다.

이제 writable replica 를 위한 parameter group 을 만들어보겠습니다. Create parameter group 을 선택하시고

이름은 mysql-57-writable-replica 로 지었습니다.

생성된 parameter group 을 선택하고 Edit 를 눌러서

read_only parameter 를 0(false) 으로 선택하고 Save changes 를 눌러 저장합니다.

이제 이 parameter group 을 replica instance 에 적용해주시면 writable replica 가 완성됩니다!

주의

  • Conflict
    • replication 은 기본적으로 master 에서 발생한 변화를 그대로 수행하는 방식입니다.
    • 따라서 replication 되고 있는 데이터를 건드리면 master 에서의 변경을 그대로 수행하다가 conflict 가 발생할 수 있습니다.
      ex) master 에 INSERT 된 id = 10 의 row 를 replication 하려는데, replica 에 이미 id = 10 의 row 가 존재하는 경우
    • 이 경우 replication 이 멈추기 때문에, 추가로 적재할 데이터는 instance 안에서 별도의 Database 를 만들어서 사용하는 것이 좋습니다.
    • 만약 conflict 가 발생해서 replication 이 중지되었다면, 해당 문제를 해결 후 instance 를 재부팅 하여 replication 을 재개시킬 수 있습니다.
      • SHOW SLAVE STATUS query 를 통해 어떤 문제로 replication 이 중지되었는지 확인할 수 있습니다.
      • 해당 문제를 해결한 후 AWS RDS 는 instance restart 를 하여 replication 이 재개할 수 있습니다.
  • USER
    • USER 도 DB 에 저장된 값이기 때문에 replication 이 됩니다.
    • writable replication 에 만든 USER 와 동일한 이름의 계정이 나중에 master 생성되어도 conflict 가 생기기 때문에 USER 의 이름은 절대 겹치지 않도록 만드시는 것을 추천합니다. ex) json.writable
    • 권한도 위에서 얘기한 것처럼 별도의 database 만 수정할 수 있도록 주면 conflict 가능성을 최소화할 수 있습니다.

소고

이렇게 writable replica 를 이용해서 간단하게 데이터 분석용 DB 를 만들어보았습니다. 이런 구성 방식에 단점이 있는 것인지, 키워드를 잘못 생각하고 있는 것인지 writable replica 에 대한 자료가 거의 없어서 글을 적어보게 되었습니다. 제가 모르고 있는 내용이 있다면 피드백 부탁드립니다!

저희는 writable replica 에 여러가지 데이터를 추가로 쌓아 서비스 데이터와 엮어서 점점 저희에게 필요한 데이터를 학습해나가고 있고, 이것이 어느 정도 완료되면 좀 더 제대로 된 Data Warehouse 를 구성해 나갈 계획입니다.

기타

참고로 Postgres 의 경우에는 9.0 부터 지원이 된 Logical Replication 을 이용해서 비슷한 구성이 가능할 것으로 생각됩니다.

https://www.postgresql.org/docs/current/logical-replication.html