Skip to content
난이도 문제은행 3

그룹 복제와 InnoDB 클러스터 ​

HA(High Availability, 고가용성)는 서버 한 대가 죽어도 서비스가 계속되게 하는 성질이다. 일반 복제(replication)로 레플리카(replica)를 두어도, 장애를 알아채고 쓰기를 받을 새 소스(source)를 고르고 애플리케이션 연결을 옮기는 일은 따로 해야 한다. 그룹 복제(Group Replication)는 서버들이 서로 합의해서 트랜잭션(transaction) 순서를 정하고 장애 난 멤버를 스스로 빼는 복제 방식이다. 그 위에 클러스터를 만들고 관리하는 MySQL Shell과, 애플리케이션 연결을 알맞은 멤버로 보내는 MySQL Router를 묶은 것이 InnoDB 클러스터(InnoDB Cluster)다. 이 문서는 장애 조치(failover)가 무엇을 해야 하는지와 그룹 복제가 커밋(commit)을 어떻게 합의하는지를 다룬다.

고가용성과 장애 조치 ​

가용성은 서비스를 쓸 수 있는 시간의 비율로 말한다. 99.99%면 1년에 약 53분만 멈춰도 된다는 뜻이다. 이 목표를 두 숫자로 나눠 생각하면 설계가 쉬워진다. RTO(Recovery Time Objective, 목표 복구 시간)는 장애 뒤 서비스가 돌아오기까지 허용하는 시간이다. RPO(Recovery Point Objective, 목표 복구 시점)는 잃어도 되는 데이터의 양을 시간으로 말한 것이다. RPO가 0이면 커밋된 트랜잭션을 하나도 잃으면 안 된다.

소스 서버가 죽었을 때 쓰기를 다른 서버로 넘기는 장애 조치는 보통 다섯 단계다.

  1. 소스가 정말 죽었는지 감지한다.
  2. 남은 서버 중 가장 최신 데이터를 가진 서버를 고른다.
  3. 그 서버의 읽기 전용 설정을 풀어 새 소스로 승격한다.
  4. 나머지 레플리카가 새 소스를 따라가도록 다시 연결한다.
  5. 애플리케이션의 쓰기 연결을 새 소스로 옮긴다.

사람이 하면 몇 분에서 몇십 분이 걸리고, 비동기 복제(asynchronous replication)라면 옛 소스에만 있던 트랜잭션은 잃는다. 자동화할 때 가장 위험한 것은 스플릿 브레인(split brain)이다. 옛 소스가 실제로는 살아 있고 네트워크만 끊겼는데 새 소스를 올리면, 두 서버가 동시에 쓰기를 받아 데이터가 두 갈래로 갈라진다. 그룹 복제는 이를 과반수 합의로 막는다. 네트워크가 끊겨 멤버들이 둘로 갈라지면 과반수 멤버를 가진 쪽만 계속 쓰기를 받고, 과반수를 잃은 쪽은 쓰기를 멈춘다. 과반수는 한쪽에만 있을 수 있으므로 두 쪽이 동시에 쓰기를 받는 일이 생기지 않는다.

그룹 복제는 어떻게 합의하나 ​

그룹은 서버 여러 대로 이루어지고, 각 멤버는 데이터 전체의 사본을 가진다. 멤버끼리는 Paxos1 계열의 그룹 통신 엔진으로 메시지를 주고받는다.

  • 읽기 전용 트랜잭션은 그룹과 조율할 필요가 없어 그 멤버에서 바로 끝난다.
  • 쓰기 트랜잭션은 커밋하려는 순간, 바꾼 행의 값과 쓰기 집합(writeset)을 그룹 전체에 보낸다. 쓰기 집합은 바뀐 행을 가리키는 고유 식별자 모음이다. 이 전송은 원자적 브로드캐스트(atomic broadcast)라서 모든 멤버가 받거나 아무도 받지 못하고, 받은 멤버들은 모두 같은 순서로 받는다.
  • 각 멤버는 그 순서대로 충돌 검사(certification, 매뉴얼 용어로는 인증)를 한다. 서로 다른 멤버에서 동시에 실행된 두 트랜잭션이 같은 행을 고쳤는지 쓰기 집합으로 비교해서, 순서가 앞선 쪽은 커밋하고 뒤쪽은 롤백(rollback)한다. 이를 "먼저 커밋한 쪽이 이긴다"(first committer wins)라고 부른다.
다이어그램 로딩…

모든 멤버가 같은 순서의 같은 입력으로 같은 규칙을 적용하므로, 추가로 통신하지 않아도 모두 같은 결론을 낸다. 트랜잭션을 실행한 멤버는 충돌 검사를 통과하면 커밋하고 클라이언트에 응답한다. 다른 멤버가 실제로 적용하는 시점은 조금 늦을 수 있다. 매뉴얼은 그룹 복제를 최종 일관성(eventual consistency) 시스템이라 부른다. 트래픽이 멈추면 모든 멤버가 같은 데이터가 되지만, 트래픽이 흐르는 동안에는 어떤 멤버에 먼저 보일 수 있다는 뜻이다. 읽기를 얼마나 최신으로 맞출지는 일관성 수준으로 정한다.

일반 반동기 복제(semisynchronous replication)와 비교하면 차이가 분명하다. 반동기 복제는 레플리카 한 대가 "받았다"고 답하기를 기다릴 뿐 누가 이길지 정하지 않는다. 그룹 복제는 과반수가 순서에 합의해야 커밋되므로, 성공을 받은 트랜잭션은 과반수 멤버에게 전달되어 있다.

이어지는 내용은 그룹 복제와 InnoDB 클러스터 2에서 다룬다.

면접 포인트 ​

  • "RTO와 RPO는?" → RTO는 서비스가 돌아오기까지 허용하는 시간, RPO는 잃어도 되는 데이터의 양. RPO 0이면 커밋된 트랜잭션을 하나도 잃으면 안 된다.
  • "스플릿 브레인이 뭐고 어떻게 막나요?" → 두 서버가 동시에 소스로 쓰기를 받아 데이터가 갈라지는 것. 과반수 멤버, 곧 정족수(quorum)를 가진 쪽만 쓰게 해서 막는다.
  • "그룹 복제에서 커밋은 어떻게 결정되나요?" → 쓰기 집합을 원자적 브로드캐스트로 같은 순서로 전달 → 각 멤버가 같은 규칙으로 충돌 검사 → 먼저 순서가 정해진 쪽이 이긴다.

참고

  1. 여러 서버가 일부가 죽거나 메시지가 늦어도 하나의 값에 동의하게 만드는 대표적인 분산 합의 알고리즘. 과반수가 동의하면 결정이 확정된다. ↩︎

관련 문서