오늘날의 대부분의 애플리케이션이 계산 중심이 아니라, 데이터 중심적이다. CPU 성능보다 더 중요한 부분은 어느 곳에 데이터를 저장할 것인지, 데이터의 양은 얼마인지, 데이터가 얼마나 복잡하고 변화하는지이다. 최근 애플리케이션은 데이터베이스(MySQL, Oracle), 캐시(Redis, Memcached), 검색 색인(ElasticSearch), 스트림 처리(Apache Kafka), 일괄 처리 (Hadoop)와 같은 시스템을 요구한다.
데이터베이스, 큐, 캐시 등은 데이터 시스템이라는 포괄적 용어로 묶어야하는 이유가 무엇일까?
1. 데이터 저장과 처리에 대한 여러 도구는 최근에 만들어졌고, 각 쓰임새에 따라 전통적인 분류에 맞지 않는다. 따라서 분류 간의 경계가 흐려지고 있다.
2. 이제 단일의 도구를 통해서 데이터 처리와 저장 모두를 만족하기 쉽지 않다. 작업을 위해서 단일 도구를 사용하는 것이 아닌, 각 테스크를 나눠 다양한 도구들을 통합해 연결하는 방식을 많이 사용한다.
또한 이러한 부분을 통합하기 위해서는 애플리케이션 단의 코드 구현을 통해 진행해야하고, 최근 개발자들은 애플리케이션 개발자 뿐만이 아닌, 데이터 시스템 설계자의 역할도 수행하게 된다.
소프트웨어에 시스템에서 중요하게 여기는 관심사는 3가지로 분류된다.
1. 신뢰성
2. 확장성
3. 유지보수성
신뢰성의 일반적인 기대치는 아래와 같다.
즉 정리하자면, "무언가 잘못되더라도 지속적으로 올바르게 동작함"을 의미한다.
잘못될 수 있는 일을 결함이라고 부르며, 이를 예측하고 대처할 수 있는 시스템을 내결함성 또는 탄력성을 지녔다고 말한다.
하드웨어 장치의 장애를 의미한다.
이를 해결하는 방법들은 아래와 같다.
최근에는 데이터 양, 계산량 증가 → 더 많은 수의 장비 → 하드웨어 결함율 증가
AWS 같은 클라우드 플랫폼은 단일 장비 신뢰성보다 유연성, 탄력성을 우선 처리.
→ 소프트웨어 내결함성 기술 사용하거나, 하드웨어 중복성을 추가해 전체 장비의 손실을 견딜 수 있는 시스템으로 옮겨가는 추세.
"체계적 오류"
무작위적이고 서로 독립적인 하드웨어 결함과 달리, 노드간 상관관계 때문에 발생하는 오류. 시스템 오류를 더욱 많이 유발
아래는 소프트웨어 오류의 예시이다.
테스트, 프로세스 격리, 시스템 가정 및 상호작용에 대해 깊게 생각하기, 시스템 모니터링 및 분석, 프로세스 재시작 등 해결해야한다.
인적 오류를 최소화할 수 있는 설계
부하 증가에도 안정적으로 동작할 수 있는가
확장성은 있다/없다 가 아니라, '특정 방식으로 시스템이 커지면 어떻게 대처할까', '추가 부하를 다루기 위해 자원을 어떻게 투입할까'를 고민하는 문제.
부하를 기술할 수 있어야 부하 성장(부하가 많아질 떄 어떻게 될지)에 대해 논의할 수 있다. 부하는 부하 매개변수를 통해 나타낼 수 있다.
부하 매개변수의 예
부하 매개변수의 평균이 중요할 수도, 소수의 극단적 케이스가 병목현상의 원인일 수 있다.
이를 트위터의 예로 설명해보자.
개별 사용자가 트윗 작성을 하면 많은 팔로워들의 타임라인에 함께 들어가야 함. - fan-out (하나의 수신 요청을 처리하는 데 필요한 다른 서비스의 요청 수)
어떻게 해결? (1→ 2→ 3으로 발전함)
위 질문은 모두 성능 수치가 필요하다. 시스템 성능에 대해 알아보자.
일괄 처리 시스템 - 처리량(throughput) : 초당 처리할 수 있는 레코드 수/데이터집합. 작업 수행에 걸리는 전체 시간을 중요하게 여긴다.
온라인 시스템 - response time : 클라이언트가 요청을 보내고 응답을 받는 사이의 시간을 중요하게 여긴다.
Scale up (용량 확장, 수직 확장)
Scale out (규모 확장, 수평 확장)
실용적인 접근방식의 조합이 필요하다.
다수의 장비에 분산하는 것이, 고사양 장비를 사용하는 것보다 저렴하다.
다수의 장비에 부하를 분산하는 아키텍처를 비공유 아키텍쳐라고 부른다.
최근에 분산 시스템을 위한 도구(auto scaling), 추상화가 좋아져서 통념이 바뀌고 있음. 부하 증가를 감지하면, 컴퓨팅 자원을 자동으로 추가해주는 탄력적 시스템은 부하 예측이 어려울 경우 유용하나, 수동으로 확장하는 시스템이 더 간단하고 운영상 예상치 못한 일이 더 적음.
범용적이고 모든 상황에 맞는 만병통치약 같은 확장 아키텍처는 없다.
아키텍처를 결정하는 요소들
주요 동작이 무엇이고, 잘 하지 않는 동작이 무엇인지에 대한 가정이 어떤 아키텍처를 갖출 것이냐에 매우 중요
우발적인 복잡도 제거를 위해 좋은 추상화를.
ex. 고수준 프로그래밍언어는 기계어, CPU레지스터, 시스템 호출을 숨김