대규모 서비스를 지탱하는 기술

저니·2023년 3월 30일
0

읽은 책

목록 보기
1/3

대규모 데이터는 어떤 점이 어려운가?

  • 메모리 내에서 계산할 수 없다.
  • 메모리 내에서 계산할 수 없게 되면 디스크에서 데이터를 검색해야 한다.
  • 하지만 디스크의 I/O는 메모리보다 느리므로 이를 어떻게 대처하는지가 어려운 점이다.

디스크가 느린 이유?

읽는 속도

  • (SSD가 아닌) 원반형의 HDD는 원반을 읽는 헤드가 물리적으로 돌아가면서 데이터를 읽게 된다.
  • 따라서 데이터의 위치까지 헤드를 옮기는 시간, 헤드를 회전시키면서 읽는 시간 등이 소요되게 된다.
  • 읽어야 하는 데이터가 여기저기 분산되어 있다면 읽는시간이 더 오래걸리게 된다. (따라서OS 차원에서는 이를 보완하기 위해 데이터를 보통 4KB단위의 블록으로 구분해서 저장한다)

전송 속도

  • 메모리와 디스크는 CPU와 버스로 연결되어 있는데
  • 메모리 ↔ CPU의 버스는 높은 대역폭의 버스로 연결되어 있고, 디스크 ↔ CPU는 비교적 낮은 대역폭의 버스로 연결되어 있다.

따라서 디스크에서 데이터를 가져오는 것은 메모리에서 가져오는 것 보다 항상 느리다. (책에서는 메모리는 디스크보다 105 ~ 106배 이상 빠르다고 한다.)

시스템 확장성

  • 서버에서 부하로 인해 처리 속도가 낮아지면 시스템을 확장해야 한다.
  • 확장 방법에는 scale out(서버 대수를 늘리기)과 scale up(서버 성능을 높이기) 두 가지가 있다.
  • 주로 저렴하고 확장에 유연하기 때문에 scale out 방법을 많이 쓴다.

부하

부하에는 두 가지 종류가 있다.

  • CPU 부하 → 어플리케이션 서버에서 많은 계산을 수행하는 경우
  • I/O 부하 → 디스크 입출력이 많은 경우. DB에 걸리는 부하

DB 확장성 확보의 어려움

  • 어플리케이션 서버는 주로 CPU 계산만 수행하기 때문에 대수를 늘려서 확장하기 쉽지만 DB는 그렇지 않다.
  • 여러 대의 DB를 둔다고 했을 때, 한 DB에 쓴 데이터를 다른 DB들에 어떻게 동기화 해야 하는지부터 문제가 생긴다.

DB 분산하기

메모리 증설만으로는 부하 감당이 불가능하다면 DB를 파티셔닝 해야한다. 파티셔닝은 국소성을 활용해서 분산할 수 있으므로 캐시가 유효하고, 그래서 파티셔닝은 효과적일 수 있다.

국소성(locality)을 고려하기

  • DB 테이블 단위로 파티셔닝
  • 요청 유형에 따라 파티셔닝
    • ex. bot인지 일반 사용자인지

분산을 고려한 MySQL 운용방법

  1. OS 캐시 활용하기

    • 데이터량 < 물리 메모리 유지.
    • 대량의 데이터를 저장하게 되면 조금의 스키마를 변경하는 것 만으로도 데이터가 기가바이트 단위로 증가할 수 있다.
    • 대량의 데이터를 저장하려는 테이블은 레코드가 가능한 작아지도록 컴팩트하게 설계.
  2. 정규화

    • 정규화를 하면 테이블 용량이 줄어서 좋을 수 있지만
    • 경우에 따라서는 오히려 쿼리가 복잡해서 속도가 떨어질 수 있으므로 trade-off를 고려해야 한다.
  3. DB 인덱스 적절하게 설정하기

    • MySQL의 인덱스는 기본적으로 B+트리 구조 (탐색속도 O(logn)) 이므로 선형 탐색보다 월등히 빠르다.
  4. 확장을 전제로 설계하기

    • 읽기 > 쓰기: 레플리케이션(Replication)
      • DB들을 Master-Slave로 구분해서 쓰기는 Master에, 읽기는 Slave에서 하는 것.
      • Master에 쓰면 Slave가 동일한 내용으로 자신을 갱신한다.
        • 참고) 마스터-슬레이브의 다중화 방법
          • 4개 이상이 한 세트이다.
          • 슬레이브가 하나 고장나면 다른 하나의 슬레이브를 중지시키고 새 서버에 복사해야 하므로 슬레이브가 3개 이상 필요하다.
          • 마스터가 고장나면 슬레이브 중 하나를 마스터로 승격시킨다.
    • 읽기 < 쓰기 라면
      • 테이블을 분할해서 쓰기 작업을 분산
      • RDBMS 대신 Key-Value 저장소 사용하기
        • 단순히 값을 저장하고 꺼내므로, RDMBS의 스키마 검사, 정렬 처리 등의 오버헤드가 전혀 발생하지 않아 빠르다.
    • 서로 JOIN하는 테이블은 분산하지 말 것.
      • 딘, MySQL 5.1 부터는 다른 머신의 테이블과 JOIN할 수 있는 FEDERATE 기능이 존재.

파티셔닝의 단점

  • 어디에 어떤 테이블이 있는지를 확인해야 하므로 운영이 복잡해진다.
  • 대수가 늘어나므로 고장률이 높아진다.

스토리지 선택하기

스토리지 선택의 전제 조건

  • 어플리케이션의 액세스 패턴을 이해하기
    • 평균 크기
    • 최대 크기
    • 신규 추가 빈도
    • 갱신 빈도
    • 삭제 빈도
    • 참조 빈도
    • 신뢰성
    • 허용할 수 있는 장애 레벨

웹 어플리케이션의 프록시/캐시 시스템

  • 포워드(Forward) 프록시
    • 클라이언트가 외부 네트워크에 접근할 때 경유.
    • 클라이언트를 외부에 숨긴다.
  • 리버스(Reverse) 프록시
    • 애플리케이션 서버 앞단에 두는 것.
    • 클라이언트에게 서버를 숨긴다.

📖 소감

2011년에 나온 꽤 오래된 책이라 요즘에는 안쓰는 옛날 지식을 다루고 있을 지 걱정했지만, 기본적인 내용들을 다루고 있어서 문제되지 않았다..! 대규모 웹 서비스에서는 어떤 고민을 하는지에 대해 폭넓게 알 수 있는 좋은 계기.

도서 링크

0개의 댓글