
오늘날의 많은 애플리케이션은 계산 중심(compute-intensive) 이 아닌 데이터 중심적(data-intensive)이다.
데이터 중심적인 애플리케이션을 충족하는 여러가지 요구사항 중 신뢰성, 확장성, 유지보수성을 알아보자.
데이터베이스, 큐, 캐시 등
기본적으로 좀 더 작은 범용 구성요소들로 새롭고 특수한 목적의 데이터 시스템을 만든다.
이제부터 개발자는 애플리케이션 개발자 뿐만이 아닌 데이터 시스템 설계자이기도 하다.
데이터 시스템이나 서비스를 설계할 때 까다로운 문제가 많이 생긴다.
여기서는 대부분의 소프트웨어 시스템에서 중요하게 여기는 신뢰성, 확장성, 유지보수성 의 3가지 관심사에 중점을 둔다.
결함이 발생해도 시스템이 올바르게 동작한다는 의미
부하가 증가해도 좋은 성능을 유지하기 위한 전략
시스템에서 작업하는 엔지니어와 운영 팀의 삶을 개선하는 데 있다.
결함(fault): 잘못될 수 있는 일, 사양에서 벗어난 시스템의 한 구성 오소
장애(failure): 사용자에게 필요한 서비스를 제공하지 못하고 시스템 전체가 멈춘 경우
따라서, 대개 결함으로 인해 장애가 발생하지 않게끔 내결함성 구조를 설계하는 것이 가장 좋다.
고의적으로 결함을 유도함으로써 내결함성 시스템을 지속적으로 훈련하고 테스트해서 결함이 자연적으로 발생했을 때 올바르게 처리할 수 있다는 자신감을 높이는 방법
확장성을 논의하기 위해선 무엇보다 현재 시스템의 현재 부하를 간결하게 기술해야 한다.
그래야 부하 성장 질문(부하가 2배가 되면 어떻게 될까?)를 논의할 수 있다.
사용자당 팔로워의 분포가 팬 아웃 분포를 결정하기 때문에 핵심 부하 매개변수가 된다.응답 시간(response time): 클라이언트가 요청을 보내고 응답을 받는 사이의 시간(네트워크 지연, 큐 지연 포함)지연 시간(latency): 요청이 처리되길 기다리는 시간, 서비스를 기다리며 휴지(latent) 상태인 시간비슷한 것 같지만 동일하진 않다.
서버는 병렬의 소수 작업만 처리할 수 있기 때문에 (ex: cpu 코어 수 제한) 소수의 느린 요청 처리만으로도 후속 요청 처리가 지체된다.
95분위, 99분위, 99.9분위이다.꼬리 지연 시간(tail latency)는 서비스의 사용자 경험에 직접 영향을 주기 때문에 중요하다.전자공학에서 빌려온 용어, 다른 게이트의 출력에 배속된 논리 게이트 입력의 수를 뜻한다고 한다.
트랜잭션 처리 시스템에서 하나의 수신 요청을 처리하는데 필요한 다른 서비스 요청의 수를 설명하기 위해 사용
→ 여기서는 용어를 더 이해하기 어려웠던 것 같다. 좀 더 원론적으로 교과서처럼 설명해주는 듯 하다.
→ 가상 면접 사례로 배우는 대규모 시스템 설계 기초 1권의 11장 뉴스 피드 시스템 설계 에서는 팬 아웃(fan-out)을 단순히 포스팅 전송하는 것. 즉 어떤 사용자의 새 포스팅을 그 사용자의 친구 관계에 있는 모든 사용자에게 전달하는 과정이라고 설명한다.
핫키(hotkey) 문제), 서비스를 자주 이용하지 않는 사용자의 경우(컴퓨팅 자원 낭비)에 문제가 된다.대부분의 사용자에 대해서는 push 모델 사용. 친구나 팔로워가 아주 많은 사용자의 경우 pull 모델 사용.따라서, 본 책의 트위터 사례의 경우, 개별 사용자의 홈 타임라인 캐시를 유지하고 팔로워 각자의 홈 타임라인 캐시에 새로운 트윗을 삽입한다 라고 했으므로 push 모델을 설명하는 듯 하다.
라이브 환경에 영향을 미치지않고 소프트웨어나 애플리케이션을 테스트하고 개발할 수 있는 제어된 환경, 실제 데이터를 사용해 안전하게 살펴보고 실험할 수 있지만 실제 사용자에게는 영향이 없는 환경
→ git 에서의 branch 분리 전략?(Develop, QA, Stage, Production) 중에 Stage 에 해당되는 것 아닌가?
→ 실제로 이전 회사에서 거의 똑같은 개념으로 해당 Stage 서버를 운용함.
우발적 복잡도. 이름 그대로 의도하지 않은 복잡성을 뜻한다.
이 말을 듣고 java 의 JDBC, JPA, Spring Data JPA 가 생각났다.
초기에 애플리케이션 코드에서 java 로 MySQL 과 같은 DB 를 연결하기 위해서는 수많은 반복되고 복잡한 코드들이 필요했다.
하지만, 이를 문제 여긴 실력 있는 개발자분들이 우발적 복잡도를 제거하기 위해 좋은 추상화(interface 등)인 JDBC, JPA, Spring Data JPA 를 개발한 것이다.
책의 예시에서는 ‘기계 언어, CPU 레지스터, 시스템 호출을 추상화(숨긴) 시킨 것이 고수준 프로그래밍 언어이다’ 라고 했다.
즉 우리 개발자들이 흔히 사용하는 java 언어도 사실 우발적 복잡도를 제거한 추상화인 것이다.
public class Main {
public static void main(String[] args) {
// 두 정수의 덧셈
int a = 10;
int b = 20;
int sum = a + b;
// 결과 출력 (실제 내부적으로는 시스템 호출을 통해 콘솔에 출력됨)
System.out.println("Sum: " + sum);
}
}
위 코드를 보면,
따라서 이러한 애플리케이션 코드에서도 interface 를 통해서 추상화를 적절히 이용하고, 시스템 간에서도 interface 화를 통해 우발적 복잡도를 줄여나가야 할 것이다.