본문 바로가기

DevOps/DOIK (Database Operator in Kubernetes)

MySQL Architecture & Replication

MySQL

복제 관련 용어 변경 History

  • Master = Source = Primary
  • Slave = Replica = Secondary
  • Multithreaded Slave = Multithreaded Applier

Database 기본 개념

Key : 검색 또는 정렬 시 Tuple을 구분할 수 있는 기준이 되는 Attribute

  1. Candidate Key (후보키) : Tuple을 유일하게 식별하기 위해 사용되는 속성들의 부분 집합 (Primary key로 사용할 수 있는 속성들)
    (1) 유일성: key로 하나의 tuple을 유일하게 식별할 수 있음
    (2) 최소성: 꼭 필요한 속성으로만 구성
  2. Primary Key (기본키) : Candidate key 중 선택한 main key
    - Null 값을 가질 수 없음
    - 동일한 값이 중복될 수 없음
  3. Alternate Key (대체키) : Candidate key 중 Primary Key를 제외한 나머지 키
  4. Super Key (슈퍼키): 유일성은 만족하지만, 최소성은 만족하지 못하는 키
  5. Foreign Key (외래키): 다른 relation의 primary key를 그래로 참조하는 속성의 집합

Join : 두 개 이상의 테이블이나 데이터베이스를 연결하여 데이터를 검색하는 방법

 

Transaction : 데이터베이스의 상태를 변화시키기 위해 수행하는 작업 단위

  • Commit 또는 Rollback이 수행된 후 Transaction 종료
    - Commit : 하나의 Transaction이 성공적으로 끝나고, DB가 일관성 있는 상태를 유지
    - Rollback : 하나의 Transaction이 비정상적으로 종료되어 이전 상태로 복구
  • Transaction 특징
    1. 원자성 (Atomicity) : transaction이 DB에 모두 반영되거나, 혹은 전혀 반영되지 않음
    2. 일관성(Consistency) : transaction의 작업 처리 결과는 항상 일관성 유지
    3. 독립성(Isolation) : 둘 이상의 transaciton이 동시에 실행될 때, 어떤 transaction도 다른 transaction의 연산에 독립적
    4. 지속성(Durability) : transaction이 성공적으로 완료되면, 그 결과는 영구 반영

MySQL Architecture

  • MySQL 엔진: 클라이언트 접속과 SQL 요청 처리. 엔진에서 Optimizer는 SQL을 실행시키기 위한 실행계획을 짠다.
  • MySQL 스토리지 엔진: 데이터를 실제로 디스크에 저장하거나 저장된 데이터를 가져온다.
  • Handler API: MySQL 엔진이 스토리지를 호출할 때 사용하는 API

MySQL Replication

Replication 동작 과정

Master의 변경 사항이 Slave의 Relay log에 작성됨을 보장 (5.5 이후 Semi-replication, 5.7.2 이후 Loss-less replication)

  • Binary Log : Master에 실행되는 모든 DML/DDL를 기록
  • Relay Log : Binary Log에 내용을 Slave에 기록

  1. Client에서 쿼리를 실행 (데이터가 변경이 되는 INSERT, UPDATE, DELETE인 경우)
  2. binary log와 file log에 기록이 되고 MySQL에 실행된다.
  3. [Requests a packet] Slave에서 binary log를 감시하다가 새로운 쿼리가 작성되면 해당 쿼리를 요청한다.
  4. [Sends the packet Wait ACK] binary log에 기록된 쿼리를 slave에 전달하고, 전달됨을 보장받기 위해 응답을 기다린다.
    (Slave가 여러 개인 경우, master는 모든 slave의 relay log 파일에 전달한다)
  5. [ACK] Slave는 받은 쿼리를 Relay log에 작성하고, master로 응답을 리턴
  6. [OK] Master는 Client에 OK 리턴
    (Slave가 여러 개인 경우, master는 하나의 Slave에서라도 응답을 리턴하면 Client에 응답 리턴 - 모두 기다리지 않음)
    -> Multi-Slave 환경에서는 하나의 Slave의 Relay log에만 작성됨을 보장함 : Replication Fail이 발생될 수 있다

MySQL Replication은 3개의 스레드에 의해 작동하는데, 이 3가지 중 하나는 Source(Master)에 존재하며 나머지 두 개는 Replica(Slave) 서버에 존재한다.

  1. Binary Log Dump Thread
    - 데이터 동기화를 위해 binary log의 내용을 Replica 서버로 전송
    - Replica 서버로 보낼 각 이벤트를 읽을 때 일시적으로 binary log에 잠금을 수행하며, 이벤트를 읽고 난 후 바로 잠금을 해제한다.
    - Source 서버에서 SHOW PROCESSLIST 명령을 통해 확인 가능
  2. Replication I/O Thread
    - Binary Log Dump Thread로부터 로그 이벤트를 가져와 로컬 서버의 파일로 저장하는 역할 수행
  3. Replication SQL Thread
    - Replication I/O Thread에 의해 작성된 Relay log의 이벤트를 읽고 실행하는 역할 수행

Replica 서버에서 I/O 스레드와 SQL 스레드는 서로 독립적으로 동작한다.(Replica 서버에 문제가 발생하더라도 Source 서버에 영향 X)

MySQL Replication 동기화 방식

  1. 비동기 복제(Asynchronous Replication) :
    Source(Master) 서버가 Replica(Slave) 서버에서 변경 이벤트가 정삭적으로 전달됐는지 확인하지 않는 방식
  2. 반동기 복제(Semi-sync Replication) :
    Source(Master)는 Replica(Slave) 서버가 전달받은 변경 이벤트를 Relay log에 기록 후 응답을 보내면 그때 트랜잭션을 완전히 커밋
    - 적어도 하나의 Replica Server에 트랜잭션이 전송됐음을 보장 BUT 실제 적용은 보장 X
    - 서버의 응답을 기다리기 때문에 비동기 방식보다 트랜잭션 처리가 느려질 수 있음
       (응답이 안 오면 무기한적으로 기다려 timeout 발생 가능)

(좌) 비동기 복제 방식, (우) 반동기 복제 방식

Replication Topology

[1] Single Replica

하나의 Source 서버에 하나의 Replica 서버만 연결되어 있는 복제 형태

 

[2] Multi Replica

하나의 Source 서버에 2개 이상의 Replica 서버를 연결한 복제 형태

 

[3] Chain Replica

Multi Replica 구성에서 Replica 서버가 너무 많아 Source 서버의 성능에 악영향이 예상될 경우 1:M:M 구조의 복제 구성 형태

 

[4] Dual Source Replica

두 개의 MySQL 서버가 서로 Source이자 Replica 서버로 구성되어 있는 형태

 

[5] Multi Source Replica

하나의 Replica 서버가 둘 이상의 Source 서버를 갖는 형태

(시계방향으로) 1.Single Replica 2. Multi Replica 3. Chain Replica 4.Dual Source Replica 5. Multi Source Replica

[궁금증!] Multi Source/Master를 구성해서 DB의 write 성능을 높일 수 있지 않을까...?

많은 사용자들이 듀얼 소스 구성을 포함해서 멀티 소스 복제 구성이 쓰기 (INSERT UPDATE DELTE) 처리량 향상에 도움이 될 것으로 생각하지만 모든 소스 서버들은 다른 소스 서버의 변경 내용들을 복제를 통해 자신에게도 똑같이 실행해야 하기 때문에 쓰기 확장 효과는 크지 않다. 오히려 여러 소스 서버에서 동시에 변경이 발생하면서 앞에서 살펴본 트랜잭션 충돌로 인해 롤백이복제 멈춤 현상 등 역효과가 많은 편이다. 그래서 실제로 멀티 소스 복제 구성은 많이 사용되지는 않는 편이다. 만약 쓰기 성능의 확장이 필요하다면 멀티 소스 복제 구성보다는 데이터베이스 서버를 샤딩 Sharding 하는 방법을 권장한다.

MySQL Group Replication

MySQL의 일반적인 복제와 그룹 복제 동작 방식 비교

Group Replication은 기존 MySQL 복제 프레임워크를 기반으로 구현되어 내부적으로 Row 포맷의 Binary Log와 Relay Log 그리고 GTID(Global Transaction IDentifier)를 사용한다.

기존 복제의 경우 일반적으로 Source-Replica 형태로 구성되어 단방향 복제가 이루어지는 반면, Group Replication에서는 MySQL 서버들이 하나의 복제 그룹(Replication Group)으로 묶인 클러스터 형태를 가지며 그룹 내 서버들은 서로 통신하면서 양방향으로도 복제를 처리할 수 있다.

 

Group Replication은 반동기 방식(Semi-sync Replication)이라고 할 수 있는데, 그렇다고 해서 기존 반동기 방식과 동일한 방식으로 처리되는 것은 아니다.

 

기존 복제(비동기 복제: Asynchronous Replication)에서는 기본적으로 Source 서버에서 Commit처리가 Replica서버와는 무관하게 처리되는 방식으로, Repplica 서버에 transaction이 잘 전달 및 적용됐는지를 확인하지 않는다.

MySQL Asynchronous Replication

반동기 방식(Semi-Sync Replication)은 transaction을 처리할 때 Source 서버와 Replica 서버 사이에 확인 단계가 추가된 것으로, Replica 서버에 transaction이 잘 전달됐는지 응답을 기다린 후 최종적으로 Commit처리를 하게 된다. (적용 유무 X)

MySQL Semisynchronous Replication

그룹 복제 방식(Group Replication)에서도 마찬가지로 transaction에 대해 그룹 내 다른 멤버들의 응답을 확인하는 단계가 존재한다.

그룹 복제에서는 한 서버에서 transaction이 commit 할 준비가 되면 transaction 정보를 그룹의 다른 멤버들에게 전송하고 과반수 이상의 멤버로부터 응답을 전달/확인(Consensus) 받으면 그때 해당 transaction을 인증(Certify)하고 최종적으로 Commit 처리를 완료한다. (Transaction Certify은 인증 대상 트랜잭션이 이미 인증 단계를 통과한 선행 트랜잭션과 동시점에 동일한 데이터를 변경했는지 충돌 여부를 검사하여 적용 가능한지를 확인하는 과정이다.)

MySQL Group Replication

  • Group Replication에서 트랜잭션 커밋을 처리할 때 만약 관반수 이상의 멤버로부터 응답을 받지 못한 경우, 해단 트랜잭션은 그룹에 적용되지 않는다. (트랜잭션을 실제로 적용했는지까지 확인하는 것은 아님)
  • 기존 복제 방식(비동기 복제: Asynchronous Replication)과 반동기 복제 방식(Semi-Sync Replication) 모두 복제 구성 내에서 트랜잭션은 Source 서버에서 일방적으로 적용된다고 할 수 있다.
    하지만 Group Replication에서는 그룹 내 멤버들의 응답에 따라 전체 복제 그룹에서 해당 트랜잭션의 적용 여부가 결정된다.
    (데이터를 변경하는 트랜잭션에 대해서만 합의 과정 필요, 데이터 읽기는 합의 과정 필요 X)

Group Replication Architecture

Group Replication은 별도 플러그인으로 구현되어 있으며, MySQL 서버에 플러그인이 설치되어 있어야 한다.

  • 그룹 복제에 참여하는 MySQL 서버들은 그룹 복제 플러그인을 통해 서로 간에 지속적으로 통신하며 복제 동기화를 처리한다.
  • 그룹 복제 플러그인은 MySQL 서버에 그룹 복제가 설정되면 group_replication_applier 복제 채널을 생성하며, MySQL 서버는 이 채널을 통해 그룹에 실행된 모든 트랜잭션을 전달받아 적용하게 된다.
  • MySQL 서버가 그룹에 새로 가입해서 이미 그룹에 참여하고 있는 다른 MySQL 서버들과 같이 그룹의 최신 데이터를 가지도록 하는 그룹 복제 분산 복구 작업이 필요한 경우 그룹 복제 플러그인은 추가로 라는 group_replication_recovery 복제 채널을 생성해서 분산 복구 작업을 진행한다.

MySQL High Availability

MySQL 이중화 진화기 : InnoDB ReplicaSet -> InnoDB Cluster -> InnoDB ClusterSet

MySQL InnoDB ReplicaSet

기존 복제 방식(비동기 복제: Asynchronous Replication 또는 반동기 방식:Semi-Sync Replication)을 기반으로 함.

InnoDB ReplicaSet: 비동기 복제 + MySQL Shell + MySQL Router

  • 자동 Failover를 지원하지 않음. (Failover 순간 data loass 가능) -> Manual Failover
  • Write 성능이 가장 좋음
  • RPO != 0, RTO = minute + (manual failover)

MySQL InnoDB Cluster

그룹 복제 방식(Group Replication)을 기반으로 함.

그룹 복제 형태의 합의 동작 방식에 따른 최소 3대의 서버가 필요

  • 자동 Failover 지원
  • RPO = 0(Primary 장애 시 data loss가 없다), RTO = seconds

MySQL InnoDB ClusterSet

  • 여러 MySQL InnoDB Cluster를 비동기 복제로 연결
  • 여러 데이터 센터 사이의 DR 솔루션으로 활용 가능
  • Primary InnoDB Cluster의 데이터센터 장애 시 수동 failover

  • MySQL Router 타겟모드를 설정 가능
    • Primary 클러스터 설정: RW, RO 포트는 Primary Cluster로 전송
    • Replica 클러스터 설정: RO 포트만 오픈

'DevOps > DOIK (Database Operator in Kubernetes)' 카테고리의 다른 글

MongoDB Architecture & Replication  (1) 2023.11.12
PostgreSQL Operator for Kubernetes  (0) 2023.10.31
MySQL Operator for Kubernetes  (0) 2023.10.26
Kubernetes Basic  (0) 2023.10.21