DB

DB 성능과 정합성 — 1편: 트레이드오프

·8 min read

개요

이 글에서는 성능(Performance)과 정합성(Consistency)의 트레이드오프를 고려하는 방법을 다룹니다.

개발하다 느끼는 벽

백엔드 개발 시작하면 대부분 DB를 CRUD로 배운다. ORM으로 감싸거나 쿼리를 짜고 Join을 거는 수준으로 웹만한 기능은 만들 수 있다.

하지만 CRUD만 하다보면 이런 질문에는 대답을 못한다 "트래픽이 2배 늘었을 때 왜 쿼리 응답이 10초 넘어가는가" (애플리케이션 단에 병목도 있겠지만, 일단 DB에 병목을 생각해보자.)

DB가 제공하고자 하는 목표

DB를 사용할때는 2가지 목표를 고려해야한다.

  • 성능: 얼마나 빠르게, 얼마나 많은 양을 처리하는가
  • 정합성: 빠르고 많은 데이터를 처리하면서 데이터를 어떻게 문제없이 유지하는가

이 두가지 목표는 보통 반대의 방향을 가르킨다. 성능을 올리기 위해 빠르게 쓰면 데이터가 꼬일 수 있고, 데이터를 꼼꼼히 검수하다 보면 성능(처리 속도)이 떨어진다. 그렇기에 우리는 트레이드 오프를 고려해야한다.

성능과 정합성의 트레이드 오프

역사적으로 문제가 발생했다면 영국을 찍으란 말이 있듯이 트레이드 오프에 원인을 찾고자 한다면 성능을 찍으면 된다. 보통 기술 발전이란게 처음에는 잘 작동하자가 목표였다가 더 잘해보자로 바뀌기 때문이다.

트레이드 오프에 관여하는 요소들

인덱스 아마 CRUD 위주로 일해도 인덱스는 이해하고 있을 것이다. 인덱스를 왜 쓰는가? 빠르게 검색하기 위해서 -> 어떻게 빠르게 검색하는가? 데이터를 색인해서 -> 색인을 하면 뭐가 문제인가? 새로운 데이터 들어올때 색인하는 시간이 걸린다.

즉 인덱스 걸리면 SELECT 시간은 빨라지는데 INSERT, UPDATE, DELETE 작업을 하면 인덱스도 같이 갱신되어야하니 쓰기 속도가 느려진다.

캐싱 SELECT 보다 빠른건 기존에 SELECT 된 결과를 바로 제공하는 방법이다. 이 방법을 위해 보통 REDIS가 사용되는데, DB 조회에 대한 부담이 DB와 Redis 2가지 요소로 나뉘어지니 더 많은 요청을 처리 할 수 있고 특히나 캐시된 데이터 제공은 메모리단에서 이루어지는 경우가 많으니 매우 빠르다.

다만 DB 원본이 바뀌면 캐시 데이터도 갱신이 이뤄져야하는데, 제때 갱신이 안되면 불일치 데이터가 생기는 것으로 정합성이 떨어진다. 성능을 높이는 대신 일정 시간의 정합성 불일치는 허용하는 것이다.

비정규화

흔히 테이블 설계할때 고민을 많이 하게 만드는 부분으로 이론대로 정규화 빡빡하게 하면 데이터 중복이 없어서 정합성이 높다. 다만 실무에서는 무슨 문제가 생기냐 간단한 조회 작업 하고 싶어도 다른 테이블에 join을 걸고 데이터를 가져오는 경우가 빈번하게 발생한다. 자주 쓰는 데이터 정도는 중복을 허용하고 테이블에 미리 합쳐두면 조회는 빠르지만, 중복이 발생한거니 데이터 관리 포인트가 늘어나는 것이다.

예시를 하나 들자면 주문 테이블과 상품 테이블이 있을때 주문 테이블에 상품 ID만 저장해두면 매번 주문내역 볼때마다 상품명을 join해서 가져와야한다. 상품명에 대해 중복을 허용하면 주문 테이블 내에서 주문내역 출력이 가능한 것이다.

정합성의 세 가지 수준

트레이드 오프를 고려했다면 정합성의 수준을 결정해야한다.

강한 정합성 모든 읽기가 가장 최신 쓰기를 반영한다. 가장 안전하지만, 가장 느리기에 계좌이체처럼 1원도 오차가 허용되지 않는 곳에 쓴다.

최종 정합성 지금 당장은 최신 데이터가 아닐 수 있지만, 시간이 지남에 따라 최종적으로는 일치한다. 캐시를 쓰는 경우 원본 데이터가 캐시에 반영되기까지 짦은 텀동안 데이터 불일치가 발생하는 것을 생각하면 된다. 정합성이 크리티컬하지 않는, 소셜에 좋아요 수 등의 수십초의 오차가 허용되는 곳에 쓴다.

약한 정합성 일기가 최신 쓰기를 보장하지 않는다. 실시간 스트리밍이나 멀티플에이어 게임처럼 성능이 극도로 중요한 곳에 쓴다.

뭘 골라야 할까?

원래 상황에 정답은 없고 최선의 선택이 있다고 본다. 성능이 좋아지만 보통 정합성이 내려가는 구조이니 상황에 맞춰서 트레이드 오프를 고려해야한다.

의식적으로 설계 결정할때가 오면 성능과 정합성을 고민하며 저울질 하면 된다.

← Previous
RDBMS와 B+Tree