고가용성
고가용성은 부품 하나가 죽어도 전체가 계속 응답하도록 만든 성질입니다. 여분을 미리 두는 것만으로는 안 됩니다. 죽은 것을 알아채고 남은 것으로 갈아끼우는 일까지 붙어야 합니다.
상세
쓰던 노트북에서 전원 코드가 뽑혀도 화면은 꺼지지 않습니다. 배터리가 미리 실려 있는 것만이 아니라, 전기가 끊긴 것을 노트북이 스스로 알아채 그 배터리로 곧장 넘어갑니다. 사람이 손댈 일 없이 하던 일이 그대로 이어집니다.
고가용성(High Availability, HA)은 부품 하나가 고장 나도 전체가 계속 요청을 받아내도록 만든 성질입니다. 가용성이 지금 요청을 받아낼 수 있는 상태에 있는 성질이라면, 고가용성은 그 성질을 높게 유지하려고 무엇을 하는가에 붙은 이름입니다.
세 가지가 함께 있어야 이 이름이 붙습니다. 먼저 같은 일을 할 수 있는 것이 둘 이상 있어야 합니다. 다중화입니다. 다음으로 어느 쪽이 죽었는지 알아내야 합니다. 헬스 체크나 하트비트가 그 자리를 맡습니다. 마지막으로 죽은 쪽이 받던 요청을 남은 쪽으로 옮겨야 합니다. 장애 조치입니다. 죽은 쪽을 알아내는 일과 요청을 옮기는 일은 사람이 지켜보다 손으로 하는 것이 아니라 기계가 맡습니다.
flowchart TD
A["다중화 · 여분을 둔다"] --> B["헬스 체크 · 죽은 쪽을 알아낸다"]
B --> C["장애 조치 · 남은 쪽으로 옮긴다"]
C --> D["계속 응답한다"]
셋 중 하나만 빠져도 성질이 성립하지 않습니다. 여분만 두고 감지가 없으면 죽은 쪽으로 요청이 계속 갑니다. 감지만 있고 전환이 없으면 죽었다는 사실만 남습니다.
여분을 둔다는 것은 단일 장애점을 없애는 일이기도 합니다. 하나가 죽으면 전체가 멈추는 자리가 남아 있으면, 나머지를 아무리 늘려도 그 자리에서 멈춥니다.
배경
부품은 고장 납니다. 디스크가 깨집니다. 전원이 나갑니다. 네트워크가 끊깁니다. 고장 자체를 아예 없애는 길은 없습니다. 그러면 남는 길은 둘입니다. 덜 고장 나게 만들거나, 고장 나도 빨리 되돌리거나입니다.
국제 표준 IEC 60050-192 는 가용성 정의에 주석을 하나 답니다. 가용성은 신뢰성과 회복성, 보전성, 그리고 보전 지원 성능이 결합된 특성에 달려 있다고 적습니다. 표준이 적는 것은 넷의 나열까지입니다. 이 넷을 앞의 두 길에 나눠 붙이는 것은 해석입니다. 신뢰성이 덜 고장 나게 만드는 쪽입니다. 나머지 셋이 고장 뒤에 되돌리는 쪽입니다.
부품 하나의 신뢰성을 아무리 올려도 고장 확률이 0 이 되지는 않습니다. 그래서 두 번째 길을 택한 구성이 자리를 잡았습니다. 같은 일을 할 수 있는 것을 여러 벌 두고, 죽은 것을 골라내 남은 것으로 갈아끼웁니다. 그 구성이 겨냥하는 성질에 붙은 이름이 고가용성입니다.
예시
PostgreSQL 의 동기 복제 설정
PostgreSQL 문서는 스트리밍 복제를 이미 구성했다면 동기 복제로 바꾸는 데 설정 한 단계만 더
필요하다고 적습니다. synchronous_standby_names 를 비어 있지 않은 값으로 두어야 합니다.
synchronous_commit 도 on 이어야 합니다. 다만 이 값이 기본값이라 대개는 바꿀 것이 없다고
적습니다.
이 설정은 커밋마다 대기 서버가 커밋 레코드를 지속 저장소에 기록했다는 확인을 기다리게 만듭니다. PostgreSQL 문서는 그 기다림이 서버가 죽어도 변경이 사라지지 않으리라는 사용자의 확신을 키운다고 적습니다.
Kubernetes 컨트롤 플레인 최소 대수
스택드 고가용성 클러스터는 etcd 가 제공하는 분산 데이터 저장소를 컨트롤 플레인 구성 요소가 도는 노드 위에 함께 올린 구성입니다. Kubernetes 문서는 이 구성이 외부 etcd 노드를 두는 클러스터보다 설치가 간단하고 복제 관리도 간단하다고 적습니다. 대신 결합된 실패의 위험을 안는다고 적습니다. 노드 하나가 내려가면 etcd 멤버 하나와 컨트롤 플레인 인스턴스 하나가 함께 사라져 여분이 깎입니다.
그래서 고가용성 클러스터라면 스택드 컨트롤 플레인 노드를 최소 세 대 돌려야 한다고 적습니다. kubeadm 의 기본 토폴로지입니다.
Amazon RDS 의 다중 AZ 배포
다중 AZ(Availability Zone, 가용 영역) 데이터베이스 인스턴스 배포에서는 Amazon RDS 가 다른 가용 영역에 동기 대기 복제본을 자동으로 프로비저닝하고 유지합니다. 주 인스턴스는 가용 영역을 가로질러 대기 복제본으로 동기 복제됩니다. AWS 문서는 이것이 데이터 여분을 주고 시스템 백업 중의 지연 급증을 줄인다고 적습니다.
전환도 자동입니다. 인프라 결함에서 비롯된 계획된 정지나 계획되지 않은 정지가 나면 RDS 가 다른 가용 영역의 대기 복제본으로 자동으로 넘어갑니다. AWS 문서는 전환에 걸리는 시간이 보통 60~120 초라고 적습니다. 큰 트랜잭션이나 긴 복구 과정이 있으면 그 시간이 늘어날 수 있다고 덧붙입니다.
대가
여분을 두고 갈아끼우는 구성은 네 가지를 내줍니다.
노드 수
같은 일을 하는 것을 여러 벌 두므로 장비가 곱절 이상 듭니다. Kubernetes 문서는 외부 etcd 토폴로지가 스택드 토폴로지의 두 배에 해당하는 호스트를 요구한다고 적습니다. 이 토폴로지의 고가용성 클러스터에는 컨트롤 플레인 노드 세 대와 etcd 노드 세 대가 필요합니다.
노드를 더 넣는다고 견디는 고장 수가 따라 늘지는 않습니다. etcd 문서는 클러스터 상태 갱신에 합의하려면 멤버의 과반, 즉 정족수가 필요하다고 적습니다. 멤버가 n 개인 클러스터의 정족수는 (n/2)+1 입니다. 홀수 크기 클러스터에 노드를 하나 더하면 정족수에 필요한 노드 수가 언제나 늘어납니다. 기계가 많아지니 나아 보이지만, 정족수를 잃지 않고 죽을 수 있는 노드 수는 똑같은데 죽을 수 있는 노드만 늘어나므로 내결함성은 오히려 나빠진다고 적습니다. 그래서 멤버 수를 홀수로 두기를 권합니다.
비용도 단계마다 같지 않습니다. 구글이 펴낸 사이트 신뢰성 엔지니어링 책은 시스템을 지어 본 경험상 비용이 신뢰성 증가분에 선형으로 늘지 않는다고 적습니다. 신뢰성을 한 단계 더 올리는 데 이전 단계의 100배가 들 수도 있다고 적습니다. 비용에는 두 축이 있다고 적습니다. 하나는 여분 장비와 계산 자원의 비용입니다. 다른 하나는 기회비용입니다. 위험을 줄이는 시스템을 짓는 데 엔지니어링 자원을 쓰면 최종 사용자에게 바로 보이거나 쓰이는 기능에는 그만큼 못 씁니다.
커밋 지연
동기 복제는 대기 서버의 응답을 기다립니다. PostgreSQL 문서는 확인을 기다리면 서버가 죽어도 변경이 사라지지 않으리라는 사용자의 확신이 커진다고 적습니다. 다만 그것이 요청한 트랜잭션의 응답 시간도 필연적으로 늘린다고 적습니다. 최소 대기 시간은 주 서버와 대기 서버 사이의 왕복 시간입니다. 읽기 전용 트랜잭션과 트랜잭션 롤백은 대기 서버의 응답을 기다릴 필요가 없습니다.
이 확신은 기다림에서 나옵니다. 확인을 기다리지 않는 쪽을 비동기 복제라고 부릅니다.
관리형 서비스에서도 같은 값을 치릅니다. AWS 문서는 다중 AZ 배포를 쓰는 데이터베이스 인스턴스가 단일 AZ 배포에 비해 쓰기 지연과 커밋 지연이 늘어날 수 있다고 적습니다. 동기 데이터 복제 때문에 그럴 수 있다고 적습니다.
스플릿 브레인
없던 실패 경로가 생깁니다. 주 서버가 죽어 대기 서버가 새 주 서버가 된 다음, 옛 주 서버가 다시 시작하는 경우입니다. PostgreSQL 문서는 그 옛 주 서버에게 더 이상 주가 아니라는 것을 알리는 장치가 반드시 있어야 한다고 적습니다. 이것을 STONITH(Shoot The Other Node In The Head)라고 부르기도 한다고 적습니다.
없으면 두 시스템이 모두 자기가 주라고 여기는 상황이 됩니다. 문서는 그 상황이 혼란을 낳고 결국 데이터 유실로 이어진다고 적습니다. 클러스터가 갈라져 양쪽이 각자 주 노드라고 여기는 이 상태를 스플릿 브레인이라고 부릅니다.
flowchart TD
A["주 서버 장애"] --> B["대기 서버가 주로 승격"]
B --> C["옛 주 서버가 다시 시작"]
C --> D{"더 이상 주가 아님을 알리는 장치"}
D -->|있다| E["옛 주 서버가 물러난다"]
D -->|없다| F["둘 다 자기가 주라고 여긴다"]
전환 장치의 운영
장애를 감지하고 전환하는 장치를 따로 붙여야 합니다. PostgreSQL 문서는 주 서버의 장애를 식별해 대기 데이터베이스 서버에 알리는 시스템 소프트웨어를 PostgreSQL 이 제공하지 않는다고 적습니다. 그런 도구가 많이 있다고 적습니다. 그리고 그 도구들이 성공적인 페일오버에 필요한 IP 주소 이전 같은 운영체제 기능과 잘 통합되어 있다고 적습니다.
붙이면 지켜볼 것도 늘어납니다. 같은 문서는 많은 페일오버 시스템이 주 서버와 대기 서버 두 대만 쓴다고 적습니다. 그리고 둘을 하트비트로 이어 서로의 연결성과 주 서버의 생존을 계속 확인한다고 적습니다.
경계
읽기 요청을 여러 대에 나눠 보내는 구성도 고가용성인가. 아닙니다. 그것만으로는 부하 분산입니다.
PostgreSQL 문서는 둘을 한 문장 안에서 나란히 가릅니다. 데이터베이스 서버들이 함께 일해 기본 서버가 죽으면 두 번째 서버가 빠르게 넘겨받게 하는 것을 고가용성이라고 적습니다. 여러 대가 같은 데이터를 서비스하게 하는 것은 부하 분산이라고 적습니다. 같은 문서는 정적 웹 페이지를 내보내는 웹 서버가 요청을 여러 대로 분산하기만 해도 꽤 쉽게 묶인다고 적습니다. 읽기 전용 데이터베이스 서버도 비교적 쉽게 묶인다고 적습니다.
가르는 자리는 한 대가 죽은 다음입니다. 나눠 보내기만 하는 구성은 죽은 대를 계속 후보로 둡니다. 죽었다는 것을 알아내고 남은 대로 요청을 옮기는 장치가 따로 붙어야 고가용성이 됩니다. 그 장치는 저절로 딸려 오지 않습니다. PostgreSQL 문서가 주 서버의 장애를 식별해 알리는 시스템 소프트웨어를 제품이 주지 않는다고 적는 자리가 그 지점입니다.
판정 기준은 구성을 무엇이라 부르느냐가 아니라 감지와 전환이 붙어 있느냐입니다.
관련 항목
고가용성을 이루는 구성 요소
다중화 · 헬스 체크 · 하트비트 · 페일오버 · IP 주소 · 운영체제 · 액티브-스탠바이 · 액티브-액티브
고가용성이 마주치는 실패와 막는 장치
단일 장애점 · 스플릿 브레인 · STONITH · 정족수 · Raft
고가용성 구성이 쓰는 복제 방식
복제 · 동기 복제 · 비동기 복제 · 대기 서버
동기 복제가 기다리는 트랜잭션 단위
고가용성을 실제로 구현·채택한 제품
PostgreSQL · Kubernetes · AWS · etcd · Patroni · Pacemaker
고가용성 클러스터를 이루는 배포 단위
클러스터 · 노드 · 배포 · 가용 영역 · 컨트롤 플레인
고가용성이 속하는 상위 분류
소프트웨어 아키텍처 · 데이터베이스 · 분산 시스템
고가용성과 헷갈리는 이웃
고가용성이 딛고 선 가용성의 구성 성질
고가용성이 대비하는 고장 원인
고가용성이 대가로 늘리는 지표
다른 이름: High Availability · HA · 고가용성 구성