책너두 (데이터 중심 애플리케이션 설계) 2일차 (~26p)

요약

  • 확장성에 대한 내용을 살펴봄.
    • 부하 기술 방법
    • 성능 기술 방법
    • 부하에 대응하기 위한 접근 방법
  • 유지보수성에 대한 내용을 살펴봄.
    • 운용성
      • 운영 상의 편리함 만들기
    • 단순성
      • 복잡도를 낮추기
    • 발전성
      • 시스템 요구사항의 변경에 유연하게 하기

발췌

  • 부하는 부하 매개변수 숫자로 나타낼 수 있음. (p11)
  • 가장 적합한 부하 매개 변수 선택에 따라 시스템 설계가 달라짐. (p11)

메모

확장성

  • 확장성은 증가한 부하에 대처하는 시스템 능력을 설명하는데 사용하는 용어임.

부하 기술하기

  • 시스템의 현재 부하를 간결하게 기술할 수 있어야 함.
    • 부하 성장 질문(ex: 부하가 2배가 되면 어떻게 될까?)을 논의할 수 있기 때문
  • 부하는 부하 매개변수(load parameter) 라 부르는 몇 개의 숫자로 나타날 수 있음.
    • 시스템 설계에 따라 부하 매개변수의 선택이 달라짐.
  • ex) 트위터(Twitter)를 예로 들어보자. 트위터의 주요 두 가지 동작은 다음과 같음.
    1. 트윗(tweet) 작성 → user 가 follower 에게 새로운 메시지 게시 (평균 초당 4.6k 요청)
    2. 홈 타임라인(timeline) → user 는 follow 한 사람이 작성한 tweet 을 볼 수 있음. (평균 초당 300k 요청)
  • 트위터의 확장성 문제는 팬 아웃(fan-out) 에서 나온다.
    • 팬 아웃이란, 다른 게이트의 출력에 배속된 논리 게이트 입력의 수를 뜻함. (즉, 내가 팔로우한 사람이 트윗을 작성하는 수에 배가 되는 것임)
    • 이 동작을 구현하는 방법은 크게 2가지 임.
      1. 관계형 스키마를 이용하여 여러 테이블을 조인
      2. 개별 사용자의 홈 타임라인 캐시를 사용
        • 즉, user 가 트윗을 작성하면, user 를 팔로우하는 사용자를 모두 찾아서 각 팔로워읭 홈 타임라인 캐시에 새로운 트윗을 삽입함.
    • 트위터는 접근 방식 1을 사용했었는데, 시스템이 홈 타임라인 질의 부하를 버텨내는 것이 힘들었음.
    • 따라서, 접근 방식 2로 전환하였고, 홈타임라인에서 요청하는 수가 트윗 작성 요청으로 옮겨졌기에 훨씬 잘 동작함.
      • 즉, 쓰기 시점에 더 많은 일을하고, 읽기 시점에 적은 일을 한 것이 바람직함.
      • 하지만, 접근 방식 2 는 트윗 작성에 많은 부가 작업이 필요.
        • 만약, 어떤 사용자의 팔로워가 3천만명이 넘으면, 단일 트윗으로 인해, 홈 타임라인에 3천만건 이상의 쓰기 요청이 될 수 있음.
  • 트위터의 예시를 봤듯이, 여기서 부하 매개변수는 팬 아웃이 부하를 결정하기에, 확장성 논의할 때 핵심 부하 매개변수가 됨.
  • 트위터의 시스템 최종 전개는, 접근 방식 1, 2를 혼합하여 사용함.
    • 사용자 수가 너무 많은 경우 접근 방식 1을 사용하도록 하여 좋은 성능을 유지함.

성능 기술하기

  • 시스템 부하를 기술하면 부하가 증가할 때 어떤 일이 일어나는지 조사할 수 있음.
    1. 부하 매개변수를 증가시키고, 시스템 자원은 유지하면, 시스템 성능은 어떻게 영향을 받을 것인가?
    2. 부하 매개변수를 증가시키고, 성능이 유지되길 원한다면 자원을 얼마나 늘려야 할 것인가?
  • 위 두 질문의 답을 하려면 성능 수치가 필요함.
    • 처치량(throughput) : ex) 하둡
    • 응답 시간(response time) : ex) 온라인 시스템
  • 클라이언트의 동일한 요청에도, 응답 시간은 다름.
    • 응답 시간을 분포로 생각해야 함.
    • 응답 시간 분포에서, 가끔 오래 걸리는 특이 값(outlier)도 생각해야 함.
      • 아래는 지연에 대한 다양한 원인들임.
        • 백그라운드 프로세스 컨텍스트 스위치
        • 네트워크 패킷 손실, TCP 재전송
        • 가비지 컬렉션 휴지
        • 디스크에서 읽기 강제하는 페이지 폴트
        • 서버 랙의 기계적인 진동
        • 등등..
  • 보통은 평균 응답 시간을 살피는게 일반적임.
    • 하지만, 평균보다는 백분위(percentile) or 중앙값(median)를 사용하는게 더 좋음.
      • 중앙값은 50분위로, p50으로 축약함.
    • 평균은 실제 사용자가 얼마나 실제 지연을 경험했는지 알 수 없기 때문
    • 특이 값에 대한 체크를 위해, 95분위, 99분위, 99.9 분위를 사용함(p95, p99, p999)
  • 꼬리 지연 시간(tail latency) 으로 알려진 상위 백분위 응답시간은 서비스의 사용자 경험에 직접적인 영향을 주기 때문에 중요함.
    • 최상위 백분위 사람의 고객 만족도와, 그에 따른 최적화 작업 비용에 대한 트레이드 오프가 존재함.
  • 백분위는 서비스 수준 목표(service level objective, SLO), 서비스 수준 협약서(service level agreement, SLA)에 자주 사용됨.
    • 기대 성능, 서비스 가용성을 정의하는 계약서에도 자주 등장함.
  • 큐 대기 지연(queueing delay)은 높은 백분위에서 응답 시간의 상당 부분을 차지함.
    • 소수의 느린 요청 처리만으로 후속 요청 처리가 지체됨
    • 이를, 선두 차단(head-of-line blocking) 이라고 함.
    • 후속 요청이 빠르게 처리되도, 앞선 요청이 처리되는 시간이 늦기에, 클라이언트는 전체적으로 응답 시간이 느리다고 생각함.
    • 따라서, 클라이언트 측 응답 시간 측정도 중요함.

부하 대응 접근 방식

  • 확장성
    • 용량 확장(scaling up) = 수직 확장(vertical scaling)
      • 강력한 장비
    • 규모 확장(scaling out) = 수평 확장(horizontal scaling)
      • 다수의 낮은 사양 장비에 부하 분산
      • 비공유(shared-nothing) 아키텍처라 부름.
  • 일부 시스템은 탄력적임(elastic)
    • 부하 증가를 감지하여 컴퓨팅 자원을 자동으로 추가할 수 있음.
  • 분산 시스템은 복잡도가 높아, 데이터베이스를 분산으로 만들어야 하는 고가용성 요구가 있을 때 까지는 단일 노드에 데이터베이스를 유지하는 것(scale up)이 최근까지의 통념임.
  • 대규모로 동작하는 시스템 아키텍처는, 해당 시스템을 사용하는 애플리케이션에 특화되어 있음.
    • 범용적이고, 모든 상황에 맞는 확장 아키텍처는 없음.
    • 아키텍처를 결정하는 요소
      • 읽기 양
      • 쓰기 양
      • 저장할 데이터 양
      • 데이터 복잡도
      • 응답 시간 요구사항
      • 접근 패턴
    • 특정 애플리케이션에 적합한 확장성을 갖춘 아키텍처 주요 동작이 무엇이고, 잘 하지 않는 동작이 무엇인지에 대한 가정을 바탕으로 구축함.
      • 이게 곧 부하 매개변수가 됨.

유지보수성

  • 소프트웨어 비용은 유지 보수 비용이 대부분임.
  • 레거시 시스템을 유지보수 하는 것은 하기 싫다.
  • 유지 보수하며, 고통을 최소화하며 레거시 소프트웨어를 만들지 않게 소프트웨어를 설계할 수 있음.
    • 소프트웨어 시스템 설계 원칙 3가지
      1. 운용성(operability) : 시스템을 원활하게 운영할 수 있도록 쉽게 만들 것
      2. 단순성(simplicity) : 시스템 복잡도를 제거, 새로운 엔지니어가 시스템을 이해하기 쉽게 만들 것
      3. 발전성(evolvability) : 엔지니어가 시스템을 쉽게 변경할 수 있게 할 것.

운용성: 운영의 편리함 만들기

  • 운영 중, 일부 측면은 자동화할 수 있고, 자동화 해야 한다.
    • 자동화의 처음 설정과, 제대로 동작하는지 확인하는 일은 사람의 몫임.
    • 운영팀이 필수로 있어야 함.
    • 좋은 운영팀은 일반적으로 다음 작업을 책임짐
      • 시스템 상태 모니터링, 상태가 좋지 않은 경우 빠르게 서비스 복원
      • 시스템 장애, 성능 저하의 문제 원인 추적
      • 보안 패치, 소프트웨어 플랫폼 최신 상태 유지
      • 서로간의 시스템에 영향을 어떻게 주는지 확인, 문제가 생길 수 있는 변경 사항은 사전 차단
      • 예측가능한 문제를 미리 발견하여 해결 (ex: 용량)
      • 배포, 설정 관리를 위한 모범 사례, 도구 마련
      • 등등 … (p19)

단순성: 복잡도 관리

  • 프로젝트가 커짐에 따라 시스템은 매우 복잡하고 이해하기 어려움
    • 복잡도는 다양한 증상으로 나타남.
      • 상태 공간 급증
      • 모듈 간 강한 커플링
      • 복잡한 의존성
      • 일관성 없는 명명과 용어
      • 성능 문제 해결을 목표로 한 해킹
      • 임시방편으로 문제를 해결한 특수 사례
    • 이러한 복잡도 때문에 예산과 일정이 초과되기도 함.
    • 따라서, 단순성은 시스템 구축에 핵심 목표여야 함.
  • 추상화를 통해 구현에서 발생할 복잡도 제거 가능.
    • 세부 구현을 숨길 수 있음.
    • ex) 고수준 프로그래밍 언어는, 기계 언어, CPU 레지스터, 시스템 호출을 숨긴 추상화임.

발전성: 변화를 쉽게 만들기

  • 시스템 요구사항은 끊임없이 변한다.
    • 예기치 않은 사용 사례 등장
    • 비즈니스 우선순위 변경
    • 사용자가 새로운 기능 요청
    • 법적, 규제 요구사항 변경
    • 시스템 성장으로 인한 아키텍처 변화
    • 등등..
  • 데이터 시스템 변경을 쉽게, 변화된 요구사항에 시스템을 맞추는 방법은, 시스템을 간단하고 추상화시키는 것임.
    • 데이터 시스템 수준에서의 변경을 발전성 이라고 부름.

댓글

Designed by JB FACTORY