느린 게 아니라, 그렇게 정한 겁니다

아샬

“결제했는데 주문 내역에 바로 안 뜨네요.”

흔한 버그처럼 보입니다.
하지만 이건 버그가 아니라 설계 결정의 결과일 수 있습니다.

읽기 부하를 줄이려고 데이터베이스를 복제했고,
그 과정에서 약간의 지연이 생겨 방금 쓴 데이터가 아직 반영되지 않은 거죠.
누군가 “이 정도 지연은 괜찮다”고 정했기 때문에 일어난 일입니다.

문제는 그 결정을 의식적으로 내렸느냐입니다.

다 가질 수는 없다

시스템이 커지면 서버 한 대로는 버티지 못합니다.
읽기 부하를 나누려고 복제하고,
저장 공간이 부족하면 파티셔닝하고,
장애에 대비해 여러 서버에 분산합니다.

그러면 문제가 생깁니다.
서버마다 서로 다른 값을 가집니다.

  • 항상 최신 값을 읽고 싶다 (강한 일관성)
  • 장애가 나도 계속 응답하고 싶다 (가용성)
  • 빠르게 응답하고 싶다 (낮은 지연)

셋이 서로 충돌합니다.
강한 일관성을 보장하려면 서버끼리 조율해야 하고, 조율은 시간이 걸립니다.
일부 서버에 장애가 나면 잠깐 멈춰야 합니다.

결국 이건 무엇을 보장할 것인가가 아니라
무엇을 포기할까의 문제가 됩니다.

방금 쓴 내 데이터는 바로 읽혀야 한다.
하지만 남이 쓴 데이터는 몇 초 늦어도 된다.
이렇게 우리 서비스에 맞게 일관성의 기준을 세우는 것이 설계입니다.

일관성은 한 종류가 아니다

“일관성 있게 해 줘”는 지시가 될 수 없습니다.
일관성에는 여러 단계가 있기 때문입니다.

  • 내가 쓴 값을 이후의 읽기에서 다시 볼 수 있는가(Read Your Writes).
  • 한번 본 최신 상태보다 과거 상태를 다시 보지 않는가(Monotonic Reads).
  • 인과 관계가 있는 사건들의 순서가 보존되는가(Causal Consistency).
  • 쓰기가 완료되면 이후의 모든 읽기가 최신 값을 보는가(Linearizability).

뒤로 갈수록 강한 보장이고, 강할수록 비쌉니다.
필요 이상으로 강한 일관성을 요구하면 시스템은 느려지거나 멈춥니다.
반대로 너무 약하면 아까처럼 “주문 내역에 바로 안 뜨네요”가 일어납니다.

어느 수준이 이 기능에 맞는지 고르는 것.
이게 판단이고, 이 판단은 AI가 대신 내려 주지 않습니다.

나누는 것도, 합치는 것도 결정이다

데이터가 너무 커서 서버 하나로 처리할 수 없다면, 적절하게 나눠야 합니다.
키 범위로 나눌까, 해시로 나눌까?
잘못 나누면 특정 서버에만 부하가 몰리는 문제가 생깁니다.

트랜잭션도 마찬가지입니다.
여러 작업을 한 덩어리로 묶어 전부 성공하거나 전부 실패하게 할지,
아니면 쪼개서 각각 처리하고 최종 일관성을 맞출지.
이건 무엇을 ACID로 보장하고 무엇을 포기할지의 문제입니다.

이 결정에는 정답이 없습니다.
도메인이 무엇을 요구하느냐에 따라 답이 달라집니다.
지금 우리에게 무엇이 더 중요한가”를 물어야 답이 나옵니다.

AI는 묻지 않는다

AI는 복제도, 샤딩도, 트랜잭션도 코드로 만들어 줍니다.
하지만 AI는 “이 데이터는 몇 초 늦어도 괜찮나요?”라고 먼저 묻지 않습니다.
물어보지 않으니 가장 흔한 기본값으로 만들어 버립니다.

그 기본값이 우리 도메인에 맞을 확률은 높지 않습니다.
은행 잔고와 게시글 조회수가 같은 일관성을 요구할 리 없으니까요.

언제 복제하고, 언제 나누고, 어떤 일관성을 어디까지 요구할지.
우리가 이 기준을 갖고 있어야 AI에게 올바르게 지시하고,
AI가 만든 시스템을 검토할 수 있습니다.

무엇을 보장하고 무엇을 포기할지.
이 질문에 답하는 법을 와일드 백엔드에서 함께 다룹니다.