본문 바로가기
ETC/System Design

Read Consistency with Database Replicas by Shopify

by devson 2022. 12. 9.

Shopify의 Read Consistency with Database Replicas에 대한 짧은 분석

 


 

read-heavy한 애플리케이션이 있을 때, DB의 쓰기(Write) 기능에 성능 저하를 막기 위해 DB replication을 구성하는 경우가 많다.

즉, 서버에서 쓰기 쿼리는 Primary DB에 보내되 읽기 쿼리는 Replica DB에 보내는 식으로 구성하여 쓰기 성능에 영향을 덜 주는 것이다.

 

위와 같은 환경에서 Shopify의 포스팅에서 얘기하는 문제는 Replica가 2대 이상으로 구성하였을 때 생기는데,

서버가 여러 번의 쿼리를 통해 조회한 데이터를 aggregation 하는 경우이다.

 

아래와 같이 2대의 Replica DB를 운용하는 경우를 예를 들어보자.

- Replica 1 DB는 복제 지연(replication lag)이 매우 짧은데 반해,

- Replica 2 DB는 네트워크 등의 이슈로 복제 지연이 상대적으로 매우 길다.

 

서버가 첫번째 쿼리는 Replica 1 DB로, 두번째 쿼리는 Replica 2 DB로 보내 각 쿼리의 데이터를 aggregation 한다고 했을 때,

각 Replica DB는 복제 지연으로 인해 서로 데이터가 동일하지 않아 서버에서 데이터 aggregation 시 정확하지 않은 결과가 나올 수 있다.

 

 

그렇기 때문에 아래와 같이 동일한 요청을 처리하기 위한 쿼리들을 같은 Replica DB로 보내면,

앞서 살펴본 Replica DB 데이터 싱크로 인한 문제가 발생하지 않게된다.

Tight Consistency와 같은 strong consistency를 설정하게 되면 Replica DB들의 데이터 싱크는 맞겠지만 성능 저하 문제가 있다.

Shopify는 다른 Consistency 모델들을 비교하여 이와 같은 Monotonic Read Consistency를 채택했다고 한다.

 

 

Shopify에서는 Monotonic Read Consistency를 구현하기 위해 ProxySQL fork에 DB 서버 선택 알고리즘을 수정하였다고 한다.

먼저 서버에서 ProxySQL로 쿼리를 보낼 때 consistent_read_id를 같이 보낸다.

 

그리고 DB 서버를 선택할 때 consistent_read_id의 hash 값을 사용하여 사용될 서버를 선택한다.

 

위와 같은 매커니즘을 통해 같은 consistent_read_id를 사용하는 쿼리들은 모두 동일한 Replica DB로 쿼리를 보내게 되는 것이다.

동일한 요청의 쿼리들에 대해 같은 consistent_read_id를 사용하게 하면 Replica DB의 데이터 싱크로 인한 문제를 피할 수 있게 된다.

 


 

참고:

댓글