요약
- 확장성에 대한 내용을 살펴봄.
- 부하 기술 방법
- 성능 기술 방법
- 부하에 대응하기 위한 접근 방법
- 유지보수성에 대한 내용을 살펴봄.
발췌
- 부하는 부하 매개변수 숫자로 나타낼 수 있음. (p11)
- 가장 적합한 부하 매개 변수 선택에 따라 시스템 설계가 달라짐. (p11)
메모
확장성
- 확장성은 증가한 부하에 대처하는 시스템 능력을 설명하는데 사용하는 용어임.
부하 기술하기
- 시스템의 현재 부하를 간결하게 기술할 수 있어야 함.
- 부하 성장 질문(ex: 부하가 2배가 되면 어떻게 될까?)을 논의할 수 있기 때문
- 부하는
부하 매개변수(load parameter)
라 부르는 몇 개의 숫자로 나타날 수 있음.
- 시스템 설계에 따라 부하 매개변수의 선택이 달라짐.
- ex) 트위터(Twitter)를 예로 들어보자. 트위터의 주요 두 가지 동작은 다음과 같음.
- 트윗(tweet) 작성 → user 가 follower 에게 새로운 메시지 게시 (평균 초당 4.6k 요청)
- 홈 타임라인(timeline) → user 는 follow 한 사람이 작성한 tweet 을 볼 수 있음. (평균 초당 300k 요청)
- 트위터의 확장성 문제는
팬 아웃(fan-out)
에서 나온다.
- 팬 아웃이란, 다른 게이트의 출력에 배속된 논리 게이트 입력의 수를 뜻함. (즉, 내가 팔로우한 사람이 트윗을 작성하는 수에 배가 되는 것임)
- 이 동작을 구현하는 방법은 크게 2가지 임.
- 관계형 스키마를 이용하여 여러 테이블을 조인
- 개별 사용자의 홈 타임라인 캐시를 사용
- 즉, user 가 트윗을 작성하면, user 를 팔로우하는 사용자를 모두 찾아서 각 팔로워읭 홈 타임라인 캐시에 새로운 트윗을 삽입함.
- 트위터는 접근 방식 1을 사용했었는데, 시스템이 홈 타임라인 질의 부하를 버텨내는 것이 힘들었음.
- 따라서, 접근 방식 2로 전환하였고, 홈타임라인에서 요청하는 수가 트윗 작성 요청으로 옮겨졌기에 훨씬 잘 동작함.
- 즉, 쓰기 시점에 더 많은 일을하고, 읽기 시점에 적은 일을 한 것이 바람직함.
- 하지만, 접근 방식 2 는 트윗 작성에 많은 부가 작업이 필요.
- 만약, 어떤 사용자의 팔로워가 3천만명이 넘으면, 단일 트윗으로 인해, 홈 타임라인에 3천만건 이상의 쓰기 요청이 될 수 있음.
- 트위터의 예시를 봤듯이, 여기서 부하 매개변수는 팬 아웃이 부하를 결정하기에, 확장성 논의할 때 핵심 부하 매개변수가 됨.
- 트위터의 시스템 최종 전개는, 접근 방식 1, 2를 혼합하여 사용함.
- 사용자 수가 너무 많은 경우 접근 방식 1을 사용하도록 하여 좋은 성능을 유지함.
성능 기술하기
- 시스템 부하를 기술하면 부하가 증가할 때 어떤 일이 일어나는지 조사할 수 있음.
- 부하 매개변수를 증가시키고, 시스템 자원은 유지하면, 시스템 성능은 어떻게 영향을 받을 것인가?
- 부하 매개변수를 증가시키고, 성능이 유지되길 원한다면 자원을 얼마나 늘려야 할 것인가?
- 위 두 질문의 답을 하려면
성능 수치
가 필요함.
- 처치량(throughput) : ex) 하둡
- 응답 시간(response time) : ex) 온라인 시스템
- 클라이언트의 동일한 요청에도, 응답 시간은 다름.
- 응답 시간을
분포
로 생각해야 함.
- 응답 시간 분포에서, 가끔 오래 걸리는
특이 값(outlier)
도 생각해야 함.
- 아래는 지연에 대한 다양한 원인들임.
- 백그라운드 프로세스 컨텍스트 스위치
- 네트워크 패킷 손실, TCP 재전송
- 가비지 컬렉션 휴지
- 디스크에서 읽기 강제하는 페이지 폴트
- 서버 랙의 기계적인 진동
- 등등..
- 보통은 평균 응답 시간을 살피는게 일반적임.
- 하지만, 평균보다는 백분위(percentile) or 중앙값(median)를 사용하는게 더 좋음.
- 평균은 실제 사용자가 얼마나 실제 지연을 경험했는지 알 수 없기 때문
- 특이 값에 대한 체크를 위해, 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가지
- 운용성(operability) : 시스템을 원활하게 운영할 수 있도록 쉽게 만들 것
- 단순성(simplicity) : 시스템 복잡도를 제거, 새로운 엔지니어가 시스템을 이해하기 쉽게 만들 것
- 발전성(evolvability) : 엔지니어가 시스템을 쉽게 변경할 수 있게 할 것.
운용성: 운영의 편리함 만들기
- 운영 중, 일부 측면은 자동화할 수 있고, 자동화 해야 한다.
- 자동화의 처음 설정과, 제대로 동작하는지 확인하는 일은 사람의 몫임.
- 운영팀이 필수로 있어야 함.
- 좋은 운영팀은 일반적으로 다음 작업을 책임짐
- 시스템 상태 모니터링, 상태가 좋지 않은 경우 빠르게 서비스 복원
- 시스템 장애, 성능 저하의 문제 원인 추적
- 보안 패치, 소프트웨어 플랫폼 최신 상태 유지
- 서로간의 시스템에 영향을 어떻게 주는지 확인, 문제가 생길 수 있는 변경 사항은 사전 차단
- 예측가능한 문제를 미리 발견하여 해결 (ex: 용량)
- 배포, 설정 관리를 위한 모범 사례, 도구 마련
- 등등 … (p19)
단순성: 복잡도 관리
- 프로젝트가 커짐에 따라 시스템은 매우 복잡하고 이해하기 어려움
- 복잡도는 다양한 증상으로 나타남.
- 상태 공간 급증
- 모듈 간 강한 커플링
- 복잡한 의존성
- 일관성 없는 명명과 용어
- 성능 문제 해결을 목표로 한 해킹
- 임시방편으로 문제를 해결한 특수 사례
- 이러한 복잡도 때문에 예산과 일정이 초과되기도 함.
- 따라서, 단순성은 시스템 구축에 핵심 목표여야 함.
- 추상화를 통해 구현에서 발생할 복잡도 제거 가능.
- 세부 구현을 숨길 수 있음.
- ex) 고수준 프로그래밍 언어는, 기계 언어, CPU 레지스터, 시스템 호출을 숨긴 추상화임.
발전성: 변화를 쉽게 만들기
- 시스템 요구사항은 끊임없이 변한다.
- 예기치 않은 사용 사례 등장
- 비즈니스 우선순위 변경
- 사용자가 새로운 기능 요청
- 법적, 규제 요구사항 변경
- 시스템 성장으로 인한 아키텍처 변화
- 등등..
- 데이터 시스템 변경을 쉽게, 변화된 요구사항에 시스템을 맞추는 방법은, 시스템을 간단하고 추상화시키는 것임.
- 데이터 시스템 수준에서의 변경을
발전성
이라고 부름.
댓글