반응형
[데이터 중심 애플리케이션 설계]
01. 신뢰할 수 있고 확장 가능하며 유지보수하기 쉬운 애플리케이션
1. 데이터 시스템
- 오늘 날의 어플리케이션은 계산 중심(compute-intensive)보다 데이터 중심(data-intensive) 적이다.
- CPU 성능보다는 데이터 양, 데이터 복잡도 등이 더 문제다.
- 많은 애플리케이션은 다음을 필요로 한다.
- 데이터베이스 : 영속성 스토리지
- 캐시 : 읽기 속도 향상, 값비싼 수행 결과 기억
- 검색 색인 : 사용자가 키워드로 데이터를 검색하거나 다양한 방법으로 필터링할 수 있게 제공
- 스트림 처리 : 비동기 처리를 위해 다른 프로세스로 메세지 보내기
- 일괄(batch) 처리 : 주기적으로 대량의 누적된 데이터를 분석
1.1 데이터 시스템에 대한 생각
데이터베이스, 큐, 캐시등은 매우 다른 접근 패턴을 갖고 있는데 왜 데이터 시스템이라는 포괄적 용어로 묶어야 할까?
- 새로운 도구들은 다양한 사용 사례로, 분류 간 경계가 흐려지고 있기 때문에
- 단일 시스템으로는 어플리케이션 니즈를 충족시킬 수 없음. 복합 데이터 시스템으로 흘러감
2. 소프트웨어 시스템에서 중요한 세가지
- 신뢰성(Reliability) : 하드웨어나 소프트웨어 결함, 인적 오류에 직명해도 시스템은 지속적으로 올바르게 동작해야 함
- 확장성(Scalability) : 데이터의 양, 트래픽, 복잡도가 증가해도 이를 처리할 수 있는 적절한 방법이 있어야함.
- 유지보수성(Maintainability) : 모든 사용자가 시스템 상에서 생산적으로 작업할 수 있어야 함.
2.1.1 신뢰성
소프트웨어에 기대하는 일반적인 기대치는 아래와 같다.
- 애플리케이션은 사용자가 기대한 기능을 수행한다.
- 시스템은 사용자가 범한 실수나 예상치 못한 소프트웨어 사용법을 허용할 수 있다.
- 시스템 성능은 예상된 부하와 데이터 양에서 필수적인 사용 사례를 충분히 만족한다.
- 시스템은 허가되지 않은 접근과 오남용을 방지한다.
2.1.2 신뢰성과 관련된 용어들
-
- 결함 : 사양에 벗어난 시스템의 구성 요소
- 내결함성 또는 탄력성 : 결함(fault)을 예측하고 대처할 수 있는 능력
- 장애 : 사용자에게 필요한 서비스를 제공하지 못하고 시스템이 멈춤
- 결함으로 인해 장애가 발생하지 않도록 내결함성 구조로 설계해야함
- 결함을 0으로 줄일 수는 없으므로 결함으로 인해 장애가 발생하지 않게끔 내결함성 구조로 설계해야 한다.
2.1.3 하드웨어 결함
- 시스템 장애의 대부분의 원인 : 디스크, 램 고장. 대규모 정전, 담당자가 장비를 잘못 다룸
- 대응 방안 : 하드웨어 구성에 중복(redundancy)을 추가
- 디스크 : RAID
- 서버 : 이중 전원 디바이스, hot-swap CPU
- IDC : 예비용 전원 발전기
- 데이터 양과 애플리케이션의 계산 요구가 늘어나면서 더 많은 장비를 사용하게 되어 하드웨어 결함율도 증가했다.
- 일부 클라우드는 단일 장비의 신뢰성보다 유연성과 탄력성을 우선적으로 처리하게끔 설계
- 따라서 소프트웨어 내결함성 기술이나 하드웨어 중복성을 추가해 전체 장비의 손실을 견딜 수 있게 하자
2.1.4 소프트웨어 결함
- 상관관계가 미미한 하드웨어에 비해 시스템 내 체계적 오류(systematic error)는 예상하기 어렵고 오류를 더욱 많이 유발한다.
- 특정 상황에 의해 발생하기 전까지 나타나지 않을수도 있다.
- 명확한 해결책은 없다. 빈틈없는 테스트, 프로세스 격리, 모니터링, 알람체계를 잘 갖춰서 설계하자.
2.1.5 인적 오류(human error)
대규모 인터넷 서비스는 하드웨어 결함은 중단원인의 10 ~ 25% 그치는 반면, 운영자의 설정 오류는 주 원인이다.
- 대응방안
- 잘 설계된 추상화 API, 인터페이스를 사용하라. 옳은 일은 쉽게하고 잘못된 일을 막을 수 있다.
- 실수가 잦게 발생하는 곳은 실제 데이터로 안전하게 실험해볼 수 있는 sandbox 를 제공하라 (ex. stage환경)
- 단위테스트, 통합테스트, 수동테스트를 철저히 해라. 특히 정상적인 동작에서는 거의 발생하지 않는 코너케이스에 유의
- 장애를 빠르게 복구 할 수 있게 도구를 만들어라. 버그는 빠르게 롤백하고 새로운 코드는 서서히 롤아웃 해라.
- 모니터링이 중요하다. 지표를 분석해라
2.2 확장성
성능 저하를 유발하는 흔한 이유 중 하나는 부하 증가다.
2.2.1 부하 기술하기
- 부하 성장 질문
- 부하가 두 배로 되면 어떻게 될까?
- 추가 부하를 다루기 위해 계산 자원을 어떻게 투입할까?
- 부하 매개변수 : 부하는 부하매개변수라는 몇개의 항목으로 나타낼 수 있다.
- 각 시스템 설계에 따라 달라진다.
- ex) 웹 서버의 초당 요청 수, 데이터베이스의 읽기 대 쓰기 비율, 캐시 적중률등
- 평균적인 경우가 중요할 수도 있고, 소수의 극단적인 경우가 병목 현상의 원인 일 수도 있다.
2.2.2 성능 기술하기
시스템 부하를 기술하면 부하가 증가할 때 어떤 일이 일어나는지 조사할 수 있다.
- 부하 매개변수를 증가시키고 시스템 자원은 변경하지 않으면 시스템 성능은 어떻게 영향을 받을까?
- 부하 매개변수를 증가시켰을 때 성능이 변하지 않고 유지되길 원한다면 자원을 얼마나 많이 늘려아 할까?
- 하둡같은 일괄 처리 시스템은 처리량에 관심이 있지만, 서비스들은 응답시간에 관심이 있다.
- 응답시간은 요청마다 매번 다르다. 따라서, 분포로 생각해야한다.
- 응답시간 분석에 백분위를 사용하고, 중앙값(p50)을 지표로 삼아라
- 특이점 = p95, p99, p999
- 꼬리 지연 시간으로 알려진 상위 백분위 응답 시간은 보통 많은 구매를 해서 가장 많은 데이터를 갖고있기 때문에 중요한 고객이다.
- 큐 대기 지연은 응답시간의 상당 부분을 차지한다.
- 선두 차단(head-of-line blocking) : 서버는 병렬로 소수의 작업만 처리할 수 있기때문에, 첫 요청을 처리하는데 느려진다면 후속 요청이 모두 영향받는다.
- 시스템의 확장성을 테스트하기 위해 인위적으로 부하를 생성하는 경우, 부하 생성 클라이언트는 응답시간과 독립적으로 요청을 계속 보내야한다. 응답을 기다리고 다음 요청을 보내면 평가가 의미없다.
2.2.3 부하 대응 접근 방식
부하 매개변수가 어느 정도 증가하더라도 좋은 성능을 유지하려면 어떻게 해야 할까?
- 용량확장(=수직확장=scaling up) 과 규모확장(=수평확장=scaling out) 사이에서 실용적인 조합을 찾아야한다.
- 적절한 사양의 장비 몇 대가 다량의 낮은 사양 가상 장비보다 여전히 훨씬 간단하고 저렴하다.
- 탄력적(elastic) : 부하 증가를 감지하면 자동으로 자원 추가
- 탄력적인 시스템은 부하를 예측할 수 없을 만큼 높은 경우 유용하지만 수동 확장이 더 간단하고 예상치 못한 운영이슈가 적다.
- 분산환경이 필요해질때 까진 스케일업하는게 보통이지만, 요새는 분산시스템과 추상화가 워낙 좋아져서, 처음부터 고려해볼만도 하다.
2. 3 유지보수성
- 많은 사람들은 레거시 시스템을 유지보수하는 것을 좋아하지 않으므로, 처음부터 레거시를 만들지 않게 끔 설계해야한다.
- 유지보수성이 좋은 소프트웨어 시스템 설계 원칙
- 운용성 : 운영팀이 원활하게 운영할 수 있도록 쉽게 만들어라
- 단순성 : 복잡도를 최대한 제거해 새로운 팀원도 잘 이해할 수 있게 만들어라
- 발전성 : 이후 변경에 열려있어야 한다. 요구사항 변경같은 새로운 사용사례를 쉽게 적용할 수 있어야한다. 이 속성은 유연성, 수정가능성, 적응성으로 알려져있다.
3. 운용성: 운영의 편리함 만들기
- 운영 중 일부 측면은 자동화할 수 있고, 자동화해야한다.
- 하지만 자동화를 처음 설정하고 제대로 동작하는 지 확인하는 것도 여전히 사람이 해야한다.
- 좋은 운영성 : 반복되는 태스크들을 쉽게 수행할 수 있도록 하는 것
- 런타임 동작과 시스템 내부에 대한 가시성 제공
- 좋은 문서
- 이해하기 쉬운 운영모델 : X를 하면 Y가 발생
- 어드민 등으로 기본값을 재정의할 수 있는 권한 부여
- 자기 회복이 가능할 뿐아니라 관리자가 상태를 수동으로 제어할 수 있어야 함
4. 단순성: 복잡도 관리
- 시스템이 복잡해지면 모든 사람의 진행을 느리게하고, 유지보수 비용이 증가한다.
- 복잡성의 사례들 : 상태 공간의 급증, 모듈 간 강결합성, 일관성 없는 네이밍, 임시방편 코드들
- 이런 복잡도 때문에 시스템 유지보수가 어려울 때 예산과 일정이 초과되곤 한다.
- 우발적 복잡도(accidental complexity)를 제거하기 위한 최상의 도구는 '추상화' 다
- 좋은 추상화는 깔끔하고 직관적인 외관 아래로 세부 구현을 숨길 수 있다.
- 재사용성이 좋아진다.
5. 발전성: 변화를 쉽게 만들기
- 시스템 요구사항은 계속 바뀐다.
- 애자일(agile) 작업 패턴은 변화에 적응하기 위한 프로세스이다.
- 작고, 로컬규모에 초점을 맞춰라
728x90
반응형
'스터디 > 데이터 중심 애플리케이션 설계' 카테고리의 다른 글
[데이터 중심 애플리케이션 설계] 06. 파티셔닝 (1) | 2023.01.02 |
---|---|
[데이터 중심 애플리케이션 설계] 05. 분산 데이터와 복제 (0) | 2022.12.29 |
[데이터 중심 애플리케이션 설계] 04. 부호화와 발전 (0) | 2022.12.28 |
[데이터 중심 애플리케이션 설계] 03. 저장소와 검색 (2) | 2022.12.21 |
[데이터 중심 애플리케이션 설계] 02. 데이터 모델과 질의 언어 (0) | 2022.12.14 |
댓글