신뢰할수 있고 확장가능하며 유지보수하기 쉬운 애플리케이션

‘데이터 중심 애플리케이션 설계’를 읽고 정리하고자함


요점 정리

  • 데이터 중심 애플리케이션을 생각하는 기본적인 방법 몇 가지 설명
  • 애플리케이션이 유용하려면 다양한 요구 사항을 채워야함
    1. 기능적 요구사항
      • 데이터를 저장, 조회, 검색하고 처리하게끔 허용하는 작업
    2. 비기능적 요구사항
      • 보안, 신뢰성, 법규준수, 확장성, 호환성, 유지보수과 같이 일반적 속성
  • 신뢰성
    • 결함이 발생하더라도 시스템이 올바르게 동작하게 만드는 의미
    • hw/sw/사람에 의해 발생할 수 있음
  • 확장성
    • 부하가 증가해도 좋은 성능이 유지하기 위한 전략
  • 유지보성
    • 시스템에서 작업하는 엔지니어와 운영 팀의 삶의 개선
    • 좋은 추상화는 복잡도를 줄이고, 쉽게 시스템을 변경할 수 있게 하며 새로운 사용 사례에 적용하는데 도움을 줌
    • 좋은 운용성이란, 시스템의 상태를 잘 과날할 수 있고 시스템을 효율적으로 관리하는 방법을 보유한다는 뜻

1. 신뢰성 (Reliability)

하드웨어나 소프트웨어 결함, 인적 오류 같은 ‘역경’에 직면하더라도 시스템은 지속적으로 올바르게 동작해야함

  • 올바르게 란 ? 원하는 성능 수준에서 정확한 기능을 수행
  • 잘못될 수 있는 일 = 결함(fault) 라고 함
  • 이 결함을 예측하고 대처할 수 있는 시스템을 내결함성(fault-tolerance) 또는 탄력성(resilient)을 지녔다고 말할 수 있음

  • 사실상, 인적 실수가 대부분의 신뢰성이 문제가 됌 ( 하드웨어 결함은 중단 원인의 10~25%에 그친다고 함)
  • 실뢰성을 높이기 위한 방법
    1. 오류의 가능성을 최소화하는 방향으로 시스템을 설계할 것
      • 잘 설계된 추상화, API, 인터페이스를 사용하면 ‘옳바른’일은 쉽게 할고, ‘잘못된 일’은 막을 수 있음
      • 하지만, 인터페이스 너무 제한적이면, 사람들은 좋은 점을 잊은 채 제한된 인터페이스를 피해 작업할 수 있음..
    2. 사람이 가장 많이 실수하는 부분에서 사람의 실수로 장애가 발생할 수 있는 부분을 분리하라.
      • 실제 데이터를 사용해 안전하게 실험할 수 있지만, 실제 사용자에게는 영향이 없는 샌드박스를 제공할 것
    3. 단위 테스트부터 전체 시스템 통합 테스트와 수동 테스트까지 모든 수준에서 테스를 할 것
    4. 장애 발생의 영향을 최소화하기 위해 인적 오류를 빠르고 쉽게 복구할 수 있게 해라
      • 설정 변경 내역을 빠르게 롤백하고 새로운 코드를 서서히 롤아웃하게 만들어, 이전 계산이 잘못된 경우 대비해 데이터 재계산 도구를 제공할 것
    5. 성능 지표 및 오류율 같은 상세하고 명확한 모니터링 대책을 마련해라

2. 확장성 (Scalability)

  • 현재 시스템이 안정적이라도 미래에는 안정적으로 동작한다고 보장할 수 없음
  • 성능 저하를 유발하는 흔한 이유 중 하나는 ‘부하 증가’

  • 확장성은 증가한 부하에 대처하는 시스템 능력을 설명하는데 사용하는 용어로써
  • 시스템이 특정 방식으로 커지면 이에 대처하기 위한 선택은 무엇인지, 추가 부하를 다루기 위해 계산 자원을 어떻게 투입할지 같은 질문을 고려해야함

부하 기술하기

  • 부하 매개변수 (load parameter)라 부르는 몇 개의 숫자로 표현할 수 있음
  • 웹 서버의 초당 요청 수, 데이터베이스의 읽기 대 쓰기 비율, 대화방의 동시 활성 사용자, 캐시 적중률 등…

성능 기술하기

  • 부하가 증가할 때, 어떤 일이 일어나는지 조사할 수 있고 밑의 두 질문 모두 ‘성능 수치’가 필요
    1. 부하 매개변수를 증가시키고, 시스템 자원은 변경하지 않고 유지하면 시스템 성능은 어떻게 영향을 받을까
    2. 부하 매개변수를 증가시켰을 때, 성능이 변하지 않고 유지되길 원한다면 자원을 얼마나 늘려야하는가
  • 하둡 같은 배치 처리 시스템은 처리량(throughput - 초당 처리할 수 있는 레코드수나 일정 크기의 데이터 집합으로 작업을 수행했을 때 걸리는 전체 시간) 중심
  • 온라인 시스템에서는 응답시간(response time - 클라이언트가 요청을 보내고 응답 바는 사이의 시간)
    • 응답시간은 단일 숫자가 아니라 측정 가능한 분포로 생각해야함
    • 응답시간은 mean값보다는 percentile, 백분위로 사용하는 편이 좋음(outlier를 보기 위함)
    • 사용자가 보통 얼마나 기다리나에 대한 값은 median값이 좋은 지표
    • 꼬리 지연 시간(tail latency), 상위 백분위 응답 시간은 서비스의 사용자 경험에 직접 영향을 주어 중요한 지표

      e.g) 아마존 내부 응답시간 요구사항이 99.9분위로 기술한다면, 요청 1000건 중 가장 느린 1건으로 측정

    • 백분위는 서비스 수준 목표(SLO-Service Level Objective)와 서비스 수준 협약서(SLA-Service Level Agreement)에 자주 사용
  • 지연시간 VS 응답시간 (latency VS response Time)
    • 응답시간은 클라이언트 관점에서 본 시간, 요청을 처리하는 실제 시간 외에도 네트워크, 큐 지연도 포함된 시간
    • 지연시간은 요청이 처리되길 기디라는 시간. 서비스를 기다리며 휴지(latency) 상태인 시간

부하 대응 접근 방식

  • 확장성 논의, 부하 매개변수가 어느 정도 증가하더라도 좋은 성능을 유지하려면 어떻게 할 것인가

  • scaling up(=vertical scaliing) vs scaling out(=horizontal scaliing)
  • 다수의 장비에 부하를 분산하는 아키텍처를 ‘비공유(shared-nothing) 아키텍처’

3. 유지보수성 (Maintainability)

  • 레거시 소프트웨어를 직접 만들지 않게끔 소프트웨어를 설계해야하며, 다음과 같은 시스템 설계 원칙을 지키자
    1. 운용성 (operability)
      • 운영팀이 시스템을 원활하게 운영할 수 있게 쉽게 만들어라
  1. 단순성 (simplicity)
    • 복잡도를 최대한 제거해 새로운 엔지니어가 시스템을 이해하기 쉽게 해라
    • 추상화를 잘해라
  2. 발전성 (evolvability)
    • 엔지니어가 이후에 시스템을 쉽게 변경할 수 있게 해라, 그래야 예기치 않은 요구사항을 쉽게 적용할 수 있음
    • 유연성(extensibility) , 수정 가능성(modifiability), 적응성(plasticity) 와 비슷함