# DDIA 1장. 신뢰할 수 있고 확장 가능하며 유지보수하기 쉬운 애플리케이션 * 오늘날 많은 애플리케이션은 계산 중심적이기 보다는 데이터 중심적이다. * CPU 성능보다 데이터의 양, 복잡도, 변화가 더 큰 문제로 여겨진다. ## 신뢰성(Reliability) * 결함이 발생해도 시스템이 올바르게 동작함. * 결함(fault)과 장애(failure)는 다르다: * 결함 - 사양에서 벗어난 시스템의 한 구성 요소. * 장애 - 사용자에게 필요한 서비스를 제공하지 못하고 시스템 전체가 멈춘 경우. * 하드웨어 결함 - 대체로 무작위적이고 독립적이다. * 소프트웨어 결함 - 예상하기 어렵고, 노드 간 상관관계 때문에 결함을 전파한다. * 인적 결함: 철저한 테스트와 모니터링, 교육으로 인적 결함을 방지할 수 있다. * 사소한 어플리케이션도 사용자에 대한 책임이 있다. * 시스템이 역경에 직면하더라도 지속적으로 원하는 성능 수준에서 정확한 기능을 수행해야 한다. ## 확장성(Scalability) * 부하가 증가해도 좋은 성능을 유지함. * 시스템의 데이터 양, 트래픽 양, 복잡도가 증가하면서 이를 처리하는 적절한 방법이 있어야 한다. * 시스템이 현재 안정적이라고 해서 미래에도 안정적이라는 보장은 없다. * 응답 시간은 단일 숫자가 아니라 분포로 생각해야 한다: * 산술평균 - 얼마나 많은 사용자가 지연을 경험했는지 알려주지 않기 때문에 좋지 않다. * 백분위: * p50(중앙값) - 200ms라면 50%는 200ms 미만으로 응답받고, 나머지 50%는 그보다 오래 걸렸다. * p95 - 1500ms라면 95%는 1500ms 미만으로 응답받고, 나머지 5%는 그보다 오래 걸렸다. * 아마존에서는 p999를 사용한다. 응답시간이 오래 걸렸다는 것은 많은 제품을 사는 사람이라는 의미. * 부하 대응 방식: * 수직 확장(scaling up) - 더 강력한 장비로 부하 처리. * 수평 확장(scaling out) - 더 많은 장비로 부하 분산. ## 유지보수성(Maintainability) * 엔지니어와 운영팀의 삶을 개선함: * 운용성(operability) - 운영팀이 시스템을 원할하게 운영할 수 있도록. * 단순성(simplicity) - 복잡성을 줄여 엔지니어가 쉽게 시스템을 이해하도록. * 발전성(evolvability) - 엔지니어가 시스템을 쉽게 변경할 수 있도록. * 신뢰성과 확장성을 쉽게 달성하기 위한 해결책이 없기 때문에 운용성, 단순성, 발전성을 염두에 두고 시스템을 생각한다. * 시간이 지남에 따라 여러 사람이 시스템에서 작업을 하기 때문에 모든 사용자가 시스템 상에서 생산적으로 작업할 수 있어야 한다.