본문 바로가기

Database

[DOIK 스터디 2기] MySQL Operator on Kubernetes를 이해하기 위한 MySQL, InnoDB Cluster 개념과 MySQL Operator 구조

반응형

DOIK 스터디 2기 - 2번째 글

 

공부하는 내용을 정리하는 글이라 부정확할 수 있음 주의

 

 

Kubernetes에서 MySQL을 운영하기 위해서는 보통 MySQL Operator를 활용하게 된다.

 

이를 제대로 활용하기 위해서는 MySQL과 InnoDB Cluster에 대한 기본적인 개념과 이를 Kubernetes 상에서 관리하기 위한 MySQL Operator for Kubernetes 기본 개념, 그리고 Kubernetes에서의 StatefulSet, Headless Service 등을 이해하고 있어야 한다.

 

이러한 개념들을 이해하고 나면 MySQL Operator, InnoDB Cluster를 Kubernetes 상에서 배포하기 한층 더 쉬워지게 된다.

 

 

1. MySQL 8.0을 운영하기 위해 필요한 기본 상식

 

복제란 한 서버에서 다른 서버로 데이터가 동기화되는 것이다.

 

복제의 목적으로는 스케일 아웃 / 데이터 백업 / 데이터 분석 / 데이터의 지리적 분산이 있다.

 

복제를 할 때는 Binary Log가 필요한데 이는 MySQL 서버에서 발생하는 모든 변경 사항을 별도 로그 파일에 순서대로 기록하게 된다.

 

Event : Binary Log에 기록된 각 변경 정보

Relay Log : Replica 서버에서 Source 서버의 Binary log를 읽어 로그 디스크에 저장해둔 파일

 

 

복제에는 2가지 타입이 있는데 각각 간단히 알아보자.

 

바이너리 로그 파일 위치 기반 복제

  • Source 서버의 로그 파일명과 파일 내에서의 위치(Offset / Position)로 개별 바이너리 로그 이벤트를 식별해서 복제가 진행되는 형태
  • 레플리카 서버는 각 이벤트들을 식별하고 자신의 적용 내역을 추적함으로 복제를 일시적으로 중단할 수 있으며 재개할 때도 적용 이후 이벤트를 다시 읽어올 수 있음

글로벌 트랜잭션 ID 기반 복제(GTID)

  • 복제에 참여한 MySQL 서버들에게 고유하도록 각 이벤트에 부여된 식별 값을 글로벌 트랜잭션 아이디(GTID)으로 복제가 진행되는 형태임
  • GTID는 서버에서 커밋된 각 트랜잭션과 연결된 고유 식별자로 해당 트랜잭션이 발생한 서버에서 고유할뿐만 아니라 그 서버가 속한 복제 토폴로지 내 모든 서버에서 고유하다.
  • GTID는 커밋되어 바이너리 로그에 기록된 트랜잭션에 한해서만 할당되며, 데이터 읽기만 수행하는 SELECT 쿼리 혹은 sql_log_bin 설정이 비활성화 되어 있는 상태에서 발생한 트랜잭션은 바이너리에 로그가 기록되지 않기에 GTID가 할당되지 않는다.
  • GTID는 소스 아이디와 트랜잭션 아이디 값의 조합으로 생성되며 두 값은 콜론 문자(:)로 구분되어 표시된다.
    • GTID = [source_id]:[transaction:id]
  • GTID 값 확인은 gtid_executed 테이블 조회 혹은 gtid_executred 시스템 변수를 통해 확인할 수 있다.
    • select @@global.gtid_executed;
    • select * from mysql.gtid_executed;
    • SHOW GLOBAL VARIABLES ‘gtid_executed’;

 

복제를 동기화하는 방식에도 2가지가 있다.

 

 

비동기 복제 : 소스 서버가 자신과 복제 연결된 레플리카 서버에서 변경 이벤트가 정상적으로 전달되어 적용됐는지 확인하지 않는 방식이다.

  • 소스 서버에 장애가 발생하면 소스 서버에서 최근까지 적용된 트랜잭션이 레플리카 서버로 전송되지 않을 수 있음 (누락된 트랜잭션 존재 가능성 O)

 

반동기 복제 : 좀 더 향상된 데이터 무결성을 제공하는 복제 동기화 방식이다.

  • 소스 서버는 레플리카 서버가 소스 서버로부터 전달받은 변경 이벤트를 릴레이 로그에 기록 후 응답 ACK를 보내면 그 때 트랜잭션을 완전히 커밋시키고 클라이언트에 결과를 반환한다.
  • 전송됐음을 보장하는 것이지, 실제 복제된 트랜잭션이 레플리카 서버에 적용되는 것까지 보장하는게 아니라서 ‘반동기 복제’임
  • 반동기 복제에서는 소스 서버가 트랜잭션 처리 중 어느 지점에서 레플리카 서버의 응답(ACK)를 기다리느냐에 따라 2가지 방식이 있다.
    • AFTER_SYNC
      • 소스 서버에서는 각 트랜잭션을 바이너리 로그에 기록하고 난 후 스토리지 엔진에 커밋하기 전 단계에서 레플리카 서버의 응답을 기다리게 된다.
      • 레플리카 서버로부터 정상 응답이 내려오면 소스 서버는 그 때 스토리지 엔진을 커밋해서 트랜잭션에 대한 처리를 완전히 끝내고 트랜잭션을 실행한 클라이언트에 그 처리 결과를 반환한다.
      • MySQL 8.0 버전의 기본 설정 동작 방식임
    • AFTER_COMMIT
      • 소스 서버에서 트랜잭션을 바이너리 로그에 기록하고 스토리지 엔진에서의 커밋도 진행하고 나서 최종적으로 클라이언트에 결과를 반환하기 전에 레플리카 서버의 응답을 기다린다.
    • AFTER_SYNC 방식에서는 레플리카 서버에 복제되지 않았지만 소스 서버에서는 커밋되어 실제 데이터에 반영된 트랜잭션이 존재하는 경우가 발생하지 않으므로 사용자는 앞서 언급한 롤백 처리를 할 필요가 없다.
    • 따라서 AFTER_SYNC는 AFTER_COMMIT보다 좀 더 데이터 무결성이 강화된 방식임

 

 

이제 MySQL 8.0의 디폴트 스토리지 엔진인 InnoDB 특징에 대해 간단히 알아보자.
우선 아키텍쳐는 아래와 같다.

https://dev.mysql.com/doc/refman/8.0/en/innodb-architecture.html

 

1. 표준 ACID 트랜잭션을 완전히 지원한다.
    - Commit / Rollback / SavePoint
    - Row 레벨 잠금
    - 데이터 일관성을 보장
    - 자동 장애 복구


2. 인메모리 지원
    - InnoDB Buffer Pool : LRU 알고리즘
    - Change Buffer : Secondary Index
    - Redo Log Buffer


3. InnoDB Tablespaces
    - Undo Tablespaces는 변경 전 데이터를 저장하여 롤백 및 읽기에 대해 일관성을 보장하고 독립된 tablespace 파일에 저장한다

(MySQL 8.0에서)


4. InnoDB에는 2가지 트랜잭션 로그 파일이 존재한다.
    - Redo Log는 InnoDB의 변경 작업을 기록하여 크래시 복구를 할 수 있도록 해주는 로그 파일이다.
        - 관련 파라미터는 다음과 같다.
            - innodb_log_files_in_group
            - innodb_log_file_size
            - innodb_log_writer_threads (MySQL 8.0.22)
    - Undo Log는 트랜잭션을 커밋하기 전 데이터를 저장하여 2개의 디폴트 undo tablespace에 저장한다.

 

5. Binary Log file
    - 실행한 쿼리 혹은 데이터가 변경된 처리 내역을 기록하여 복제(Replication)에 사용하려는 목적으로 관리한다.
    - ROW, STATEMENT, MIXED 3가지 기록 포맷이 존재한다.

 

 

아래는위에서 설명한 내용들을 기반으로 InnoDB가 어떻게 일을 하는지 간단히 정리된 그림이다.
메모리 Layer, Thread Layer, Disk Layer로 구분하여 이해하면 좋다.

 

https://blog.ex-em.com/1700

 

 

2. InnoDB Cluster에 대해서

InnoDB Cluster가 왜 등장하게 되었고 이를 구성하는 구성 요소들이 무엇인지 간단히 살펴보자

 

MySQL의 Master - Slave 복제 구성은 자체 HA 혹은 Failover 기능을 제공하지 않기에 Master(Source)에 장애가 생기면 DBA 혹은 관리자가 복구 혹은 Failover를 별도로 수행해야 한다.

그리고 Read Replica 노드에 대한 부하 분산을 처리할 때 별도 솔루션 혹은 프록시를 앞단에 두어 기술적으로 구현이 필요하다.

이러한 이유로 InnoDB Cluster가 나오게 되었다.


InnoDB Cluster 구성 요소 및 각 구성 요소의 특징들은 다음과 같다.

 

- Group Replication
    - 소스 서버의 데이터를 레플리카 서버로 동기화해주는 역할을 한다.


    - 그룹 멤버 관리, 그룹 단위의 정렬된 트랜잭션 적용 및 트랜잭션 충돌 감지, 자동 페일오버 등을 수행한다.


    - 한 서버에서 트랜잭션이 커밋할 준비가 되면 트랜잭션 정보를 그룹의 다른 멤버들에게 전송하고 과반수 이상의 멤버로부터 응답을 전달받으면 그 때 해당 트랜잭션을 인증하고 최종 커밋을 완료하게 된다.

        - 트랜잭션 인증은 대상 트랜잭션이 이미 인증 단계를 통과한 선행 트랜잭션과 동 시점에 동일한 데이터를 변경했는지 충돌 여부를 검사하여 문제없이 적용 가능한지를 확인하는 과정이다.


    - 그룹 복제는 별도 플러그인으로 구성되어 있다.

 


- MySQL Router
    - 애플리케이션 서버와 MySQL 서버 사이에서 동작하는 미들웨어 프로그램이다.


    - InnoDB 클러스터의 MySQL 구성 변경을 자동으로 감지하고 쿼리의 부하를 분산하며 자동으로 페일오버를 수행한다.


    - 클라이언트는 MySQL 라우터에 연결하여 쿼리를 실행하기 때문에 InnoDB 클러스터가 어떤 서버로 구성되어 있는지 알 필요가 없으며 커넥션 정보에는 MySQL Router 서버만 설정해두면 된다.


    - MySQL 라우터는 InnoDB 클러스터로 구성된 MySQL 서버들에 대한 메타정보를 가지고 있고 이를 통해 페일오버 등을 수행하게 된다.

 


- MySQL Shell
    - 기존 MySQL Client 보다 좀 더 확장된 기능을 가졌으며 Admin API를 제공한다.

    - JavaScript, Python 등 프로그래밍 언어로도 사용이 가능하다.

 


그럼 장애가 발생할 경우 어떻게 동작될까?

- 그룹 복제가 이를 먼저 감지하여 해당 서버를 복제 그룹에서 곧바로 제외한다.


- MySQL Router는 그룹 복제에 의해 제외된 서버가 복제 토폴로지에서 변경됨을 인지하게 되고 곧바로 메타데이터를 갱신하여 클라이언트로부터 실행된 쿼리가 현재 복제 그룹에서 정상적으로 동작하는 MySQL 서버로만 전달될 수 있도록 변경한다.

 

 

 

3. MySQL Operator for Kubernetes에 대해서

지금까지 MySQL에 대해서와 InnoDB Cluster의 개념들을 이해하였다.

 

사실 1) MySQL 기본 개념 2) InnoDB Cluster에 대한 개념 3) 쿠버네티스 기본 개념 4) Operator Pattern 개념

이정도만 잘 이해하고 있다면 MySQL Operator for Kubernetes는 금방 이해할 수 있다고 생각한다.

 

MySQL Operator는 위에서 설명한 InnoDB Cluster를 Kubernetes 상에서 손쉽게 관리하기 위해 만들어진 Operator이며 MySQL 8.0.29 버전부터 정식 GA 되었다.

 

 

사진에서 볼 수 있듯이 MySQL Operator가 Deployment로 떠 있는 것을 확인할 수 있다.

MySQL Operator가 배포되어야 InnoDB Cluster를 배포할 수 있게 된다.

MySQL InnoDB Cluster Helm으로 배포되는 컴포넌트들을 간단히 알아보자.

- StatefulSet : MySQL 서버 인스턴스(MySQL Servers)들이 스테이트풀셋으로 배포된다.
- Deployment : MySQL 라우터가 디플로이먼트로 배포된다. Proxy 역할을 수행하며 애플리케이션에서 요청한 쿼리를 알맞는 서버로 전달하게 된다.
- MySQL Shell : MySQL Router, MySQL Server에 이 Shell 프로그램이 포함되며 기존 MySQL Client보다 좀 더 확장된 기능을 제공한다.
- 그 외 컨피그맵을 통해 MySQL Config 파일을, 시크릿을 통해 시스템 암호 등이 배포된다.

 

고로 Kubernetes 상에서 MySQL Operator for Kubernetes를 사용하기 위해서 MySQL Operator를 Helm으로 먼저 구성한 뒤 MySQL InnoDB Cluster를 Helm으로 설치해야 한다는 것을 의미한다.

 

 

 

 

-------

 

데이터베이스에 대해서 잘 모르다보니 개념만 정리하는데 꼬박 하루가 걸렸다.

 

실습도 해봐야하는데 도저히 시간이 안나서 우선 개념 정리만...

반응형