운영 DB를 지키는 읽기 전용 미러

AI 예측 분석
운영 DB를 지키는 읽기 전용 미러
2026.06.18 · 3분 읽기
대학 역량관리 플랫폼을 개발하면서 가장 먼저 해결해야 했던 문제는 화면이 아니라 데이터 조회 구조였다.
학사 데이터는 학교의 IBM DB2에 저장되어 있었다. 운영 DB를 직접 조회하면 화면 하나를 여는 데 5분 이상이 걸렸다. 수업 등록과 성적 처리를 담당하는 운영 DB에 서비스 조회를 직접 연결하는 구조는 적절하지 않았다.
그래서 학교 데이터를 읽기 전용 PostgreSQL 미러 DB로 동기화하고, 서비스의 모든 조회는 미러에서 수행하도록 설계했다.
왜 스냅샷을 선택했나
변경된 데이터만 반영하는 증분 동기화를 먼저 검토했다. 하지만 학교에서 제공한 데이터는 변경 이력이 없는 View 형태였다. View에는 변경 시점을 알 수 있는 타임스탬프나 변경 로그가 없어 증분 동기화를 적용할 수 없었다.
대신 하루 한 번 전체 데이터를 다시 적재하는 스냅샷 방식을 선택했다. 필요한 학년도만 다시 적재한 뒤 기존 데이터를 교체했다.
구현은 단순했지만 운영은 더 안정적이었다. 같은 데이터를 여러 번 적재해도 항상 동일한 결과를 만들 수 있고(멱등성), 이전 데이터와 새 데이터가 섞이지 않아 정합성을 유지하기도 쉬웠다.
하루 한 번 동기화
동기화는 하루 한 번 배치 작업으로 수행했다. 사용량이 가장 적은 새벽 시간(KST 03시)에 IBM DB2 데이터를 PostgreSQL 미러에 다시 적재해 최신 상태를 유지했다.
실시간 반영은 포기해야 했다. 최신 데이터는 최대 하루 정도 늦게 반영된다. 하지만 학사·역량 데이터는 초 단위 최신성이 필요하지 않아 하루 한 번의 동기화로도 충분했다.
반복되는 집계는 미리 계산한다
미러를 구축했다고 해서 모든 조회가 빨라지는 것은 아니었다. 화면마다 학과 평균이나 전체 분포 같은 집계를 매번 계산하면 여전히 응답 시간이 길어진다.
자주 사용하는 집계는 미리 계산해 캐시에 저장하고, 나머지는 지연 로딩으로 분리했다.
이 구조를 적용한 결과 조회 시간은 5분 이상에서 1초 이내로 줄었고, 같은 화면과 같은 조건에서 체감 성능은 300배 이상 개선됐다.
미러 계층이 만든 변화
읽기 전용 미러는 조회 속도를 높이기 위한 계층이 아니라 운영계와 서비스를 분리하는 계층이었다.
서비스는 항상 미러만 조회하고, 반복되는 집계는 캐시에서 처리했다. 서비스 트래픽이 늘어나도 운영 DB에는 영향이 없었고, 원천 데이터 구조가 바뀌더라도 동기화 계층에서 대부분의 변경을 흡수할 수 있었다.
조회 성능을 바꾼 것은 쿼리가 아니라 읽기 구조였다.
다음에 읽을 글
전체 글 보기
브라우저 녹음은 되는데 음성합성 API는 왜 거절할까
브라우저는 WebM·48kHz·스테레오로 녹음하고, 음성합성 API는 WAV·16kHz·Mono·3MB 이하 입력을 요구한다. WebAssembly 트랜스코더를 브라우저에서 필요할 때만 로드해 형식을 맞추고, 보내기 전에 용량을 두 번 검사했다. 기술보다 중요했던 건 둘 사이를 잇는 통합 계층이었다.

잘 돌아가던 렌더러를 갈아엎은 이유
손그림 캐릭터를 실시간으로 움직이는 렌더러는 잘 돌아갔다. 문제는 캔버스 2D 벡터 엔진이라 GPU를 적극 활용하기 어렵다는 점이었다. 코어를 테스트로 고정하고 새 WebGL 엔진을 옆에서 키운 뒤 구 라이브러리를 걷어냈다. 잘 돌아가는 코드를 버린 이유는 고장이 아니라 구조의 한계 때문이었다.

리그가 없는 그림을 웹캠 포즈로 움직이기
사용자가 그린 그림에는 본도 가중치도 없다. 랜드마크를 관절로 축약하고, 신뢰도에 따라 스무딩을 조절하고, 가려진 관절은 약한 추론으로 메워 웹캠 포즈를 실시간으로 입혔다. 파이프라인을 관통한 원칙은 하나, 불확실성을 버리지 않고 신뢰도로 들고 다니는 것이었다.