인턴으로 일하면서 개발한 API를 테스트하는데 분명 로컬에서는 쿼리가 나가지만 개발 서버에서는 쿼리가 안나가는 문제가 발생했던 적이 있다.
심지어 개발 서버 DB를 로컬 코드와 붙여 실행해보면 쿼리가 잘 나갔다.
# 다소 의역된 코드
1. 모델 생성 & commit
1.5 DB로부터 모델 정보 업데이트
2. if 모델의 개수 >= 5, Update 쿼리 # 문제의 Update 쿼리
로컬 환경에 개발서버 DB를 붙여 실행해보기도 하고..
log를 덕지덕지 찍어보기도 했지만 당시에는 문제를 빠르게 파악하지 못 했다.
제목에도 써놓고 이제와서 강조하는 문제의 원인은 Replication Lag(복제 지연)이다.
이 개념을 이해하기 위해서는 먼저 실 서버의 RDB가 주로 성능을 위해 Master - Slave 구조를 사용한다는 것을 알아야 한다.
이 구조를 간단하게 말하자면 대부분의 요청은 Read 연산에 몰려있으니, 그에 맞게 읽기 전용 DB 서버를 여러개 둔다는 것이다.
이미지 출처: https://server-talk.tistory.com/
이때, 여러가지 복잡한 상황을 피하기 위해 Insert/Update/Delete 등 DB를 변경하는 요청은 모두 하나의 서버에서 처리하고 이 내용을 다른 읽기 전용 서버들에게 전달한다.
문제는 여기서 발생한다.
위에서 작성한 유사 코드를 직접 그린 간단한 그림과 함께 문제가 되는 시나리오를 작성해봤다.
# 다소 의역된 코드
1. 모델 생성 & commit (From Main DB)
2. DB로부터 모델 정보 업데이트 (From Read DB)
3. Main DB => Read DB 복제 완료
4. if 모델의 개수 >= 5, Update 쿼리 # 새로 생성된 모델이 반영되지 않음!
DB단에서 해결하는 방법도 여러가지 있을 수 있지만 코드 레벨에서 해결하는 간단한 방법은 바로
데이터를 Main DB에서 읽는 것이다.
물론 언어마다 방법은 조금씩 다르겠지만 아래 코드처럼 간단히 해결될 것이다.
# 다소 의역된 코드
1. 모델 생성 & commit (From Main DB)
2. DB로부터 모델 정보 업데이트 (From Main DB)
3. Main DB => Read DB 복제 완료 (이제 상관없음)
4. if 모델의 개수 >= 5, Update 쿼리 # 모델 개수 정상 확인
해결 방법이 제일 짧은 것 같아 허무한 감이 없지 않지만, 사실 원인만 제대로 파악하면 고치는건 어렵지 않은 문제라고 생각한다.