1. Reliable, Scalable, and Maintainable Applications

신뢰성, 확장성, 유지보수성

  • Haram Lee
  • 2026-03-24
  • studies / Topics / DDIA

Martin Kleppmann, 『Designing Data-Intensive Applications』(O’Reilly, 2017)를 읽으며 정리한 노트. 한국어판 『데이터 중심 애플리케이션 설계』의 번역 용어를 주로 따랐고, 내용은 책을 요약한 것이며 그림은 개념만 다시 그렸음.

1.1 Thinking About Data Systems

  • 목표: 특정 목적에 어떤 기술이 적합한지 결정하고, 좋은 애플리케이션 아키텍처의 기반을 만들기 위해 도구를 조합하는 방법을 이해하는 능력을 기른다
  • 데이터 중심적 vs 계산 중심적
    • 주된 문제: 데이터 양, 데이터 복잡성, 데이터가 변하는 속도 등 vs CPU 사이클
  • 요즘 애플리케이션은 DB 하나가 아니라 여러 도구를 애플리케이션 코드로 엮어서 하나의 데이터 시스템을 만듦
flowchart TD
  client["Client Request"] --> app["Application Code"]
  app --> cache["In-memory Cache"]
  app --> db["Primary Database"]
  app --> search["Full-text Index"]
  app --> queue["Message Queue"]
  • 기능적 요구사항: 애플리케이션이 처리하는 다양한 작업
  • 비기능적 요구사항: 보안, 신뢰성, 법규 준수, 확장성, 호환성, 유지보수성

1.2 Reliability

  1. 사용자가 기대한 기능 수행(expected)
  2. 사용자가 실수하거나 소프트웨어를 예상치 못한 방식으로 써도 견딤(fault tolerance; resiliency)
  3. 예상된 부하와 데이터 양에서 필요한 사용 사례를 충분히 만족함
  4. 허가되지 않은 접근과 오남용을 막음(protection)
  • 하드웨어 장애
    • 대응: 하드웨어 구성 요소마다 중복(redundancy)을 추가
    • 데이터와 부하가 작을 땐 이걸로 충분했지만, 장비 수가 늘면서 하드웨어 결함 자체도 늘어남
  • 소프트웨어 장애
    • 그래서 소프트웨어 내결함성 기술과 하드웨어 중복을 함께 써서 장비 하나가 통째로 죽어도 버티는 시스템으로 가는 중
    • 이런 시스템은 한 번에 한 노드씩 패치할 수 있어서 전체 중단 없이 운영 가능
    • 정교한 테스트, process isolation, 재시작 허용, 시스템 동작 측정과 모니터링이 예방에 도움
  • 인적 오류
    • 애초에 실수할 여지를 줄이는 설계: 잘 만든 추상화, API, 관리 인터페이스
    • 실수가 나도 빨리 복구할 수 있게: 설정 롤백, 점진적 롤아웃, 데이터 재계산 도구
    • 성능 지표와 오류율 같은 상세하고 명확한 모니터링

1.3 Scalability

  • 확장성: 증가한 부하에 대처하는 시스템 능력
  • 부하는 부하 매개변수로 표현함
    • e.g. 웹 서버의 초당 요청 수, DB 읽기 대 쓰기 비율, 대화방의 동시 활성 사용자, 캐시 적중률

e.g. Twitter 홈 타임라인

  1. 읽을 때 합치기: 트윗은 전역 컬렉션에 넣기만 하고, 타임라인을 요청하면 팔로우하는 사람들의 트윗을 모아 시간순으로 합침
  2. 쓸 때 퍼뜨리기(fan-out): 사용자별 타임라인 캐시를 두고, 트윗을 쓰면 팔로워 각자의 캐시에 넣어 둠. 그래서 읽기가 싸짐
  • 핵심 부하 매개변수는 사용자당 팔로워 분포 (fan-out 부하를 결정)
  • 결론적으로 둘을 섞음: 팔로워가 매우 많은 사용자는 fan-out에서 빼고 읽을 때 1번 방식으로 합침

e.g. Hadoop 같은 배치 시스템과 온라인 시스템의 성능

  • 배치 시스템은 처리량(throughput), 온라인 시스템은 응답 시간(response time)을 봄
  • vs. latency: 응답 시간은 실제 처리 시간에 네트워크 지연과 큐 지연까지 포함. latency는 요청이 처리되기를 기다리며 쉬고 있는 시간이라, 응답 시간이 latency보다 항상 더 김
  • 응답 시간은 단일 숫자가 아니라 분포로 봐야 함
    • context switch, 패킷 손실과 TCP 재전송, GC pause, page fault 같은 것들로 가끔씩 튀기 때문
  • 산술 평균, 백분위, 중앙값
  • 백분위는 SLO(service level objective), SLA(service level agreement)에 주로 쓰임
  • 선두 차단(head-of-line blocking): 느린 요청 몇 개 때문에 뒤의 요청 처리까지 밀림

확장 방식

  • 용량 확장(scaling up) 또는 수직 확장(vertical scaling) vs 규모 확장(scaling out) 또는 수평 확장(horizontal scaling)
  • 탄력성(elasticity): 부하 증가를 감지하면 컴퓨팅 자원을 자동으로 추가하는 특성
  • stateless 서비스를 여러 장비에 배포하는 건 간단하지만, stateful 데이터 시스템을 여러 노드로 분산하는 건 복잡도가 훨씬 커짐

1.4 Maintainability

  • 운용성(operability)
    • 운영하기 편해야 함. 운영 중 일부는 자동화할 수 있고, 또 자동화해야 함
  • 단순성(simplicity)
    • 상태 공간 급증, 모듈 간 강한 커플링, 복잡한 의존성, 일관성 없는 명명, 성능용 해킹, 임시방편 같은 복잡성을 없애야 함
    • 복잡할수록 변경할 때 버그가 생길 위험이 커지기 때문
    • 우발적 복잡도를 없애는 최상의 도구는 추상화: 깔끔한 겉모습 뒤로 구현을 숨기고, 다른 곳에서도 재사용
  • 발전성(evolvability): extensibility, modifiability, plasticity
    • 요구사항은 끊임없이 변함. 조직 프로세스 측면에서는 agile한 작업 패턴이 변화에 적응하는 프레임워크가 됨
Discussion