신뢰할 수 있고 확장 가능한

오늘날 많은 애플리케이션은 계산 중심이 아니고 데이터 중심적이다. 문제는 데이터의 양, 데이터의 복잡도, 데이터의 변화 속도이다.

데이터베이스(DB), 캐시(cache), 검색 색인(search index), 스트림 처리(stream processing), 일괄 처리(batch processing) 들은 추상화된 개념이다.

1. 데이터의 저장과 처리에 따른 여러 가지 도구들. 분류 간 경계가 흐려지고 있다.

Ex) 메시지 큐로 사용하는 데이터 스토어 Redis, 데이터베이스처럼 지속성을 보장하는 메시지 큐 아파치 카프카(Apache Kafka)

2. 단일 도구로는 더 이상 데이터 처리와 저장 모두를 만족시킬 수 없는 과도하고 광범위한 요구사항을 지닌다.

작업은 단일 도구에서 태스크로 나누고 다양한 도구들은 서로 연결하는 방식을 이용

EX) 캐시계층(Memcached), 전문검색 서버(Elastic search)

신뢰성(Reliability) 결함 오류에 직면하더라도 지속적으로 올바르게 동작해야 한다. 무언가 잘못되더라도 지속적으로 올바르게 동작함. 결함(fault)은 뭔가 잘못된 것이고, 장애(failure)는 서비스를 제공하지 못하고 시스템이 멈춘 경우.

고의적으로 결함을 유도함으로써 내결함성 시스템을 지속적으로 훈련하고 테스트해서 결함이 자연적으로 발생했을 때 올바르게 처리할 수 있다는 자신감을 높인다.

하드웨어 결함 : 하드웨어 구성 요소에 중복(redundancy)을 추가하는 방법이 일반적. RAID, hot swap CPU, 예비 발전기 등 고장 난 구성 요소가 교체되는 동안 중복된 구성요소를 대신 사용하는 방법. 이 경우에는 SW의 운영상 장점도 있다.

소프트웨어 오류 : 하드웨어는 무작위 적이고 서로 독립적인 결함이다. 시스템 내 체계적 오류. 예상하기 어렵고 노드 간 상관관계 때문에 시스템 오류를 더욱 많이 유발하는 경향이 있다. 발생하기 전까지 나타나지 않는다. 신속한 해결책이 없다. 시스템의 가정과 상호작용에 대해 깊게 생각, 테스트, 프로세스 격리, 프로세스 재시작, 프로덕션 환경에서 동작 측정, 모니터링, 분석하기 등 여러 가지 일을 지속적으로 확인하고 경고를 발생시켜야 한다.

인적 오류 : 사람은 미덥지 않다고 알려져 있다.

확장성(Scalability) 시스템의 데이터 양, 트래픽 양, 복잡도가 증가하면서 이를 처리할 수 있는 방법

성능 저하를 유발하는 흔한 이유 중 하나가 부하 증가. 전에 처리했던 양보다 더 많은 데이터를 처리하고 있다.

확장성은 증가한 부하에 대처하는 시스템 능력. 시스템의 현재 부하를 간결하게 기술해야 한다. 부하 매개변수라 부르는 숫자로 나타낼 수 있는데 시스템 설계에 따라 달라진다. EX) 웹 서버의 초당 요청 수, DB의 읽기 대 쓰기 비율, 채팅방의 동시 활성 사용자, 캐시 적중률 등

성능 기술하기.

1. 부하가 증가할 때 자원을 유지하면 얼마나 성능이 떨어질까?

2. 부하 증가할 때 성능을 유지하려면 얼마나 자원을 투자해야 하는가?

일괄 처리 시스템은 throughput, 온라인 시스템에서는 response time을 생각하자.

지연시간(latency)과 응답시간(response time)

응답 시간은 Client관점에서 본 시간, 요청을 처리하는 실제 시간 + 네트워크 지연, 큐 지연 포함

지연시간은 요청이 처리되길 기다리는 시간. 아무것도 하지 않는 휴지(latent) 상태인 시간.

보통 얼마나 오랫동안 기다려야 하는지 알고 싶다면 중앙값이 좋은 지표이다. 절반은 중앙값 응답 시간 미만으로 제공, 나머지는 중앙값보다 오래 걸리므로.

특이 값이 얼마나 좋지 않은 지 알아보려면 상위 백분위를 살펴보는 것

아마존의 경우 내부 서비스 응답 시간 요구사항을 99.9 분위로 기술한다. (데이터 많이 쓰는 사용자가 좋은 고객이라서) 큐 대기 지연은 응답 시간의 상당 부분을 차지한다.

서버는 병렬로 소수의 작업만 처리할 수 있기 때문에 소수의 느린 요청 처리만으로도 후속 요청 처리가 지체된다. 선두 차단 (head- of -lone blocking)이라 한다. 아무리 병렬 처리를 한다고 해도 가장 오래 걸리는 호출까지 완료해야 전체 작업이 완료되므로 지연되는 효과를 꼬리 지연 증폭(tail latency amplification)라고 한다.

용량 확장(scaling up : 수직 확장) 좀더 강력한 장비로 이동

규모 확장(scaling out : 수평 확장) 다수의 낮은 사양 장비에 부하를 분산

실용적인 접근 방식의 조합이 필요하다. 일부 시스템은 탄력적으로 부하를 감지, 컴퓨팅 자원을 자동으로 추가할 수 있게 한다.

범용적이고 모든 상황에 맞는 확장 아키텍처는 없다. 읽기의 양, 쓰기의 양, 데이터의 양, 복잡도, 응답시간, 접근 패턴에 따라서 다른 아키텍처를 선택해야 한다. -> 이 가정이 곧 부하 매개변수가 된다.

유지보수성(Maintainability) 모든 사용자가 시스템 상에서 생산적으로 작업할 수 있게 해야 한다.

운용성(operability) 운영팀이 시스템을 원활하게 운영할 수 있게 만들기.

-> 동일하게 반복되는 태스크를 쉽게 수행하게끔 안 들어 운영팀이 고부가가치 활동에 노력을 집중한다는 의미

단순성(simplicity) 복잡도를 최대한 제거, 새로운 엔지니어가 시스템을 이해하기 쉽게 만들기

-> 최상의 도구는 추상화다. 좋은 추상화는 깔끔하고 직관적인 외관 아래로 많은 세부 구현을 숨길 수 있다.

발전성(evolvability) 이후에 시스템을 쉽게 변경할 수 있게 만들기.(유연성, 수정가능성, 적응성)

정리

애플리케이션이 유용하려면 기능적 요구사항, 비기능적 요구사항을 만족해야 한다.

신뢰성은 결함이 발생해도 시스템이 올바르게 동작하게 만든다는 의미

확장성은 부하가 증가해도 좋은 성능을 유지하기 위한 전략을 의미한다.

유지보수성의 본직은 시스템에서 작업하는 엔지니어와 운영 팀의 삶을 개선하는 데 있다.

간단한 해결책은 없지만 계속 재현되는 특정 패턴과 기술이 있다.

Last updated