Designing Data-Intensive Applications - (2) Defining NonFunctional Requirements

Designing Data-Intensive Applications, 2nd Edition
Data is at the center of many challenges in system design today. Difficult issues such as scalability, consistency, reliability, efficiency, and maintainability need to be resolved.... - Selection from Designing Data-Intensive Applications, 2nd Edition [Book]

Distributed Systems lecture series
Accompanying lecture notes: https://www.cl.cam.ac.uk/teaching/2122/ConcDisSys/dist-sys-notes.pdf These videos form an 8-lecture series on distributed systems...
Chapter 2: Defining NonFunctional Requirements
The Internet was done so well that most people think of it as a natural resource like the Pacific Ocean, rather than something that was man-made. - Alan Kay, in interview with Dr Dobb’s Journal (2012)
- functional requirements
- nonfunctional requirements → obvious things… fast, reliable, secure, legally compliant
- define and measure the performance of a system
- means for a service to be reliable
- allowing a system to be scalable
- making it easier to maintain a system in the long term
Case Study: Social Network Home Timelines
Representing Users, Posts, and Follows

SELECT posts.*, users.* FROM posts JOIN follows ON posts.sender_id = follows.followee_id JOIN users ON posts.sender_id = users.id WHERE follows.follower_id = current_user ORDER BY posts.timestamp DESC LIMIT 1000
Materializing and Updating Timelines
- 서버는 온라인 상태의 followers에게만 새로운 포스트를 전달한다.
- 대상자가 아닌 사람들은 연산하지 않는다.
- precompute: 결과를 미리 연산한 뒤 이를 캐시에 저장해두어 유저가 요청할 때 빠르게 보여준다.
- 특정 이벤트 발생으로 포스트 생성 비율이 증가할 경우, 즉각적으로 타임라인에 전달하기 보다, enqueue 해두어 followers의 타임라인에 조금은 느리게 보여지더라도 캐시를 통해 전달하여 그 시간 간극을 줄일 수 있다.

Pre-computingDecoupling- materialization ← Pre-computing
- materialization view ← cache
- materialization donwside
- 만약 많은 셀럽이 동시간에 포스트를 생성하면 많은 양의 작업을 수행해야 함
- 해결 방법 중 하나로, celebrity 포스트와 ~celebrity 포스트를 분리해서 관리할 것.
Describing Performance
- Response time (seconds): the elapsed time
- Throughput: somethings per second
queueing: 앞선 request가 completed 될 때까지 기다려야 하므로 load가 증가할 수록 response time이 sharply increase하는 원인- 계속 요청이 쌓이게 된다면 retry storm 발생
- load가 줄어든다고 해도 시스템은 reboot 또는 reset 하지 않는 이상 여전히 over-loaded 상태
- client-side resilience
- exponential backoff: client side에서 재시도를 랜덤한 시간 이후로 진행
- circuit breaker: 오류가 반환되거나 타임아웃되는 요청을 그만 보낼 것
- token bucket algorithm: 클라이언트가 요청을 보내는 속도를 제어(Rate Limiting)하는 알고리즘 / 버킷에 담긴 토큰만큼만 요청을 보낼 수 있게 하여 일시적인 트래픽 폭주를 제어
- server-side protectino
- load shedding: 서버가 과부하 상태에 도달했음을 감지하면, 중요도가 낮은 요청을 선제적으로 거절하여 핵심 기능의 가용성을 유지하는 전략
- backpressure: send back response asking clients to slow down (ex. HTTP 429 Too Many Requests)
- 사용자 관점 → response time
- 운영/비용 관점 → throughput
- 시스템 설계의 목표 ⇒ scalability
Latency and Response Time

- service time
- queueing time
- latency
- response time
head-of-line blockingAverage, Median, and Percentiles
tail latenciesUse of Response Time Metrics

구분 | 의미 | 예시 | 비고 |
SLO
(Objective) | 우리가 달성하고자 하는 기술적 목표 | p99 응답 속도를 1초 미만으로 유지하자. | 팀 내부의 성능 지표 |
SLA
(Agreement) | 고객과의 비즈니스 계약 | SLO를 못 지키면 요금의 10%를 환불해줄게. | 법적/금전적 보상이 따름 |
Reliability and Fault Tolerance
- functional correctness: performs the function that the user expected
- fault tolerance for users: can tolerate the user making mistakes
- performance under load: good enough for the required use case
- security & abuse prevention: prevents any authorized access and abuse
faultfailureFault Tolerance
fault-tolerantSPOF; Single Point of Failure 를 식별하고, 중복성을 도입하여 시스템을 robust 하게 만들어야 함 더 fault injection- 많은 심각한 버그는 실제 장애 자체가 아니라 장애를 처리하는 코드가 제대로 작동하지 않기 때문에 발생
Chaos Engineering ← 결함 주입을 포함하여, 시스템에 의도적인 장애를 주는 실험을 통해 시스템의 견고함을 개선하려는 체계적인 방법론Hardware and Software Faults
However, in a large-scale system, hardware faults happen often enough that they become part of normal system operation.
- Redundancy 중복성을 추가하여 하드웨어의 불완전함을 보완
- Availability Zones 가용 영역을 사용함으로써 물리적으로 떨어진 곳에 자원을 배치해 동시에 고장날 확률을 줄임
- Software Faults
- every node to fail at the same time in particular circumstances: 동시 다발적 발생
- Cascading failures
- 시스템의 가정과 상호작용을 깊이 고민하기
- 철저한 테스트 및 프로세스 격리
- 프로세스가 죽어도 다시 시작할 수 있게 설계 (Crash and restart)
- 재시도 폭풍(Retry storms) 같은 피드백 루프 방지
- 실제 운영 환경에서의 지속적인 측정과 모니터링
The problem of systematic faults in software has no quick solution.
Humans and Reliability
Given a choice between more features and more testing, many organizations understandably choose features.
Scalability
Scalability- coping with growth
- add computing resources
- hit the limits
Understanding Load
- load parameters examples
- 웹 서버: 초당 요청 수 (RPS)
- 데이터베이스: 읽기/쓰기 비율 (Read/Write Ratio)
- 채팅/메시징: 대화방의 동시 접속자 수
- 캐시: 히트율 (Cache Hit Ratio)
- you can investigate what happens when the load increases
- 성능 변화 측정 (자원 고정)
- 자원 투입량 계산 (성능 고정)
linear scalability 로 자원을 2배 투입하면 load도 2배 늘어나는 상태 → 매우 이상적인 상태- 데이터 양이 많아지면 요청 하나를 처리하는 데 필요한 '기본 작업량' 자체가 늘어나기 때문
Shared-Memory, Shared-Disk, and Shared-Nothing Architectures
vertical scaling or scaling up 을 위해 하드웨어 리소스를 늘리는 것도 방법이다.- Shared-Memory
- Shared-Disk
- shared-nothing architecture / horizontal scaling or scaling out
- 장점
- it has the potential to scale linearly
- achieve greater fault tolerance
- 단점
- requires explicit sharding
- incurs all the complexity of distributed systems
Principles for Scalability
There is no such thing as a generic, one-size-fits-all scalable architecture (informally known as magic scaling sauce)
- break a system into smaller components that can operate largely independently from one another
- not to make things more complicated than necessary
Maintainability
Every system we create today will one day become a legacy system if it is valuable enough to survive for a long time.
- Operability: keep system running smoothly
- Simplicity: make it easy to understand
- Evolvability: make it easy to make changes
Operability: Making Life Easy for Operations
- 역설적인 숙련도 요구: 자동화로 해결할 수 없는 아주 복잡한 문제들만 남아 운영팀은 자동화 이전보다 훨씬 더 높은 수준의 문제 해결을 해야 함
- 추적의 어려움: 사람이 수동으로 명령어를 입력하다 사고를 치면 뭘 잘못했는지 알기 쉬우나 자동화 시스템이 오작동하면 수많은 추상화 계층 속에서 어디가 망가졌는지 찾을 수 없음
- 모니터링 툴을 도입
- 디펜던시를 제거
- 이해를 위한 좋은 수준의 문서화 필요
- 관리자가 주도권을 잃어서는 안된다
- 예측 가능한 동작을 정의해서 의외성을 최소화 해야 한다.
Simplicity: Managing Complexity
- essential complexity: 문제 자체에 내제된 복잡함 / 비즈니스 로직의 복잡함
- accidental complexity: 도구, 언어, 인프라로 인해 발생한 복잡함
abstraction 을 해봐야 한다.- 알 필요 없는 것의 격리 → 추상화를 통해 복잡한 내부 동작을 숨김
- 재사용성 → 비슷한 류의 문제에 적용
- 품질의 선순환 → 추상화된 컴포턴트를 하나 개선하면 그것을 사용하는 모든 곳에 혜택이 전파된다.
Evolvability: Making Change Easy
- 조직적 차원 : agile → 기획이 변경되면 개발 방향을 틀 수 있는 유연함
- 기술적 차원 : TDD, refactoring → 코드를 고쳐도 시스템이 깨지지 않는다는 확신
Summary
- reliability 신뢰성
- fault vs. failure → 결함이 장애로 이어지지 않게 설계하는 것이 중요함
- scalability 확장성
- load parameters를 정의하여 수직 확장 vs. 수평 확장 고려
- maintainability 유지보수성
- operability: 운영 팀이 시스템을 원활하게 돌릴 수 있도록 모니터링 도구를 제공
- simplicity: 복잡도를 낮추기. 우연적 복잡도를 추상화로 제거하여 예측 가능한 동작을 만드는 것
- evolvability: 비즈니스 요구사항은 변함으로, 유연하게 설계하기
- 1.Designing Data-Intensive Applications - (1) Trade-offs in Data Systems Architecture
- 2.Designing Data-Intensive Applications - (2) Defining NonFunctional Requirements

Claude Code 완전 정복: 에이전틱 개발자를 위한 필수 워크플로우와 컨텍스트 최적화
시스템 프롬프트를 절반으로 줄이고 성능은 높이는 Claude Code 해킹 비법! AI가 지시를 잊어버리는 '컨텍스트 드리프트' 현상을 막고, 크고 복잡한 개발 문제를 단계별로 격파하는 노하우를 공개합니다. Discover the ultimate Claude Code hacking secrets to cut your system prompts in half while boosting performance! Learn how to prevent "context drift" where AI forgets instructions, and master the art of breaking down complex development problems step-by-step.
Designing Data-Intensive Applications - (1) Trade-offs in Data Systems Architecture
데이터 집약적 애플리케이션 설계에 대한 내용으로, 운영 시스템(OLTP)과 분석 시스템(OLAP)의 차이를 설명하며, 데이터 웨어하우스와 데이터 레이크의 개념을 다룬다. 클라우드 서비스와 자체 호스팅 시스템의 장단점을 비교하고, 분산 시스템과 단일 노드 시스템의 전환 시점을 논의한다. 또한, 데이터 시스템과 법률, 사회의 균형을 맞추는 중요성에 대해서도 언급한다.

NEWPySpark: 대용량 분산 처리 DataFrame 기초
PySpark는 Apache Spark를 Python 환경에서 사용할 수 있게 해주는 API로, 대량의 데이터를 분산 처리할 수 있다. 핵심 구조로는 Driver Node, Worker Node, Cluster Manager가 있으며, RDD와 DataFrame이 주요 데이터 구조이다. 학습 로드맵은 DataFrame 기초 조작, 스파크 최적화 및 고급 기능, 확장 모듈 다루기로 구성된다. Lazy Evaluation, SparkSession 생성, 데이터 불러오기 및 변환, 집계, 조인 등의 기법을 통해 성능을 최적화할 수 있다. 또한, Spark SQL, Structured Streaming, MLlib 등의 확장 모듈을 활용하여 데이터 엔지니어링을 강화할 수 있다.

Google Antigravity 시작하기 및 실제 프로젝트 구현해보기
구글 안티그래비티를 실제 프로젝트에 적용하며 얻은 기술적 통찰을 정리한다. 단순한 코드 추천을 넘어 스스로 계획을 수립하고 실행하는 '에이전트'로서의 특징과, 실제 배포 과정에서의 생산성 및 쿼터 관리 효율성을 분석한다. 개발자의 역할이 단순 코더에서 전체 프로세스를 관리하는 디렉터로 변화하는 지점을 가식 없이 기술한다. This post provides a technical review of Google Antigravity based on real-world project application. It explores its capabilities as an autonomous "Agent" that goes beyond code suggestions to planning and execution. The review analyzes productivity gains and the realities of quota management, highlighting the industry's shift where developers evolve from manual coders into strategic directors of AI agents.