Zayson
A to Zayson!
Zayson
전체 방문자
오늘
어제
  • 분류 전체보기 (132)
    • Computer Science (20)
      • Network (4)
      • DB (12)
      • OS (4)
    • Algorithm (32)
      • 완전탐색(Brute-Force) (3)
      • 그리디(Greedy) (6)
      • 투포인터(Two-Pointer) (1)
      • 그래프(Graph) (5)
      • BFS & DFS (9)
      • 구현, 시뮬레이션(Implementation) (5)
      • 다이나믹 프로그래밍(DP) (3)
    • Backend (51)
      • Spring Boot (19)
      • JPA (16)
      • Kafka (2)
      • Java (13)
      • Kotlin (1)
    • DevOps (1)
      • Jenkins (5)
      • Oracle Cloud Infrastructure (1)
      • Kubernetes & Docker (1)
    • Trouble Shooting (3)
      • JPA (1)
      • Spring Boot (2)
    • 회고 (5)
      • 엔빵 프로젝트 포스트 로드맵 (1)
      • 2022년 (4)
    • Kafka (7)
      • Kafka (5)
      • Kafka Connect (2)
    • 기술 서적 (6)
      • 데이터 중심 애플리케이션 설계 (3)
      • 개발자가 반드시 정복해야할 객체 지향과 디자인 패턴 (2)
      • 가상 면접 사례로 배우는 대규모 시스템 설계 기초 (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

인기 글

태그

  • Backend
  • BFS
  • 완전탐색
  • 엔빵프로젝트
  • spring boot
  • JPA
  • 백준
  • 라이브스터디
  • SpringBoot
  • 나 혼자 스프링부트!
  • kafka
  • dfs
  • CS
  • Computer science
  • 그리디
  • 프로그래머스
  • Java
  • Kafka Connect
  • 관계형 데이터베이스 실전 입문
  • 구현

최근 글

티스토리

hELLO · Designed By 정상우.
Zayson

A to Zayson!

1장. 신뢰할 수 있고 확장 가능하며 유지보수하기 쉬운 애플리케이션
기술 서적/데이터 중심 애플리케이션 설계

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

2024. 5. 19. 16:46

개요


  • 데이터가 중심이 되는 애플리케이션에서 신뢰할 수 있고 확장 가능하며 유지보수하기 쉬운 데이터 시스템을 구축하기 위해 필요한 내용을 알아보자.
  • 신뢰성, 확장성, 유지보수성의 의미를 명확히 알아보자

데이터 시스템


  • 비교적 최근에 등장한 다양한 데이터 저장/처리를 위한 도구 (e.g Kafka, Redis 등)들은 전통적인 데이터 저장소 분류(e.g 큐, 캐시, 데이터베이스)를 위한 경계가 흐려졌다.
  • 애플리케이션에서는 다양한 데이터 저장/처리 도구를 사용한다.
    • 다양한 도구들을 애플리케이션 코드를 이용해
    • 단일 도구에서 작업을 효율적으로 수행하기 위한 여러 태스크를 생성한다.
  • 데이터 시스템를 올바르게 설계하기 위해선 신뢰성, 유지보수성, 확장성을 중점을 둬야 한다.
    • 신뢰성(Reliability): 하드웨어, 소프트웨어, 휴먼 에러 상황에서도 지속적으로 올바르게 동작해야 한다.
    • 확장성(Scalability): 시스템의 데이터 양, 트래픽, 복잡도가 증가할 때 적절히 처리할 수 있어야 한다.
    • 유지보수성(Maintainability): 시간이 지날수록 다양한 사람이 시스템 상에서 작업하기 때문에 모든 작업자가 생산적으로 작업할 수 있게 만들어야 한다. 

신뢰성


  • 신뢰성은 애플리케이션이 “뭔가 잘못되더라도 지속적으로 올바르게 동작하는 것”을 의미한다.
  • 결함(Fault)은 잘못될 수 있는 것을 의미하며, 이 결함을 예측하고 대처할 수 있는 시스템을 내결함성(fault-tolerant), 탄력성(resilient)을 가졌다고 말한다.
  • 결함 ≠ 장애
    • 결함은 사양에서 벗어난 구조를 의미한다.
    • 장애는 사용자에게 필요한 서비스를 제공하지 못해 시스템 전체가 멈춘 경우를 의미한다.
  • 고의적 결함을 유도해 내결함성 시스템을 지속적으로 테스트해 처리가 가능한지 확인이 필요하다.
넷플릭스의 카오스 몽키(Chaos Monkey)는 대표적인 fault-tolerance 테스트 툴

하드웨어 결함

  • 하드웨어 결함(e.g 디스크 고장, 네트워크 단절)이 일어나도 시스템은 올바르게 동작해야 한다.
  • 하드웨어 결함에 따른 시스템 장애율을 줄이기 위한 방법으로 하드웨어 구성 요소를 중복(redundancy) 시키는 방법이 있다.
  • 최근에는 소프트웨어 내결함성 기술 + 하드웨어 중복성 추가 하는 방식을 주로 사용한다.
    • 서버의 재부팅이 필요한 경우 서버 다운타임 없이 이중화(중복성)로 인한 롤링 업데이트 가능하다.

소프트웨어 오류

  • 소프트웨어 결함을 유발하는 버그는 특정 상황에 의해 발생하기 전에는 확인하기 어렵다.
  • 소프트웨어 결함에 대해선 신속한 해결책이 없으므로 상세한 테스트, 프로세스 격리, 모니터링 등을 통해 지속적인 탐색이 필요하다.

인적 오류

  • 인적 오류는 완벽한 해결책이 존재하는 것이 아니기 때문에 오류율을 줄이는 것이 중요하다.
    • 오류 가능성을 최소화 하는 방항으로 시스템을 설계하자.
    • 사람들이 자주 실수하는 부분을 격리하자.
    • 단위 테스트부터 통합 테스트까지 철저하게 진행하자.
    • 시스템을 지속적으로 모니터링하자.
    • 장애 발생을 최소화하기 위해 오류를 빠르게 롤백할 수 있도록 설계하자.

확장성


  • 확장성은 증가하는 부하에 대처하는 시스템 능력을 의미한다.
    • 시스템이 특정 방식으로 커질 때 이에 대한 대처 방식이나 추가 부하를 다루기 위한 컴퓨팅 자원을 어떻게 투입할지를 고민하는 것이다.

부하 기술하기

  • 확장성을 고려하기 위해선 부하 매개변수를 이용해 시스템의 부하를 판단해야 한다.
부하 매개변수 예시: RPS (Request Per Second), DB Read/Write Rate, Cache Hit Rate
  • 병목 현상은 평균적인 부분에서도 발생할 수 있지만, 소수의 극단적인 경우에서도 발생할 수 있다.

팔로우 하는 사람의 모든 트윗을 홈 타임라인 조회 시점에 요청 (방안 1, 좌) / 트윗을 작성하면 모든 팔로워의 홈 타임라인에 트윗이 들어감 (방안 2, 우)

  • 평균적인 상황에서 방안 2는 “1개의 트윗이 75명의 팔로워에게 전달”되어 부하가 발생하지 않지만, 일부 극단적인 상황 (유저 1명을 팔로워하는 사람이 3,000만 명)인 경우 부하가 발생할 수 있다.
  • 트위터 예시에서 사용자당 팔로워의 분포는 트윗의 팬아웃 부하를 결정하기 때문에 부하 매개변수가 된다.

성능 기술하기

  • 시스템의 부하를 기술하면 부하가 일어날 때 애플리케이션에 어떤 일이 발생하는지 확인할 수 있다.
    • 부하 매개변수를 증가시키고 시스템 자원은 변경하지 않는 경우의 시스템 성능
    • 부하 매개변수를 증가시켰을 때 성능이 변하지 않도록 유지하기 위해 필요한 자원

요청 시 응답 시간에 대한 평균 및 백분위

  • 시스템의 성능을 판단할 때 평균보다는 백분위를 사용하는 것이 좋다.
    • 위의 예시에서 응답 시간을 빠른시간 → 늦은시간으로 정렬했을 때 중간 지점이 중간값(median, p50)이 된다.
    • 즉, 50%의 유저는 중간값 이하로 응답을 받고, 나머지 유저는 중간값 이상으로 응답을 받는다는 의미이다.
  • 특이 값을 알아보기 위해선 상위 백분위를 살펴보자. (일반적으로 p95, p99, p99.9 사용)
  • 꼬리 지연 시간(tail latency)으로 알려진 상위 백분위 응답 시간은 서비스 사용자 경험에 직접적인 영향을 주기 때문에 중요하다. 
  • 큐잉으로 인한 지연(Queueing Delay)은 이후 들어오는 요청에 대해서도 지연이 발생하는데 이를 선두 차단(head-of-line blocking)이라 한다.

부하 대응 접근 방식

  • 일반적으로 확장성은 Scale-Up(Vertical Scaling), Scale-Out(Horizontal Scaling)으로 구분한다.
  • 부하 증가를 감지하면 컴퓨팅 자원을 자동으로 추가하도록 탄력적인 시스템을 구축할 수 있다.
  • 상태 유지(stateful) 시스템을 분산시키는 것은 복잡도가 크기 때문에 확장 비용이나 데이터베이스에 대한 고가용성 요구가 있을 때까지 단일 노드에 데이터베이스를 유지하는 것(Scale-Up)이 최근까지의 통념이다.
  • 일반적으로 대규모 동작 시스템의 아키텍처는 애플리케이션에 특화되어 있다.
    • 애플리케이션에 적합한 확장성을 갖춘 아키텍처의 주요 동작을 파악해야 한다.

유지보수성


  • 유지보수에 대한 편의성을 제공하도록 시스템을 설계해야 한다.
  • 유지보수성을 위한 시스템 설계 원칙 
    • 운용성(Operability): 운영팀이 시스템을 원활하게 운영하도록 만들자.
    • 단순성(Simplicity): 시스템의 복잡도를 최소화하자.
    • 발전성(Evolvability): 시스템을 쉽게 변경할 수 있도록 만들자. (= 유연성(extensibility), 수정가능성(modifiability), 적응성(plasticity))

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

  • 시스템 운영 중 필요한 부분을 자동화하자.
  • 운영성이 좋은 것은 동일하게 반복되는 태스크를 쉽게 수행하게 하는 것이다.
    • 모니터링을 통한 런타임 및 시스템 내부 가시성 제공
    • 장비 의존성을 제거
    • 운영 로그와 같은 문서화

단순성: 복잡도 관리

  • 시스템이 복잡해질수록 유지보수 작업이 많아지고 비용이 증가하기 때문에 시스템을 단순하게 설계하는 것이 중요하다.
  • 우발적 복잡도를 제거하기 위한 가장 좋은 방법은 추상화이다.
    • 좋은 추상화는 세부 구현을 숨길 수 있으며, 다양한 애플리케이션에서 재사용이 가능하다.
    • 재사용으로 인해 효율성이 증가하며, 이는 품질 향상에 도움이 된다 .
우발적 복잡도(accidental complexity): 부적절한 설계, 구현, 관리로 인해 발생하는 소프트웨어의 복잡도

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

  • 시스템의 요구사항은 변화한다.
  • 애자일 프로세스와 같은 방법론과 TDD, 리팩토링 등을 적용하여 요구사항 변경에 대해 유연하게 대처할 수 있도록 시스템을 설계하자.
반응형
저작자표시 비영리 변경금지 (새창열림)

'기술 서적 > 데이터 중심 애플리케이션 설계' 카테고리의 다른 글

3장. 저장소와 검색  (0) 2025.03.02
2장. 데이터 모델과 질의 언어  (0) 2025.01.31
    '기술 서적/데이터 중심 애플리케이션 설계' 카테고리의 다른 글
    • 3장. 저장소와 검색
    • 2장. 데이터 모델과 질의 언어
    Zayson
    Zayson
    공부한 내용을 정리하는 공간

    티스토리툴바