1. 신뢰할 수 있고 확장 가능하며 유지보수하기 쉬운 애플리케이션

조현창·2022년 12월 27일
0

1장에서는 신뢰성 확장성 유지보수성을 달성하기 위한 방법을 알아본다.
2장에서는 데이터 모델과 질의 언어를 비교한다. 데이터베이스를 가장 가시적으로 구별할 수 있는 요소다.
3장에서는 저장소 엔진과 디비가 어떻게 데이터를 배치하는지 알아본다.
4장에서는 데이터 부호화(직렬화)포맷을 비교한다. 스키마를 변경해야하는 환경에서 어떻게 사용되는지 살펴본다.

이후 2부에서는 분산 파일 시스템의 특정한 문제를 다룬다.

오늘날 많은 애플리케이션은 계산 중심과는 다르게 데이터 중심적이다. 결국 CPU성능보다 데이터의 양, 복잡도, 변화 속도를 중점적으로 보아야한다.

  • 다시 데이터를 찾을 수 있게 데이터를 데이터베이스에 저장
  • 읽기 속도 향상을 위해 코스트가 큰 결과를 캐싱
  • 사용자가 데이터를 필터링할 수 있게 검색 색인 제공
  • 비동기 처리를 위해 스트림으로 다른 프로세스에 메세징
  • 주기적으로 누적된 데이터를 배치 처리

데이터 시스템에 대한 생각

데이터베이스, 큐, 캐시를 데이터 시스템이라는 용어로 묶어야 하는 이유
각각은 최근에 만들어졌다. 새로운 도구들은 특정 사례에 최적화됐기 때문에 전통적인 분류에 들어맞지 않는다.

따라서 단일 작업(work)을 단일 도구에서 수행할 수 있는 일(task)로 나누고 코드를 이용해 연결한다.

인메모리캐시(멤캐시디)를 지원하는 도구를 이용하여 애플리캐이션이 관리하는 캐시 계층을 사용하거나 Elasticsearch, Solr처럼 풀텍스트 검색 서버의 경우 디비와 동기화된 캐시나 색인을 유지하는 것은 보통 애플리케이션 코드의 책임이다.

신뢰성

하드웨어, 소프트웨어 결함, 휴먼에러같은 역경에 직면하더라도 시스템은 지속적으로 정확한 기능을 수행해야한다.

  • 기대한 기능
  • 사용자의 실수나 이상한 사용법을 허용해야함
  • 부하와 많은 데이터에서 필수적인 사례를 만족
  • 허가되지 않은 접근, 오남용 방지

잘못될 수 있는 일을 결함이라고 한다. 이를 대처할 수 있는 시스템을 내결함성 또는 탄력성을 가졌다고 한다.
결함은 시스템 전체가 멈춘 장애와 달리 사양에서 벗어난 한 구성요소다.

하드웨어 결함

하드 디스크는 10000개의 디스크가 있을 때 평균적으로 하루 한 개의 디스크가 죽는다고 예상해야한다.
이를 해결하기 위해 디스크는 RAID 구성으로 설치할 수 있고 서버는 이중 전원 디바이스와 핫 스왑 가능한 CPU를 데이터센터는 건전지와 예비 전원용 디

확장성

데이터, 트래픽, 복잡도가 증가하면서 이를 처리할 수 있는 적절한 방법이 있어야 한다.
규모가 늘어나더라도 이에 대처하기위한 방안이 있어야한다.

부하 기술하기

웹서버의 초당 요청 수, 디비 읽기/쓰기 비율, 대화방의 동시 활성 사용자, 캐시 적중률
평균적인 경우와 극단적인 경우를 파악해야한다.

트위터

팔로워에게 메세지 게시(초당 4.6k, 최대 12k)
홈 타임라인 조회 (초당 300k)

타임라인 조회

select tweets.*, users.* from tweets
	join users on tweets.sender_id = users.id
	join follows on follows.followee_id = users.id
	where follows.follower_id = current_user

매번 리프레쉬할 때마다 해당 조인이 발생하면 엄청난 부하가 아닐 수 없다
따라서 해당 데이터를 캐싱해두고 메세지를 게시하면 캐싱된 데이터에 해당정보를 추가한다.
또한 작성시 부가 요청이 많은 경우(팔로워가 많은 경우) 게시할 때 캐싱데이터에 추가하는 작업이 부하가 커지므로 해당 사용자의 게시글만 직접 디비를 조회해 가져오도록 한다.

성능 기술하기

처리량 : 초당 처리할 수 있는 레코드 수나 일정 크기의 데이터 집합으로 작업을 수행할 때 걸리는 전체 시간
응답 시간: 클라이언트가 요청을 보내고 응답을 받는 사이의 시간

지연시간 latency: 서비스를 기다리며 휴지 상태인 시간
응답시간 response time: 네트워크 지연, 큐 지연을 포함한 전체 시간

컨텍스트 스위치가 발생하거나 네트워크 패킷 손실과 TCP 재전송, 가비지 컬렉션 휴지, 페이지 폴트, 서버 랙등으로 지연이 발생할 수 있다.

이 때 지표는 산술 평균보다는 중앙값을 사용한다.
백분위를 통한 중앙값은 서비스 수준 목표와 서비스 수준 협약서에 자주 사용하고 기대 성능과 서비스 가용성을 정의하는 계약서에서도 자주 등장한다. "응답 시간 중앙값이 200밀리초 미만이고 99분위가 1초 미만인 경우(응답 시간이 길면 서비스가 종료될 수도 있다) 정상 상태이며 제공 기간은 99.9% 이상이어야한다."

후속 요청 처리가 현재 처리중인 요청으로 인해 지체되는 현상을 선두 차단이라고 한다.

최종 사용자 요청중 많은 비율이 느려지는 현상을 꼬리 지연 증폭이라고 한다.

부하 대응 접근 방식

용량확장(수직확장) : 사양을 높인다
규모확장(수평확장): 여러대를 사용한다.
다수의 장비에 부하를 분산하는 아키텍처를 비공유 아키텍처라고 부른다.

탄력적 시스템(AWS)는 부하를 예측할 수 없을 경우는 유용하지만 수동 확장이 더 예측가능하다.(파티션 재구성등이 일어날 수 있기 때문)

만약 많은 장치를 사용할 경우 stateful(세션)을 사용할 경우 아주 많은 복잡도가 생긴다. 이런 용례에는 수직확장을 하는 것이 일반적이다.

아키텍처를 결정하는 요소는 읽기, 쓰기, 데이터의 양, 복잡도, 요구사항, 접근 패턴이 있다.

각 크기가 1kb인 초당 100,000건의 요청을 처리하도록 설계한 시스템과 2GB 요청을 3건 처리하는 시스템은 매우 다르다.

유지보수성

프로그래머가 생산적으로 작업할 수 있게 한다.
버그 수정, 시스템 운영 유지, 장애 조사, 새로운 플랫폼 적응, 새 요구사항을 위한 변경, 기술 채무 상환 등이 있다.

레거시를 최대한 안만들어야한다.

운용성

운영팀이 원활하게 운영할 수 있게 만들어라

단순성

복잡도를 최대한 제거해 새로운 엔지니어가 시스템을 이해하기 쉽게 만들어라

발전성

유연성 수정 가능성 적응성

운용성

자동화를 통해 반복 태스크를 쉽게 하여 고부가 가치활동에 노력을 기울일 수 있도록 합니다.

단순성: 복잡도 관리

상태 공간의 급증, 모듈간 의존성, 일관성없는 명명, 해킹으로 인한 유지보수성 저하 특수사례로 인한
해킹등이 있다.

추상화와 고수준의 모듈화를 통해 이런 복잡도를 관리해야한다.

발전성: 변화를 쉽게 만들기

애자일과 TDD 리팩토링을 통해 앞서 언급한 복잡도관리와 운용성을 기반으로 빠르게 수정및 반영이 가능하도록하여 변화를 쉽게 만든다.

profile
공부중

0개의 댓글