본문으로 바로가기

08

로드밸런싱 알고리즘

똑같이 나누는 것이 공평한 것은 아니다

먼저 보면 좋은 강의: 로드밸런서

단계별로 보기

스페이스바로 재생/정지, 좌우 화살표로 단계 이동, R로 처음으로 돌아갑니다.

대기 중1 / 4 단계 — 똑같이 나눴는데 한 대만 죽는다

라운드 로빈이 초당 150건을 세 서버에 정확히 50건씩 나눕니다. 숫자로만 보면 완벽하게 공평합니다. 그런데 구형 서버 C는 초당 10건이 한계입니다. 나머지 40건을 매초 버립니다. 신형 서버 두 대는 여유가 넘치는데도 말입니다. 똑같이 나누는 것은 공평한 것이 아닙니다.

이 강의를 마치면

  • 라운드 로빈이 서버 성능이 다를 때 왜 실패하는지 설명한다.
  • 최소 연결 우선이 성능 차이를 자동으로 흡수하는 원리를 설명한다.
  • 일관된 해시가 필요한 상황과 그 대가를 구분한다.
  • 알고리즘 선택이 정답 찾기가 아니라 상황에 맞추는 일임을 이해한다.

나누기는 나누는데, 어떻게 나눌 것인가

로드밸런서가 요청을 나눠준다는 것은 배웠습니다. 그런데 어떤 규칙으로 나눌까요? 이 규칙을 로드밸런싱 알고리즘이라고 합니다.

놀랍게도 이 선택 하나가 서비스를 살리기도 하고 죽이기도 합니다.

1. 라운드 로빈 — 순서대로

가장 단순합니다. 1번, 2번, 3번, 1번, 2번, 3번… 순서대로 돌립니다.

잘 동작합니다. 서버 성능이 같고 요청 무게가 비슷하다면 이보다 나은 게 없습니다. 기억할 것도 없고, 계산할 것도 없고, 고장 날 것도 없습니다. 대부분의 시스템은 여기서 끝내도 됩니다.

그런데 서버가 제각각이면

현실에서는 서버가 똑같지 않습니다. 3년 전에 산 서버와 지난달에 산 서버가 같이 돌아갑니다.

서버 A (신형) : 초당 160건 처리 가능
서버 B (신형) : 초당 160건 처리 가능
서버 C (구형) : 초당 10건 처리 가능

초당 150건을 똑같이 나누면 각 50건입니다. A와 B는 여유롭습니다. C는요? 초당 40건씩 버립니다.

전체 유실률이 27%입니다. A와 B가 놀고 있는데도 사용자의 4분의 1이 오류를 봅니다.

여기서 핵심을 짚습니다. 똑같이 나누는 것은 공평한 것이 아닙니다. 병약한 사람과 장정에게 똑같은 무게의 짐을 지우면, 그것은 공평이 아니라 병약한 사람을 쓰러뜨리는 일입니다.

요청 무게가 다를 때도 같은 일이 벌어진다

서버가 전부 똑같아도 문제가 생길 수 있습니다. 요청마다 무게가 다르기 때문입니다.

  • "로그인 상태 확인" — 1밀리초
  • "지난 3년 매출 보고서 생성" — 4초

라운드 로빈은 요청의 무게를 보지 않습니다. 그냥 숫자를 셉니다. 운 나쁜 서버에 무거운 요청이 연달아 가면, 그 서버만 죽어갑니다. 요청 수는 정확히 똑같이 나눴는데도요.

2. 최소 연결 우선 — 지금 가장 한가한 곳으로

발상을 바꿉니다. 횟수를 세지 말고, 지금 몇 개를 붙들고 있는지를 봅니다. 그리고 가장 적게 붙들고 있는 서버에 보냅니다.

마법 같은 일이 벌어집니다. 아무도 서버 성능을 알려주지 않았는데 알아서 맞춰집니다.

  • 구형 서버 C는 처리가 느리니 요청을 오래 붙들고 있습니다.
  • 붙들고 있는 수가 많으니 로드밸런서가 C를 잘 고르지 않습니다.
  • 결과적으로 C에는 C가 감당할 수 있는 만큼만 갑니다.
라운드 로빈  : A 50  B 50  C 50 → C가 40건 유실
최소 연결    : A 70  B 70  C 10 → 유실 없음

같은 서버, 같은 트래픽입니다. 규칙 한 줄을 바꿨을 뿐인데 유실이 사라졌습니다. 서버를 새로 사는 것보다 훨씬 싼 해결책입니다.

실무에서 "느린 서버 한 대가 전체를 갉아먹는" 상황의 상당수가 이것으로 풀립니다. 느린 이유가 무엇이든 상관없습니다. 구형이든, 이웃 프로세스가 CPU를 먹고 있든, 디스크가 아프든, 결과적으로 느리면 알아서 덜 받습니다.

3. 일관된 해시 — 같은 사람은 같은 곳으로

세 번째 규칙은 목적이 아예 다릅니다. 균형이 아니라 일관성을 위한 것입니다.

사용자 ID를 계산해서 "이 사람은 항상 2번 서버"로 고정합니다. 왜 이런 걸 할까요?

주로 캐시 때문입니다. 2번 서버가 이 사용자의 데이터를 이미 메모리에 갖고 있다면, 같은 서버로 계속 보내는 편이 훨씬 빠릅니다. 매번 다른 서버로 가면 매번 처음부터 읽어야 합니다.

하지만 대가가 큽니다.

문제설명
불균형인기 사용자가 배정된 서버만 바쁘다
유연성 상실그 서버가 아파도 다른 곳으로 못 보낸다
앞 강의의 함정서버가 상태를 들고 있게 된다

마지막 것이 중요합니다. 일관된 해시는 "상태 없는 서버"의 반대 방향입니다. 그래서 "그냥 캐시 히트율이 좀 좋아지면 좋겠다" 정도의 이유로 쓰면 안 됩니다. 분명한 이유가 있을 때만 씁니다.

정리 — 어떻게 고를 것인가

상황선택
서버가 같고 요청 무게도 비슷하다라운드 로빈. 고민하지 마세요
서버 성능이 제각각이다최소 연결 우선
요청 무게 편차가 크다최소 연결 우선
서버별 캐시를 살려야 한다일관된 해시 (대가를 감수하고)
서버 성능 차이를 정확히 안다가중 라운드 로빈

가장 중요한 조언은 이것입니다. 기본은 라운드 로빈입니다. 그리고 어느 한 서버만 이상하게 힘들어하는 것이 보이면, 그때 최소 연결 우선을 떠올리세요. 미리 복잡하게 갈 이유가 없습니다.

직접 해보세요

아래 과제에는 신형 서버 두 대와 구형 서버 한 대가 있습니다. 서버를 추가할 수는 없습니다. 있는 것만으로 유실을 없애 보세요.

이 강의가 단순화한 것

교육용 모형은 언제나 무언가를 생략합니다. 무엇을 생략했는지 아는 것도 학습의 일부입니다.

전제한 것

  • 로드밸런서는 요청을 어느 서버에 보냈는지 기억하고, 응답이 오면 그 기록을 지운다. 이 기록이 '연결 수'다.
  • 버려진 요청은 응답이 돌아오지 않으므로 로드밸런서의 연결 수에서 줄어들지 않는다. 그래서 계속 버리는 서버는 후보에서 더 강하게 밀려난다.
  • 일관된 해시는 이 강의에서 개념만 설명하고 그래프로 재현하지 않는다.
  • 가중 라운드 로빈의 가중치는 사람이 미리 정해줘야 하며, 이 강의에서는 조정하지 않는다.

다루지 않은 것

  • 일관된 해시 링의 구조와 가상 노드
  • 서버 추가·제거 시 해시 재배치 비용
  • EWMA·Peak EWMA 같은 지연 기반 알고리즘
  • 클라이언트 측 로드밸런싱

더 읽을거리: Google SRE Book — Load Balancing in the Datacenter

이제 직접 만들어 보세요

읽어서 아는 것과 만들어서 아는 것은 다릅니다. 컴포넌트를 배치하고 트래픽을 흘려서 실제로 동작하는지 확인해 보세요.

실습 과제 열기

이 강의에 물어보기

하루 5번

이 강의 본문만 근거로 답합니다. 강의에 없는 내용은 지어내지 않습니다.