샤딩

Sharding

방법

한 서버에 다 담기지 않는 데이터를 정해 둔 기준값에 따라 조각으로 갈라 여러 서버에 나눠 담는 방법입니다.

등장 배경

데이터베이스는 오랫동안 한 대로 버텼습니다. 느려지면 그 한 대의 메모리와 디스크를 키우고, 읽기가 몰리면 같은 내용을 복사한 서버를 붙여 읽기만 그쪽으로 보냈습니다.

그런데 두 가지는 이 방법으로 해결되지 않습니다. 하나는 저장 용량입니다. 문서 표가 8억 줄이 되어 디스크를 2테라바이트까지 채우면, 더 큰 디스크를 살 수는 있어도 한 대가 감당할 크기에는 끝이 있습니다. 다른 하나는 쓰기입니다. 복사본을 몇 대 붙여도 새 글을 받아 적는 일은 원본 한 대가 합니다.

실제로는 조용히 나빠집니다. 표가 커지면 색인이 메모리에 다 올라가지 않고, 그때부터 새 줄을 넣는 시간이 늘어납니다. 어제까지 0.02초였던 저장이 0.4초가 되고, 사용자에게는 저장 버튼이 굼뜬 것으로 나타납니다.

수평 확장, 즉 대수를 늘려 부하를 감당하는 방식은 프로그램 쪽에서 진작 쓰던 수였습니다. 샤딩은 그것을 데이터에 적용한 것입니다. 한 대를 키우는 대신 데이터를 갈라 나눠 담고, 각 서버가 자기 조각만 책임지게 만듭니다.

사용 절차

다섯 단계로 진행하고, 앞의 두 단계가 나머지를 결정합니다.

  1. 샤드 키를 고릅니다. 어느 조각에 넣을지 판단할 때 보는 칸입니다. 문서 표라면 조직 번호가 후보이고, 회원 표라면 회원 번호가 후보입니다. 기준은 하나입니다. 대부분의 질의가 그 값을 알고 들어오는지입니다. 문서 번호만 들고 오는 질의가 많다면 조직 번호로 나눈 조각 전부를 뒤져야 합니다.
  2. 나누는 방식을 정합니다. 번호 구간으로 자르는 방식은 1번부터 100만 번까지를 1번 조각에 두는 식이라 이해하기 쉽지만 최근에 가입한 조직이 한 조각에 몰립니다. 값을 계산해 흩는 방식은 고르게 퍼지는 대신 구간으로 훑는 질의를 못 씁니다.
  3. 조각을 찾아 주는 층을 만듭니다. 질의가 들어왔을 때 어느 서버로 보낼지 정하는 자리입니다. 샤드 키를 계산해 바로 고르거나, 어느 값이 어느 조각에 있는지 적어 둔 표에 물어봅니다. 표를 두는 쪽이 나중에 조각을 옮기기 쉽습니다.
  4. 이미 쌓인 데이터를 옮깁니다. 서비스를 멈추지 않으려면 마이그레이션을 네 걸음으로 나눕니다. 새 글을 옛 서버와 새 조각 양쪽에 함께 쓰고, 과거 데이터를 뒤에서 복사하고, 양쪽 건수와 값을 맞춰 보고, 마지막에 읽기를 새 조각으로 돌립니다.
  5. 운영 절차를 준비합니다. 조각이 여덟 개면 백업도 여덟 벌, 감시 대상도 여덟 벌입니다. 한 조각이 다시 커졌을 때 조각을 늘리고 재분배하는 절차도 미리 적어 둡니다.

적합한 상황과 한계

맞는 자리는 좁습니다. 한 대의 저장 용량이나 쓰기 처리량에 실제로 부딪혔고, 데이터가 자연스러운 경계로 갈라지며, 대부분의 질의가 한 조각 안에서 끝나는 경우입니다. 조직 단위로 쓰는 협업 도구가 이 조건에 맞습니다. 한 조직의 문서를 읽을 때 다른 조직 문서를 함께 볼 일이 없습니다.

한계는 넷입니다.

  1. 조각을 넘는 질의가 어려워집니다. 전체 사용량 합계나 두 조직에 걸친 검색은 조각마다 물어본 뒤 합쳐야 해서, 한 번에 끝났던 일이 여덟 번 묻는 일이 됩니다.
  2. 트랜잭션, 즉 전부 성공하거나 전부 없던 일이 되게 묶는 장치가 한 조각 안에서만 온전합니다. 두 조각에 걸친 작업은 한쪽만 성공한 상태가 남을 수 있어 프로그램이 그 경우를 직접 처리해야 합니다.
  3. 샤드 키를 잘못 고르면 한쪽으로 몰립니다. 조직 번호로 나눴는데 한 대형 고객사가 전체 문서의 30퍼센트를 차지하면 그 조각만 혼자 힘들어져, 나눠 놓고도 한 대가 버티던 시절과 같아집니다.
  4. 되돌리기 어렵습니다. 샤드 키는 데이터 배치뿐 아니라 질의를 만드는 코드 전반에 박힙니다.

그래서 순서가 있습니다. 먼저 인덱스, 즉 검색을 빠르게 하려고 미리 만들어 둔 색인을 정리하고, 자주 쓰는 결과를 따로 얹어 두고, 오래된 데이터를 다른 곳으로 옮겨 봅니다. 이 셋으로도 안 될 때 샤딩을 꺼냅니다.

실무 용례

"이 표는 조직 번호로 샤딩해 뒀으니까 조직 전체를 가로지르는 통계는 따로 모아야 해요."

조각을 넘는 집계는 별도 절차로 처리한다는 뜻입니다.

"샤드 키를 회원 번호로 잡으면 큰 고객사 하나가 한 조각에 몰립니다."

기준 선택이 데이터 분포를 어떻게 망칠 수 있는지 짚는 말입니다.

"지금은 색인 정리로 버티고 샤딩은 다음 분기에 다시 보죠."

더 싼 수단이 남아 있으니 아직 이 방법을 쓸 단계가 아니라는 판단입니다.

페이지덱은 문서 표만 조직 번호로 여덟 조각에 나눠 담았습니다. 회원 표와 권한 표는 작아서 그대로 한 대에 있습니다. 나눈 이유는 문서 저장이 느려졌기 때문이고, 기준을 조직 번호로 잡은 이유는 문서를 읽는 거의 모든 화면이 어느 조직인지를 알고 들어오기 때문입니다.

옮기는 작업에는 3주가 걸렸습니다. 태오가 양쪽에 함께 쓰는 상태로 2주를 두고 건수를 매일 맞춰 본 다음 읽기를 돌렸습니다. 남은 일거리는 전체 사용량 통계입니다. 조각에 흩어진 값을 밤마다 한 표에 모아 두고 화면은 그 표를 읽으니, 전날까지의 숫자를 내주는 대신 저장 속도를 얻었습니다.

흔한 오해

샤딩을 하면 데이터베이스가 전반적으로 빨라진다고 읽는 경우가 가장 많습니다. 서버가 여덟 대가 되니 그만큼 빨라질 것처럼 보입니다. 하지만 빨라지는 것은 한 조각 안에서 끝나는 질의뿐입니다. 조각을 넘는 질의는 여덟 대에 각각 묻고 결과를 합쳐야 해서 전보다 느려집니다. 이 차이를 모른 채 전체 검색을 그대로 두면 문서 저장은 빨라졌는데 검색은 2초에서 6초가 됩니다.

나중에 필요해지면 그때 하면 된다는 생각도 자주 어긋납니다. 미리 나눠 두면 관리할 것이 늘기만 하니 미루는 판단은 대개 맞습니다. 문제는 미루는 값이 커진다는 점입니다. 8억 줄일 때 옮기는 것과 30억 줄일 때 옮기는 것은 복사 시간이 다르고, 그동안 코드에 쌓인 질의 수도 다릅니다. 그래서 실행을 미루더라도 샤드 키만은 미리 정해 둡니다. 어느 칸으로 나눌지 정해 두면 새로 쓰는 질의가 그 값을 늘 들고 다니게 만들 수 있어서, 나중에 나눌 때 코드를 덜 고칩니다.

자주 헷갈리는 용어

용어여러 서버에 무엇을 두는가샤딩과의 차이
복제같은 데이터의 복사본어느 서버에나 전체가 있어 한 대가 죽어도 서비스가 이어지고 읽기를 나눠 보낼 수 있습니다. 대신 전체 용량과 쓰기 부담은 한 대 몫으로 남습니다. 샤딩은 용량과 쓰기를 나누는 대신 한 조각이 죽으면 그 조각만 못 읽게 되어서, 실무에서는 조각마다 복제를 함께 겁니다

같이 보면 좋은 페이지

  • 데이터베이스

    이 방법이 어느 문제를 푸는 수단인지 전체 지형에서 먼저 봅니다

  • 마이그레이션

    실제로 나누는 작업의 대부분을 차지하는 절차를 자세히 봅니다

마지막 업데이트 2026-09-16