# 1장 신뢰성, 확장성 그리고 유지보수성
데이터 중심 애플리케이션 구축(Designing Data-Intensive Application, 2017) 책을 읽고 정리하였습니다.
신뢰성(Reliability)
시스템이 올바르게 작동하도록 만드는 것
확장성(Scalability)
부하증가시에 성능을 좋게 뽑아낼 수 있는 것
유지보수성(Maintainability)
여러 측면이 있지만, 엔지니어와 운영팀의 삶 더 나아지게 목표하는 것
어플리케이션에서 당연히 필요한 것들
데이터베이스
캐시
검색 엔진
스트리밍 프로세싱
배치 프로세싱
1. 신뢰성
응용 프로그램은 사용자가 예상한 기능을 수행합니다.
사용자가 실수를 하거나 소프트웨어를 예기치 않은 방식으로 사용하는 것을 수용할 수 있습니다.
예상로드 및 데이터 볼륨에서 요구된 사용 환경에 충분한 성능을 제공합니다.
시스템은 무단 액세스 및 남용을 방지합니다.
즉, 어떠한 상황에도 잘 수행된다는 것
fault와 failure 차이
fault - 일반적으로 사양에서 벗어난 시스템의 한 구성 요소
failure - 시스템이 전체적으로 사용자에게 필요한 서비스를 제공하지 못하는 경우
결론, fault를 줄여가면 failure가 발생하지 않게 만들어 가는 것. (eg. 넷플릭스 카오스 몽키)
1.1 하드웨어 fault 막기
하드웨어는 평균 고장시간(MTTF) 10~50년 정도 걸린다.
예방법
RAID
듀얼 파워서플라이
배터리와 디젤 전기생산기가 있는 데이터센터 구축
전원이 켠상태로 교체 가능(hot-swappable)한 CPU
*a rolling upgrade -> 전체 시스템 죽이지 않고 노드 하나씩 패치하는 방법.
1.2 소프트웨어 에러
하드웨어 하나가 고장났다고 전부가 고장나는 경우는 매우 드물다.(자연재해 같은것 말고) = weak correlations이에 반해, 소프트웨어는 하나 고장시 도미노 처럼 무너지는 경우가 생길 수 있다.(예시 - leap second / 무한회귀하는 프로세스(runaway process) - 자원 고갈) 예방법
잘 설계된 추상화, API 및 관리 인터페이스
샌드박스 환경 제공 -> 실제 사용자에게 영향을주지 않고 실제 데이터를 사용하여 안전하게 실험할 수 있는 환경을 제공
테스트 -> 단위 테스트에서 전체 시스템 통합 테스트에 이르기까지 모든 수준에서 철저히 테스트. 자동화 테스트 사용( corner cases 찾기 좋음 )
빠르고 쉬운 복구 -> roll out new code gradually
모니터링-> 성능 지표(performance metrics) 및 오류율(error rate)
준수한 관리 관행 및 교육
2. 확장성
2.1 부하 확인
소프트웨어의 성능 저하는 대부분 increased load. 즉, Scalability = 증가한 부하를 잘 대응할 수 있는 가능성이고, 측정이 가능해야 확장 가능성에 대해 대화가능하다.
부하 매개변수load parameters) 숫자들로 설명가능. 예를 들어,
초당 웹서버 들어오는 요청수
읽기에 대한 쓰기에 대한 비율
채팅룸에서 유저들의 동시 접속수
캐시의 hit rate
트위터 사례분석(트위터의 두가지 기능 - Post tweet / Home timeline)
과정: 사용자가 홈 타임 라인을 요청 -> 팔로우하는 모든 사람을 찾아 각 사용자에 대한 모든 트윗을 검색 -> 시간별로 정렬
1. Post tweet - 팔로워들에게 새로운 메시지를 보낸다.(초당 4600개에서 최대 12000개 요청) 2. Home timeline - 팔로우하는 사람들의 트윗을 확인한다. (초당 300,000 요청)

tweets트윗 내용 테이블users유저 테이블follows유저가 팔로우하는 팔로이들 목록 테이블
내가 쿼리를 짯다면... 인라인로 유저테이블과 팔로우테이블을 조인하여 현재 유저가 팔로우하는 follow_id를 받는다. 이 follow_id로 트윗테이블을 찾아가면서 트윗을 가져와 홈타임라인에 표시한다.
2.2 성능 확인
부하를 확인할 수 있게 되었으면, 부하가 높아졌을 때 성능을 측정한다.
CPU, 메모리 그리고 네트워크 대역폭과 같은 자원증축 없이, 부하 파라미터를 증가시키면 성능이 어떻게 변화할까?
부하증가시 성능변화없이 유지하고 싶다면, 얼마나 많은 자원을 투입해야할까?
배치처리 시스템 -> 처리량(throughput)이 중요 온라인 시스템 -> 서비스의 응답시간이 중요
지연시간(Latency)와 응답시간(Response time) 차이
Latency - 요청이 처리되기 위해 기다리는 시간
Response time - 요청을 처리하는데 드는 실제 서비스시간(네트워크지연, 큐잉지연 포함).

동일한 서비스 실행 시 답시간이 다른 이유들
백그라운드 프로세스로의 컨택스트 스위치
네트워크 패킷 손실과 TCP 재전송
가비지 컬렉션 멈
디스크로부터 강제 읽게하는 페이지 오류
서버랙(장비틀)의 기계적인 진동
기타 등
이러한 이유들로, 성능측정시에는 백분위수(percentiles)을 이용한다. (응답시간 리스트를 시간 순서대로 나열해 중간지점(median)을 구한다.) 이로써 유저가 평균적으로 얼마나 기다려야 하는지를 알 수 있다. 아마존에서 응답시간이 0.1초 증가시 판매가 1% 떨어지는 것을 확인하였고, 다른 조사기관에서 1초가 느려질시 소비자 만족지수가 16% 떨어짐을 확인하였다. 따라서, 응답시간을 잘 체크 해야한다. (SLA에도 이용)
2.3 부하를 다루기 위한 접근법
부하 파라미터가 어느 정도 증가하더라도 어떻게 우수한 성능을 유지해야 할까?
scaling up(vertical scaling)
scaling out(horizontal scaling)
elastic - 자동으로 자원 추가하는 것. (unpredictable한 시스템에 좋다.)
*shared-nothing = 부하를 여러 머신에 나누는 것.
3. 유지보수성
레거시시스템은 종사자들에 눈엣가시다. 다른사람의 실수들을 수정하는 상황이 생기고, 요즘 쓰지 않는 플랫폼들 같은 것들이 들어있어 미래에 투입된 종사자들이 개입하기 싫어한다. 따라서, 웃는 모습으 레거시 시스템에 다가갈 수 있게 사전에 지켜야할 원칙들이 있다.
Operability - 운영팀을 위한
Simplicity - 새로 투입된 엔지니어를 위한
Evolvability - 엔지니어를 위한
3.1 Operability
좋은 운영성은 일상적인 작업을 쉽게 만들어 운영 팀이 고부가가치(high-value) 활동에 집중할 수 있도록 한다. 그럼 이러한 것에는 어떤것들이 있을까요?
우수한 모니터링 기능 제공 -> 런타임 동작 및 시스템 내부에 대한 가시성 제공.
자동화 및 표준 도구와의 통합 제공 .
개별 시스템에 대한 종속성 방지. (시스템 전체가 중단없이 계속 실행되는 동안, 유지 관리를 위해 시스템이 중단되도록 허용)
좋은 문서와 이해하기 쉬운 운영 모델 제공. (예를 들어, "X를 하면 Y가 발생합니다")
기본 동작은 양호하지만 관리자는 필요할 때 기본값을 무시할 수있는 자유를 제공. 뭔말?
기본적으로 좋은 동작을 제공하지만, 필요할 경우 관리자가 시스템을 수동으로 수정가능하게 제공.
예측 가능한 행동을 나타내어주어 향후 발생하는 예기치 못한 상황 최소화.
Providing visibility into the runtime behavior and internals of the system, with good monitoring
Providing good support for automation and integration with standard tools
Avoiding dependency on individual machines (allowing machines to be taken down for maintenance while the system as a whole continues running uninterrupted)
Providing good documentation and an easy-to-understand operational model(“If I do X, Y will happen”)
Providing good default behavior, but also giving administrators the freedom to override defaults when needed
Self-healing where appropriate, but also giving administrators manual control over the system state when needed • Exhibiting predictable behavior, minimizing surprises
3.2 Simplicity
시스템이 복잡해지면 시스템 작업이 필요한 모든 사람들이 느려지고 버그가 발생할 확률이 높 유지 관리 비용이 추가된다. 이러한 복잡한 소프트웨어는 진흙속의 큰공(as a big ball of mud)으로 묘사된다. 엉망진창이라는 뜻.
복잡한 소프트웨어의 증상들
상태 공간의 폭발
모듈의 밀접한 결합(tight coupling)
얽힌 종속성
일관되지 못 이름 및 용어
성능 문제 해결을 위한 해킹
다른 문제를 해결하기 위한 특수 사례
기타 등등
복잡성을 제거할 수있는 방법 추상화 사용이 있다. 추상화는 의도치 않은 복잡성 제거하여 구현 세부 사항을 숨길 수 있다. 추상화가 적용된 개념의 예를 들자면, 머신 코드, CPU 레지스터 및 시스템 콜을 숨기는 고급 프로그래밍 언어가 추상화이고 복잡한 온 디스크 및 인 메모리 데이터 구조, 다른 클라이언트의 동시 요청 및 충돌 후 불일치를 숨기는 SQL도 추상화가 된다.
3.3 Evolvability
시스템이 평생 변경되지 않고 가는 일은 없다. 비즈니스 우선순위가 변하거나 종사자들이 새로운 기술을 배워온다던가 사용자가 새로운 요구사항을 요청할 수도 있기 때문이다. 이렇게 자주 변화하는 환경에서 소프트웨어를 개발할 때를 위한 애자일이 있다. (애자일 커뮤니티는 TDD (Test-driven development) 및 리팩토링과 같이 자주 변화하는 환경에서 소프트웨어를 개발할 때 유용한 기술 도구 및 패턴을 개발하였다.) 그러나 대부분의 전문가들의 의견으로, 이 애자일 기법은 적은 규모(a couple of source code files within the same application)로 개발할때 유용한 기술이다. 따라서 큰 데이터 시스템 수준에서 민첩성(Agility)을 높이는 방법을 이후에 더 찾아보자.
다음장에서는 데이터 시스템들의 목적을 달성하기 위해 어떻게 작동되는지 확인해보자.
첫번째장이라 정리를 너무 못한 것같다... 다음장부터 더 꼼꼼히 해보자.
Last updated