Vitess는 오픈소스 데이터베이스 인스턴스의 대규모 클러스터를 배포, 확장 및 관리하기 위한 데이터베이스 솔루션입니다. 현재 MySQL과 Percona Server for MySQL을 지원합니다. 전용 하드웨어에서와 마찬가지로 퍼블릭 또는 프라이빗 클라우드 아키텍처에서 효과적으로 실행되도록 설계되었습니다.
NoSQL 데이터베이스의 확장성과 함께 많은 핵심적인 몇 가지의 SQL 기능을 결합하고 확장하여 구현되었습니다.
Table Of Contents
Vitess는 다음과 같은 문제를 해결하는 데 도움을 줄 수 있습니다.
- 애플리케이션 변경을 최소화하는 동시에 SQL 데이터베이스를 샤딩하여 확장할 수 있습니다.
- 베어 메탈 또는 VM에서 프라이빗 또는 퍼블릭 클라우드로 마이그레이션합니다.
- 대량의 SQL 데이터베이스 인스턴스를 배포하고 관리합니다.
Vitess는 네이티브 쿼리 프로토콜을 사용하는 호환 JDBC 및 Go 데이터베이스 드라이버를 포함합니다. 또한, 사실상 다른 모든 언어와 호환되는 MySQL 서버 프로토콜을 구현합니다.
Vitess는 5년 이상 모든 YouTube 데이터베이스 트래픽을 처리했으며, 많은 기업이 Vitess를 채택했습니다
Vitess 대 NoSQL
MySQL의 확장성에 대한 우려 때문에 주로 NoSQL 솔루션을 고려하고 있다면 Vitess가 애플리케이션에 더 적합한 선택일 수 있습니다. NoSQL은 비정형 데이터에 대한 훌륭한 지원을 제공하지만 Vitess는 여전히 NoSQL 데이터 저장소에서 사용할 수 없는 여러 가지 이점을 제공합니다.
NoSQL | Vitess |
NoSQL 데이터베이스는 데이터베이스 테이블 간의 관계를 정의하지 않으며, SQL 언어의 하위 집합만 지원합니다. | Vitess는 단순한 키-값 저장소가 아닙니다. where 절, JOINS, 집계 함수 등과 같은 복잡한 쿼리 의미론을 지원합니다. |
NoSQL 데이터 저장소는 일반적으로 트랜잭션을 지원하지 않습니다. | Vitess는 트랜잭션을 지원합니다. |
NoSQL 솔루션은 사용자 정의 API를 갖추고 있어 사용자 정의 아키텍처, 애플리케이션, 도구가 가능합니다. | Vitess는 대부분 사람들이 이미 익숙하게 사용하고 있는 데이터베이스인 MySQL에 거의 변화를 주지 않습니다. |
NoSQL 솔루션은 MySQL에 비해 데이터베이스 인덱스에 대한 지원이 제한적입니다. | Vitess를 사용하면 MySQL의 모든 인덱싱 기능을 사용하여 쿼리 성능을 최적화할 수 있습니다. |
Vitess Architecture
Vitess 플랫폼은 일관된 메타데이터 저장소로 지원되는 여러 서버 프로세스와 커맨드라인(명령줄) 유틸리티, 웹 기반 유틸리티로 구성됩니다.
애플리케이션의 현재 상태에 따라 여러 가지 다른 프로세스 흐름을 통해 전체 Vitess 구현에 도달할 수 있습니다. 예를 들어, 처음부터 서비스를 빌드하는 경우 Vitess를 사용하는 첫 번째 단계는 데이터베이스 토폴로지를 정의하는 것입니다. 그러나 기존 데이터베이스를 확장해야 하는 경우 Unmanaged 모드에서 Vitess를 배포하는 것으로 시작할 가능성이 높습니다.
Vitess 도구와 서버는 전체 데이터베이스로 시작하든 소규모로 시작해서 시간이 지남에 따라 확장하든 도움을 주도록 설계되었습니다. 더 작은 구현의 경우 연결 풀링 및 쿼리 재작성과 같은 vttablet 기능을 사용하면 기존 하드웨어에서 더 많은 것을 얻을 수 있습니다. 그런 다음 Vitess의 자동화 도구는 더 큰 구현에 대한 추가 이점을 제공합니다.
아래 다이어그램은 Vitess의 구성 요소를 보여줍니다.
Cell
셀 은 한 지역에 함께 배치되고 다른 셀의 장애로부터 격리된 서버와 네트워크 인프라의 그룹입니다. 일반적으로 전체 데이터 센터이거나 데이터 센터의 하위 집합이며, 때로는 존 또는 가용성 존 이라고도 합니다 . Vitess는 셀이 네트워크에서 차단되는 경우와 같이 셀 수준의 장애를 우아하게 처리합니다.
Vitess 구현의 각 셀에는 해당 셀에 호스팅된 로컬 토폴로지 서비스가 있습니다 . 토폴로지 서비스에는 셀의 Vitess 태블릿에 대한 대부분의 정보가 포함되어 있습니다. 이를 통해 셀을 해체하고 하나의 단위로 다시 구축할 수 있습니다.
Vitess는 데이터와 메타데이터 모두에 대한 크로스 셀 트래픽을 제한합니다. 읽기 트래픽을 개별 셀로 라우팅하는 기능도 있으면 유용할 수 있지만, Vitess는 현재 로컬 셀에서만 읽기를 제공합니다. 쓰기는 필요한 경우 해당 샤드의 기본이 있는 곳으로 크로스 셀로 이동합니다.
토폴로지 서비스
토폴로지 서비스 는 다양한 서버에서 실행되는 백엔드 프로세스 집합입니다. 이러한 서버는 토폴로지 데이터를 저장하고 분산 잠금 서비스를 제공합니다.
Vitess는 토폴로지 데이터를 저장하기 위한 다양한 백엔드를 지원하기 위해 플러그인 시스템을 사용하는데, 이는 분산되고 일관된 키-값 저장소를 제공한다고 가정합니다. 기본 토폴로지 서비스 플러그인은 etcd2 입니다.
토폴로지 서비스는 다음과 같은 이유로 존재합니다.
- 이를 통해 태블릿이 클러스터로 서로 조정될 수 있습니다.
- 이를 통해 Vitess는 태블릿을 검색하여 쿼리를 어디로 라우팅해야 할지 알 수 있습니다.
- 여기에는 클러스터 내의 여러 다른 서버에 필요한 데이터베이스 관리자가 제공한 Vitess 구성이 저장되며, 이 구성은 서버를 다시 시작해도 지속되어야 합니다.
Vitess 클러스터에는 하나의 글로벌 토폴로지 서비스와 각 셀에 하나의 로컬 토폴로지 서비스가 있습니다.
Keyspace & Keyspace ID
Keyspace
키 스페이스는 논리적 데이터베이스입니다. 샤딩(Sharding)을 사용하면 하나의 키스페이스는 여러 MySQL 데이터베이스에 매핑되고, 샤딩을 사용하지 않는 경우 키스페이스는 MySQL 데이터베이스 이름에 직접 매핑됩니다. 어느 경우든 키스페이스는 애플리케이션의 관점에서 단일 데이터베이스로 나타납니다.
키스페이스에서 데이터를 읽는 것은 MySQL 데이터베이스에서 데이터를 읽는 것과 같습니다. 그러나 읽기 작업의 일관성 요구 사항에 따라 Vitess는 기본 데이터베이스 또는 복제본에서 데이터를 가져올 수 있습니다. 각 쿼리를 적절한 데이터베이스로 라우팅함으로써 Vitess는 단일 MySQL 데이터베이스에서 읽는 것처럼 코드를 구조화할 수 있습니다.
Keyspace ID
키 스페이스 ID는 주어진 행이 어느 샤드에 있는지 결정하는 데 사용되는 값입니다. Range-based Sharding (범위 기반 샤딩)은 각각 특정 범위의 키스페이스 ID를 포함하는 샤드를 만드는 것을 말합니다.
이 기술을 사용하면 다른 샤드에 있는 레코드를 이동하지 않고도 키스페이스 ID의 원래 범위를 포괄하도록 결합된 두 개 이상의 새 샤드로 대체하여 주어진 샤드를 분할할 수 있습니다.
키스페이스 ID 자체는 사용자 ID와 같은 데이터의 일부 열의 함수를 사용하여 계산됩니다. Vitess를 사용하면 다양한 함수( vindexes ) 중에서 선택하여 이 매핑을 수행할 수 있습니다. 이를 통해 샤드 간에 데이터를 최적으로 분산하는 데 적합한 함수를 선택할 수 있습니다.
Vindexes
Vindex는 컬럼(column, 열) 값을 키스페이스 ID에 매핑합니다
Vindex는 열 값을 keyspace ID에 매핑하는 방법을 제공합니다 . 즉, mysql의 테이블의 특정 컬럼을 기준으로 데이터를 샤드에 나누는 것을 말합니다.
Vitess의 각 샤드는 값 범위를 포함하므로 keyspace ID이 매핑을 사용하여 행이 포함된 샤드를 식별할 수 있습니다.
다양한 vindex를 선택할 수 있으며, 서로 다른 트레이드오프가 있으며, 질의에 따라 가장 적합한 것을 선택할 수 있습니다.
샤딩 키는 NoSQL 데이터 저장소에서 도입된 개념입니다. NoSQL 데이터베이스에서 데이터에 대한 액세스 경로가 키인 단 하나뿐이라는 사실에 기반합니다. 그러나 관계형 데이터베이스는 저장된 데이터와 그 관계에 대해 더 다재다능합니다. 따라서 단일 샤딩 키만 지정하여 데이터베이스를 샤딩하는 것은 종종 충분하지 않습니다.
비유를 하자면, 데이터베이스의 인덱스는 NoSQL 데이터스토어의 키와 동일하지만, 데이터베이스는 테이블당 여러 인덱스를 허용하고 인덱스 유형이 다양합니다. 이 비유를 샤드 데이터베이스로 확장하면 다양한 유형의 크로스 샤드 인덱스가 생성됩니다. Vitess에서는 이를 Vindex라고 합니다.
장점
Vindexes의 장점은 유연성에서 비롯됩니다.
- 테이블에는 여러 개의 Vindex가 있을 수 있습니다.
- Vindexes는 NonUnique일 수 있으므로 열 값이 여러 개의 키스페이스 ID를 생성할 수 있습니다.
- Vindexes는 간단한 함수가 될 수도 있고 조회 테이블을 기반으로 할 수도 있습니다.
- Vindex는 여러 테이블에서 공유될 수 있습니다.
- 사용자 정의 Vindex를 만들어 사용할 수 있으며, Vitess는 이러한 Vindex를 사용하여 리샤딩하는 방법을 계속 알고 있을 것입니다.
Execution Plans
Vitess는 VTGate와 VTTablet 계층에서 쿼리를 구문 분석하여 쿼리를 실행하는 가장 좋은 방법을 평가합니다. 이 평가는 쿼리 계획이라고 하며 쿼리 실행 계획 으로 이어집니다 .
실행 계획은 쿼리와 관련 VSchema 에 모두 종속됩니다 . Vitess의 Plan 전략의 기본 목표 중 하나는 가능한 한 많은 작업을 기본 MySQL 인스턴스로 푸시하는 것입니다. 이것이 불가능한 경우 Vitess는 여러 소스에서 입력을 수집하고 결과를 병합하여 올바른 쿼리 결과를 생성하는 계획을 사용합니다.
VSchema
VSchema를 사용하면 키스페이스와 샤드 내에서 데이터가 어떻게 구성되는지 설명할 수 있습니다. 이 정보는 쿼리 라우팅과 리샤딩 작업 중에 사용됩니다.
키스페이스의 경우, 샤딩되었는지 여부를 지정할 수 있습니다. 샤딩된 키스페이스의 경우, 각 테이블에 대한 vindex 목록을 지정할 수 있습니다.
평가 모델
실행 계획은 각각 특정 작업을 구현하는 연산자로 구성됩니다. 연산자는 트리와 같은 구조로 결합되어 전체 실행 계획을 나타냅니다. 계획은 각 연산자를 트리의 노드로 나타냅니다. 각 연산자는 0개 이상의 행을 입력으로 받고 0개 이상의 행을 출력으로 생성합니다. 즉, 한 연산자의 출력이 다음 연산자의 입력이 됩니다. 트리의 두 분기를 연결하는 연산자는 두 개의 들어오는 스트림의 입력을 결합하여 단일 출력을 생성합니다.
실행 계획의 평가는 트리의 리프 노드에서 시작됩니다. 리프 노드는 토폴로지 서비스인 VTTablet에서 데이터를 가져오고, 어떤 경우에는 로컬에서 표현식 값을 평가할 수도 있습니다. 각 리프 노드는 다른 연산자의 입력을 받지 않으며, 생성된 노드를 부모 노드로 파이프로 연결합니다. 그런 다음 부모 노드는 노드를 부모 노드로 파이프로 연결하여 루트 노드까지 연결합니다. 루트 노드는 쿼리의 최종 결과를 생성하여 사용자에게 결과를 전달합니다.
라우팅 운영자
실행 계획의 라우팅 연산자는 Vitess에 작업을 보낼 목적지를 지시합니다. 일반적으로 라우팅 연산자는 작업을 실행할 때 사용할 키스페이스, 키스페이스가 샤딩되었는지 여부, 샤딩된 키스페이스의 경우 사용할 vindex를 Vitess에 알려줍니다.
분산 쿼리
샤딩된 키스페이스를 지정하지만 vindex를 지정하지 않는 라우팅 연산자는 샤딩된 키스페이스의 모든 샤드로 "분산"합니다. "분산" 쿼리에는 샤딩된 키스페이스로 라우팅된 하나 이상의 작업이 포함되지만 vindex를 사용하여 라우팅할 수 없습니다.
샤드 키스페이스의 여러 샤드(또는 전체 샤드)에 전송된 모든 쿼리가 분산 쿼리로 간주되는 것은 아닙니다.
실행 계획 관찰
캐시된 실행 계획은 /queryz 엔드포인트를 탐색(etcd2 등)하여 VTGate 수준에서 볼 수 있습니다
Vitess 16부터 개별 구문에 대한 플랜도 VExplain 에서 확인할 수 있습니다 .
Replication
Vitess는 고가용성과 데이터베이스 테이블 변경 피드를 수신하기 위해 MySQL 복제를 사용합니다. 이 피드는 VReplication 과 같은 기능에서 사용되며 , 스키마 변경을 식별하여 캐시를 업데이트할 수 있습니다.
Semi-Sync
Vitess는 고가용성을 위해 Semi-synchronous replication (반동기식 복제)를 사용할 것을 강력히 권장합니다. 반동기식의 특징은 키스페이스에 대해 구성된 내구성 정책 에 의해 관리되는 복제입니다 . 일부 특징은 모든 정책에서 공유됩니다.
반동기식 복제는 1개의 노드가 ack를 반환하는 특징을 갖습니다. 반동기화를 활성화하면 기본 장애가 발생할 경우 클라이언트에 완료된 것으로 보고된 모든 트랜잭션이 있는 다른 복제본이 최소한 하나 있다는 속성을 제공합니다.
그런 다음 VTOrc가(장애 관리자) Failover 복구할 때까지 기다리거나 ( GTID 위치에서 가장 앞서 있는 복제본을 수동으로 선택하여 새 기본으로 승격시킬 수 있습니다.
- Vitess는 반동기화 시간 초과를 기본적으로 무제한으로 구성하여 비동기 복제로 동작하지 않습니다. 이는 네트워크 파티션의 경우 스플릿 브레인을 방지하는 데 중요합니다. 모든 복제본이 복제를 중단했는지 확인할 수 있다면 이전 기본 복제본이 쓰기를 허용하지 않는다는 것을 알 수 있으며, 이전 기본 복제본 자체에 연결할 수 없더라도 마찬가지입니다.
- 이 부분은 장애에 취약한 구조지만, 데이터 정합성을 맞추는데 중요한 요소로 판단할 수 있음 ( 과연 무엇이 중요한가? )
- 모든 사전 구성된 내구성 정책은 rdonly 유형의 태블릿이 반동기 ACK를 보내는 것을 허용하지 않습니다. 이는 rdonly 태블릿이 기본으로 승격될 수 없기 때문에 의도적인 것이며, 따라서 Vitess는 기본 실패 시 rdonly 태블릿이 선거에 가장 적합한 단일 후보인 경우를 피합니다.
따라서 클라이언트에 완료된 것으로 보고된 트랜잭션을 잃지 않고 갑작스러운 Primary 장애를 견뎌낼 수 있습니다.
복제(이중화) 지연과 관련하여, 쿼리가 항상 최신 결과를 반환하는 최소한 하나의 복제본이 항상 있다는 것을 보장 하지 않는다는 점에 유의해야합니다
즉, 반동기화는 최소한 하나의 복제본이 릴레이 로그에 트랜잭션을 가지고 있지만 아직 적용되지 않은 상태입니다. 그러므로, Vitess가 완전히 최신 읽기를 보장하는 유일한 방법은 요청을 Primary로 보내는 것입니다.
데이터베이스 스키마 고려 사항
- 행 기반 복제는 복제본이 기본 복제본과 동일한 스키마를 가져야 하며, 테이블의 컬럼(열) 순서가 일치하지 않으면 손상이 발생할 가능성이 높습니다.
- 명령문(SQL) 기반 복제를 사용한 이전 버전의 Vitess는 먼저 복제본에 스키마 변경을 적용한 다음 역할을 기본 복제본으로 바꾸는 것을 권장했습니다. 이 방법은 더 이상 권장되지 않으며 Online-DDL을 사용합니다. 자세한 내용은 여기에서 확인할 수 있습니다 .
- 참고로, MySQL용 온라인 DDL 툴(go-ost)은 다음에서 확인하실 수 있습니다.
- 유형 FLOAT또는 DOUBLE기본 키의 일부로 열을 사용하는 것은 지원되지 않습니다. 이 제한은 Vitess가 값(예: 2.2)에 대한 쿼리를 실행하려고 할 수 있기 때문에 MySQL은 근사값이 존재하더라도 0개의 결과를 반환합니다.
- 리샤딩 작업이 수행되는 동안 스키마를 변경하는 것은 권장되지 않습니다. 이러한 제한은 RBR 이벤트를 해석하려면 테이블 스키마에 대한 정확한 지식이 필요하고 Vitess가 스키마가 변경된 경우를 항상 올바르게 처리하지 못하기 때문입니다.
이 외에도 다양한 기능들이 있는데, 재미있는 것은 MySQL을 건드리지 않고 모두 외부 시스템으로 구현했다는 것입니다. 이 구조에 대해서도 한번 고민해 보면 좋겠습니다.
아마도, youtube에서 RDBMS는 쓰고 싶고, 확장성은 필요한데, MySQL 코드는 건드리고 싶지 않아서 다른 레이어로 구현한 것 같다는 생각이 많이 들었습니다.
그리고, Vitess의 장애 관리는 VTOrc라는 녀석이 하는데, 이 부분에 대해서는 다음에 정리해 보도록 하겠습니다.
'IT' 카테고리의 다른 글
unicrsv3.dll 오류의 원인 - CrossCert 인증 프로그램과 삭제 방법 (0) | 2024.11.19 |
---|---|
HP 노트북의 에러 없애기 - HP Client Security 제거로 DPPassFilter.dll 오류 해결 (3) | 2024.11.04 |
쿠팡 API를 이용하여 상품 업로드 시 인증 에러 원인과 처리 방법 (6) | 2024.10.31 |
네이버 스마트스토어 상품 가져와서 쿠팡에 자동으로 올리는 프로그램 만들기 (5) | 2024.10.28 |
우분투 20.04 리눅스에서 crontab(크론탭)으로 주기적인 작업 자동화하기 (0) | 2024.10.21 |