ASHD Dev_Blog

7. 유일 ID 설계 [SYS-study]

이재룡
이재룡Jul 2, 2025

[ 0. 수직적 규모 확장 vs 수평적 규모 확장 ]

Scale up - 수직적 : 서버의 성능 (고사양 자원)

Scale out - 수평적 : 더 많은 서버

[ 1. 다중화 ]

로드 밸런서

  • 클라이언트는 로드 밸런서의 public IP로 접속 (서버 자체와 연결 X)
  • 로드 밸런서가 내부 서버들과 연결되는 private IP는 내부 통신만 (인터넷 접속 X)

웹 서버 다중화

  • 웹 계층에서는 트래픽 분산 및 고가용성만 신경 쓰면 됨
    • 고가용성 (Higfh Availability) : 다중으로 서버를 구성하여 하나의 서버가 다운 되더라도 시스템 전체는 정상 작동되도록

DB 서버 다중화

  • 트래픽 분산 및 고가용성 이외에도, 데이터 계층에 대한 처리가 필요

Master-Slave(주-부 다중화 모델) : 원본 + 사본 저장 방식

  • 쓰기 연산은 Master에서만 지원
  • Master의 수는 Slave의 수보다 적거나 같다.
  • query의 병렬 처리률 증가
👉
운영 중 Master 서버가 다운되었을땐?
Master가 다운되면, Slave들에 저장된 데이터가 최신이 아닐 수 있기 때문에
복구 스크립트를 통해 복구해서 slave에 집어넣은 이후, 해당 slave서버를 master로 승격
💡
- 방법 1 : “multi-master” 모든 서버가 동시에 읽기/쓰기 가능하도록 설정하는 방법

⇒ 하나의 마스터가 다운되더라도 다른 마스터가 즉시 대응 가능하나,
충돌 관리와 데이터 정합성 유지가 어렵고 복잡

💡
- 방법 2 : “circular replication” → 여러 노드가 원형 구조로 서로 데이터를 복제하도록 구성
  • "누가 누구에게 복제할지"는 처음 구성할 때 미리 설정
  • 각 서버는 자기 앞 또는 뒤에 있는 특정 서버 한 곳과 만 복제 관계를 맺음
  • 다운되면 그 서버에 복제 데이터를 전달했던 서버를 Master로 승격

[ 2. Latency 개선 ]

캐시(DB 부하 감소)를 사용하거나 CDN을 통해 응답 시간을 빠르게

콘텐츠 전송 네트워크 (CDN)

  • CDN 서버 : 자주 요청할 거 같은 데이터를 원본 서버에서 가져오는게 아니라, CDN서버에 저장해놓고, 클라이언트가 CDN 서버로 접속하도록 설정
  • CDN 서버가 다운 되었을 때, 원본 서버에서 가져갈 수 있도록 구성 필요
    • JS 처리 :
      <img src="https://cdn.example.com/img/logo.png" onerror="this.src='https://origin.example.com/img/logo.png'">
      javascript
    • Nginx FallBack
      location /img/ {
          proxy_pass https://cdn.example.com;
          error_page 502 504 = @fallback;
      }
      
      location @fallback {
          proxy_pass https://origin.example.com;
      }
      javascript

[ 3. 대규모 확장 ]

Stateless - 무상태 웹 계층

세션 데이터와 같은 상태 정보를 웹 계층에서 가지고 있으면, 확장한 새 서버에서는 이용 불가

DB와 같은 지속형 저장소에서 관리하고, 필요할 때 서버로 전달

  • 단순, 안전, 쉬운 확장



다중 데이터 센터 - 대규모 서비스

보통은 geoDNS-routing을 통해 지리적으로 가까운 데이터 센터로 트래픽이 연결

동기 복제 (Synchronous Replication)

데이터 센터에 데이터가 추가되면 연결된 모든 데이터 센터에 복제 완료된 후에 클라이언트에 응답

  • 모든 데이터 센터의 데이터가 항상 완전히 동일
  • 거리만큼 응답 지연(latency) 발생
  • 활용 분야: 금융, 은행 등 정합성이 중요한 서비스

비동기 복제 (Asynchronous Replication)

한 데이터 센터에서 데이터를 먼저 저장하고 응답 이후 백그라운드로 다른 데이터 센터에 복제

  • 빠른 응답 속도
  • 일시적으로 데이터 불일치 발생 가능
  • 활용 분야: 넷플릭스, 유튜브 등 읽기 위주 서비스

[ 4. 메시지 큐 : 서버 간 결합을 느슨하게 ]

MSA : 현재는 모놀리식 구조가 아닌, 기능 별로 분리해서 각 기능별 동작 및 배포 확장이 가능하도록 설계

  • 이 때 “결제”서비스가 들어왔다고, “배달”서비스를 직접 호출하게 되면,
    • 의존도 높아짐
    • 장애 전파

    ⇒ 직접적으로 연결하는 순간 MSA의 의미가 없어짐

    해결책 : 메시지 큐에 넣고, 필요할 때, 이후 서비스들에서 꺼내서 사용

메시지 큐 : 모손실을 보장하는 비동기 통신 컴포넌트

  • 비동기적
  • 버퍼 역할

동작 과정

  1. producer가 메시지 발행 → 메시지 큐에 들어감
  1. subscriber가 구독하고 있는 토픽의 메시지를 알림받고
  1. 이를 받아서 사용

    producer와 실제 연결 없이, 심지어 producer가 다운되어 있어도, 메시지 수신 가능

    ⇒ 결과적으로, 생산자와 소비자가 서로의 처리 속도나 규모에 영향을 받지 않음 → 독립적 서비스 동작 및 확장

[ 5. 샤딩 : 데이터베이스의 수평적 확장 ]

shard : 전체 데이터 중에서 일부만 저장된 데이터베이스나 서버 단위

데이터를 여러 개로 나눠서 저장 (sharding)

  • 샤딩된 데이터는 중복이 없음 (보통 ID를 기준으로 분할 using “%”)

Sharding key(=Partition key) : 각 샤드에 나누는 기준에 되는 키 컬럼 (= user_id)

  1. 데이터 Resharding : 특정 샤드의 공간소모가 빠를 때, 이를 shard exhaustion이라고 부르고 샤드키 계산 함수를 변경 및 샤드 데이터 재분배
  1. celebrity problem : 특정 샤드의 일부 데이터가 호출되는 query가 많아, 해당 샤드에 read 연산에 의한 부하가 몰리는 상태
  1. De-normalization (비정규화) : user라는 하나의 테이블을 샤딩을 통해 나누었기 때문에 조인이 불가능 → 이를 필요한 데이터끼리 묶어 저장하는 비효율적 방식(이미 조인을 진행한 상태로 저장)을 통해 해결

[최종 설계]

  • 로드 밸런서
  • CDN
  • 데이터 센터 및 DB 다중화
  • 메지지큐
  • 캐시
  • tool