ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 1장 - 신뢰할 수 있고 확장 가능하며 유지보수하기 쉬운 애플리케이션
    CS/데이터 중심 애플리케이션 설계 요약 2022. 11. 6. 00:01

    데이터 중심적인 애플리케이션

    오늘날 많은 애플리케이션은 계산 중심과는 다르게 데이터 중심적입니다.

    즉, CPU의 성능은 애플리케이션에 크게 문제가 되지 않으나 데이터의 양, 데이터의 복잡도, 데이터의 변화 속도가 문제가 될 수 있습니다.

     

    예를 들어 많은 애플리케이션은 다음을 필요로 합니다.

    - 데이터베이스

    - 읽기 속도 향상을 위해 값비싼 수행 결과를 기억(캐시)

    - 사용자가 키워드로 데이터를 검색 또는 다양한 방법으로 필터링할 수 있도록 제공 (검색 색인)

    - 비동기 처리를 위해 다른 프로세스로 메시지 보내기(스트림 처리)

    - 주기적으로 대량의 누적된 데이터를 분석(일괄 처리 = batch processing)

     

    너무 뻔한 말처럼 들릴 수 있지만 현실의 애플리케이션은 요구사항이 다양하기 때문에 다양한 데이터베이스, 캐시 등에서 적합한 방법을 적절하게 선택해서 사용해야 합니다.

     

    예시) NoSQL vs 관계형 DB , Local Cache, Global Cache 등등


    개발자에게 점점 중요해 지는 데이터 시스템

    더 많은 애플리케이션이 단일 도구로는 더 이상 데이터 처리와 저장 모두를 만족시킬 수 없는 과도하고 광범위한 요구사항을 가지고 있습니다.

     

    따라서 단일 도구에서 효율적으로 수행할 수 있는 것들을 나누고 다양한 도구들은 애플리케이션 코드를 이용해서 서로 연결해야 합니다.

     

    예를 들어 메인 DB와 분리된 캐시 계층(Memcached or Redis)과 엘라스틱서치와 같은 검색 서버의 경우 메인 데이터베이스와 동기화된 캐시나 색인은 유지하는 것은 보통 애플리케이션 코드의 책임입니다.

     

    데이터 시스템 또는 서비스를 설계할 때 발생할 수 있는 문제들

    - 내부적으로 문제가 있어도 데이터를 정확하고 안전하게 유지하려면 어떻게 해야 할까?

    - 시스템의 일부 성능이 저하되더라도 클라이언트에 일관되고 좋은 성능을 어떻게 제공할 수 있을까?

    - 부하 증가를 다루기 위해서는 어떻게 규모를 확장해야 할까?

    - 서비스를 위해 좋은 API는 어떤 모습일까?

     

    관련자의 기술 숙련도, 기존 시스템의 의존성, 전달 시간 척도, 다양한 종류의 위험에 대한 조직의 내성, 규제 제약 등은 시스템 설계에 영향을 줄 수 있는 요소들이며, 이런 요소는 상황에 크게 좌우됩니다.

     

    이 책에서는 기본적으로 신뢰성, 확장성, 유지보수성을 가장 중요하게 여깁니다.


    신뢰성

    신뢰성은 어떤것인지에 대해 대부분 직관적인 개념을 가지고 있습니다.

     

    소프트웨어의 경우 일반적인 기대치는 다음과 같습니다.

    - 사용자가 기대한 기능을 수행한다

    - 사용자가 범한 실수나 예상치 못한 소프트웨어 사용법을 허용할 수 있다

    -시스템 성능은 예상된 부하와 데이터 양에서 필수적인 사용 사례를 충분히 만족한다

    - 허가되지 않은 접근과 오남용을 방지한다.

     

    잘못될 수 있는 일을 결함(falut)라고 하며, 이런 결함을 대처할 수 있는 시스템을 내결함성 또는 탄력성을 지녔다고 말합니다.

     

    하지만 절대적으로 모든 결함에 대처할 순 없습니다.

    예를 들어 블랙홀이 지구와 지구상의 모든 서버를 삼키더라도 웹 호스팅이 가능한 내결함성을 지닐 순 없습니다.

    따라서 특정 유형의 결함 내성에 대해서만 이야기하는 것이 타당합니다.

     

    결함은 장애와 동일하지 않습니다.

    결함은 사양에서 벗어난 시스템의 한 구성 요소로 정의되지만, 장애는 시스템 전체가 멈춘 경우입니다.

    결함 확률을 0으로 줄이는 것은 불가능하지만 결함으로 인해 장애가 발생하지 않게끔 내결함성 구조를 설계하는 것이 가장 좋습니다.

     

    하지만 보안문제의 경우에는 예방책이 해결책보다 훨씬 좋은 경우입니다.

    만약 공격자가 시스템을 손상시키고 민감한 데이터에 접근 권한을 얻는다면 이를 되돌릴 수 없습니다.

     

    하드웨어의 결함

    시스템의 장애원인을 생각하면 하드웨어의 결함이 바로 떠오릅니다.

    - 하드디스크의 고장

    - 램의 결함

    - 대규모 정전 사태

    - 네트워크 케이블을 잘못 뽑음

     

    이에 대비하기 위해서는 하드웨어 구성 요소에 중복을 추가하는 방법 중복을 추가하는 방법이 일반적입니다.

    - 디스크는 RAID 구성

    - 서버는 이중 전원 디바이스와 핫 스왑 가능한 CPU

    - 데이터센터는 건전지와 예비 전원용 디젤 발전기를 갖추기

     

    소프트웨어의 오류

    소프트웨어의 장애원인은 예를 들면 다음과 같습니다

    - 잘못된 특정 입력이 있을 때 모든 애플리케이션 서버 인스턴스가 죽는 소프트웨어 버그

    -  CPU, 메모리, 디스크 공간, 네트워크 대역폭처럼 공유 자원을 과도하게 사용하는 일부 프로세스

    - 시스템 속도가 느려져 반응이 없거나 잘못된 응답을 반환하는 서비스

    - 한 구성 요소의 작은 결함이 다른 구성 요소의 결함을 야기하고 차례대로 더 많은 결함이 발생하는 연쇄 장애

     

    이런 오류에는 신속한 해결책이 없지만 문제를 해결하기 위해 도움을 받기 위해서는 다음과 같은 일을 해야 합니다.

    - 빈틈없는 테스트

    - 프로세스 격리

    - 죽은 프로세스의 재시작 허용

    - 프로덕션 환경에서 시스템 동작의 측정, 모니터링, 분석

     

    인적 오류

    대규모 인터넷 서비스에 대한 연구에 따르면 운영자의 설정 오류가 중단의 주요 원인인 반면에 하드웨어 결함은 중단 원인의 10~25% 정도에 그칩니다.

     

    이런 인적 오류를 어떻게 신뢰성 있게 해결할 수 있을까요?

    - 추상화, 관리 인터페이스 활용하기

    - 단위테스트~ 통합 테스트 모든 수준에서 철저하게 테스트하기

    - 장애 발생의 영향을 최소화하기 위해 인전 오류를 빠르고 쉽게 복구할 수 있는 환경 구축(roll back)

    - 성능 지표나 오류율을 측정 및 모니터링

     

    신뢰성이 중요한 이유

    비즈니스 애플리케이션에서 버그는 생선성 저하의 원인입니다.

    예를 들어 전자 상거래 사이트의 중단은 매출에 손실이 발생하고 명성에 타격을 준다는 면에서 비용이 많이 듭니다.


    확장성

    시스템이 현재 안정적으로 동작한다고 해서 미래에도 안정적으로 동작할 것이라는 보장은 없습니다.

    시스템의 동시 사용자 수가 1만 명 -> 10만 명 -> 100만 명으로 증가하게 되면 부하가 증가하게 되고 성능 저하가 발생할 수 있습니다.

     

    확장성을 논하기 위해서는 "시스템이 특정 방식으로 커지면 이에 대처하기 위한 선택은 무엇인가?"에 대한 질문을 고려해야 합니다.

     

    부하 기술하기

    부하는 부하 매개변수라 부르는 몇 개의 숫자로 나타낼 수 있습니다.

    웹 서버의 초당 요청 수, 데이터베이스의 읽기 대 쓰기 비율, 대화방의 동시 활성 사용자, 캐시 적중률 등이 될 수 있습니다.

    이를 통해 "부하가 2배로 되면 어떻게 될까?"를 논의할 수 있습니다.

     

    책에서는 트위터 예시를 통해 팔로우에서 발생한 문제를 해결하기 위해 읽기 요청량과 쓰기 요청량을 고려하여 적절한 방법으로 문제를 해결해나간 예시를 들어줍니다.

     

    성능 기술하기

    - 부하 매개변수를 증가시키고 시스템 자원은 변경하지 않으면 시스템 성능은 어떻게 될까?

    - 부하 매개변수를 증가시켰을 때 성능이 변하지 않으려면 자원을 얼마나 늘려야 할까?

     

    하둡같은 일괄 처리 시스템은 보통 처리량에 관심을 가집니다.

    온라인 시스템에서는 서비스 응답 시간에 관심을 가집니다.

     

    콘텍스트 스위치, 네트워크 패킷 손실과 TCP 재전송, GC, page fault 등의 다양한 이유로 추가 지연이 발생할 수 있습니다.

    지연시간은 일반적으로 평균보다는 백분위를 사용하는 편이 좋습니다.

    이를 통해 중간 지점인 중앙값을 통해 사용자의 요청 시간을 측정하는 것이 좋은 지표입니다.

     

    특히 99.9 분위 값을 중요하게 봐야 합니다.

    예를 들어 아마존은 내부 서비스의 응답 시간 요구사항을 99.9 분위로 기술합니다.

    보통 응답 시간이 가장 느린 요청을 경험한 고객들은 가장 많은 구매를 하기 때문에 고객 중 계정에 많은 데이터를 가지고 있기 때문입니다.

     

    즉, 가장 소중한 고객을 계속 행복하게 만드는 것이 중요합니다.

     

    부하 대응 접근 방식

    확장성과 관련하여 스케일 업, 스케일 아웃으로 구분해서 말합니다.

    둘 중 가격 대비 효율적인 방식을 적절하게 선택해서 사용해야 합니다.

     

    또한 일부 시스템은  탄력적입니다.

    부하 증가를 감지하면 자동으로 컴퓨팅 자원을 추가할 수 있습니다.

    이때 DB를 분산하는 것은 매우 복잡하기 때문에 고가용성 요구가 있기 전까지는 단일 노드에 DB를 유지하는 것이 최근까지의 통념입니다.

    하지만 일부 애플리케이션에서는 분산 시스템을 위한 도구와 추상화가 좋아지면서 점점 복잡도가 낮아지고 있습니다.

     

    이 모든 것을 아우르는 마법 같은 아키텍처는 존재하지 않습니다.

    읽기의 양, 쓰기의 양, 저장할 데이터의 양, 데이터의 복잡도, 응답 시간 요구사항, 접근 패턴 등을 적절히 판단하여 적합한 아키텍처를 선택해야 합니다.

     


    유지보수성

    소프트웨어의 비용의 대부분은 초기 개발이 아니라 지속해서 이어지는 유지보수에 들어간다는 사실은 잘 알려져 있습니다.

     

    이를 대비하기 위해 주의를 기울여야 할 소프트웨어 시스템 설계 원칙 세 가지입니다.

    - 운영팀이 시스템을 원활하게 운영할 수 있게 쉽게 만들어라

    - 복잡도를 최대한 제거하여 새로운 개발자가 시스템을 이해하기 쉽게 만들어라

    - 요구사항을 반영하기 쉽게 시스템을 쉽게 변경할 수 있도록 하라.

     

    운영의 편리함 만들기

    좋은 운영은 나쁜 소프트웨어를 방지할 수 있는 좋은 대안이 될 수 있습니다.

    하지만 좋은 소프트웨어라도 나쁘게 운영한다면 작동을 신뢰할 수 없습니다.

     

    좋은 운영팀은 일반적으로 다음과 같은 작업 등을 책임집니다.

    - 모니터링 및 상태가 좋지 않으면 빠르게 서비스를 복원

    - 시스템 장애, 성능 저하 등의 문제의 원인을 추적

    - 미래에 발생 가능한 문제 예측하여 해결

    - 다른 시스템이 서로 영향을 주는 부분을 확인하여 문제가 생길 수 있는 변경 사항을 미리 차단

     

     

    복잡도 관리

    보통 프로젝트가 커지면서 매우 복잡하고 이해하기 어려워집니다.

    이때 가장 좋은 도구는 추상화입니다.

    좋은 추상화는 깔끔하고 직관적인 외관 아래로 많은 세부 구현을 숨길 수 있습니다.

    또한 재사용성을 높여줍니다.

     

    예를 들어 고수준 프로그래밍 언어는 기계 언어, CPU 레지스터, 시스템 호출을 숨긴 추상화입니다.

     

    요구사항을 쉽게 반영하는 시스템

    애자일 커뮤니티는 TDD와 리팩터링 같이 자주 변하는 환경에서 소프트웨어를 개발할 때 도움이 되는 기술 도구와 패턴을 개발하고 있습니다.

    데이터 시스템 변경을 쉽게 하고 변화된 요구사항에 시스템을 맞추는 방법은 시스템의 간단함과 추상화와 밀접한 관련이 있습니다.

     


    정리

    애플리케이션이 이용하기 위한 요구사항

    기능적 요구사항(데이터를 저장, 조회, 검색 처리하는 작업)

    비기능적 요구사항(보안, 신뢰성, 법규, 확장성, 유지보수성)

     

    신뢰성

    결함이 발생해도 시스템이 올바르게 동작해야 함

    결함은 소프트웨어와 하드웨어 또는 사람에게서 발생

     

    확장성

    확장성을 위해서는 부하와 성능을 설명할 수 있어야 함

    부하는 트위터의 홈 타임라인, 성능 측정은 응답 시간 백분위가 있음

    확장성이 높은 시스템은 부하가 높은 상태에서 신뢰성을 유지하기 위해 처리 용량을 추가할 수 있음

     

    유지보수성

    좋은 추상화를 통해 복잡도를 줄이고 변경에 용이한 시스템을 설계해야 함.

     

    아쉽게도 간단한 해결책은 없고 여러 애플리케이션에서 계속 재현되는 특정 패턴과 기술이 있습니다.

    이후에는 몇 가지를 예제로 살펴보고 이런 목표를 향해 데이터 시스템이 어떻게 작동하는지 분석합니다.

    'CS > 데이터 중심 애플리케이션 설계 요약' 카테고리의 다른 글

    6장 - 파티셔닝  (1) 2022.12.10
    5장 - 복제  (0) 2022.12.02
    4장 - 부호화와 발전  (0) 2022.11.18
    3장 - 저장소와 검색  (0) 2022.11.17
    2장 - 데이터 모델과 질의 언어  (0) 2022.11.16

    댓글

Designed by Tistory.