10 min readFeb 3, 2022
Vitess
CNCF Study in NaverLabs
What?
Vitess는 다음과 같은 특징을 가진다.
- 횡적 확장이 가능한 MySQL 클러스터링 시스템
- Cloud Native DB이고 리소스만 충분하다면 무한에 가까운 scale out 가능
- 손쉬운 구성과 auto piloting을 위한 쉬운 운영을 제공
- MySQL과의 높은 호환성 지원
- HA를 지원
Vitess의 Consistency 수준은 다음과 같다.
- ACID
- Isolation Level: READ COMMITTED(for cross-shard query)
- causal consistency(read after write) 지원 예정
Vitess는 다음과 같은 features들을 제공한다.
Sharding
- Vertical 샤딩과 Horizontal 샤딩을 모두 지원한다.
- 두개의 방식은 서로 완전히 독립적이다.
- 한 row는 하나의 KeyspaceID를 갖는다. 따라서 해당 row가 속한 샤드가 자연스럽게 정의된다.
MySQL 호환성
- one shared keyspace에서는 MySQL에서 이용하던 거의 대부분의 쿼리를 사용할 수 있다.
- shared keyspace에서는 cross shard 상에서 처리하기 어려운, 일부 사용할 수 없는 쿼리가 존재한다.
- endpoint만 MySQL -> Vitess의 vtgate service로 바꾸면, 기존 MySQL에서 사용하던 거의 모든 프레임워크를 그대로 사용할 수 있다.(예: mysql connector)
- Vitess는 MySQL 대비 throughput이 향상되고, query latency에 1~2ms 정도 손해를 본다.
- unmanaged tablet을 사용하면, 온라인 상에서 매우 손쉽게 MySQL -> Vitess로 데이터를 마이그레이션할 수 있다.(데이터 복사 및 동기화)
- Vitess는 성능을 위해서 가능한 쿼리를 하부의 MySQL로 push down한다.
- MySQL로 push down할 수 없는 cross-shard 쿼리도 지원한다.(scatter/gather, aggregation, join)
Vitess Operator
- 자동으로 압축된 백업을 보관한다.
Vitess Orchestrator
- 복제 형상 관리와 HA 관리를 위해서 사용한다.
- Discovery, Refactoring, Failure Detection, Recovery
- 자동으로 복제 형상을 찾거나 변경하고, 장애를 자동으로 감지해서 복구한다.
- 수동 복구나 Failover가 가능하다.
- primary, replica server의 outages뿐만 아니라 비정상적인 상태도 감지한다. 예를들어 writable replica, read-only primary, multi-primary, prematurely terminated failover process 등도 감지해서 복구해준다.
Monitoring
- Vitess는 널리 사용되는 다양한 모니터링 도구와의 통합을 제공한다.
- 예를들어 Prometheus, InfluxDB and Datadog를 지원한다.
- Tracing을 위한 간단한 구성을 통해서 Jaeger등과도 연동할 수 있다.
Scheme Migration
- vitess는 non-blocking, asynchronous, scheduled online DDL를 제공한다.
- gh-ost, pt-online-schema-change를 built-in하고 있어서, 최소한의 영향으로 온라인상에서 스킴을 변경할 수 있고, 비동기적인 DDL 수행이 가능하다.
Where?
- 2010년 유투브에서 오픈소스로 공개
- 2018년 2월 CNCF incubation 프로젝트가 됨
- 2019년 9월 CNCF graduation 프로젝트가 됨
Who?
When?
- MySQL을 사용하는 애플리케이션이 존재한다면
- MySQL을 사용하는 애플리케이션을 개발한다면
- Cloud Native DB가 필요하다면
- scale out이 가능한 RDBMS를 원한다면
- 최소한의 노력으로 MySQL DB를 운영하길 원한다면
- 심지어 간단한 prototype 개발을 위한 MySQL DB에도
Why?
운영 용이성
- k8s 기반
- 모니터링, 온라인 스킴 수정, 오픈 트레이싱 등 운영 필요한 필수 기능들을 내장하고 있음
- Linear Scale의 scale out이 가능함
- Connection pooling, hot row protection, restrict toxic query 등 프로덕션 레벨의 부가적인 기능들도 제공함
안정성
- CNCF graduated 프로젝트로 성숙도가 매우 높음
- 이미 많고 쟁쟁한 레퍼런스들을 보유하고 있음
- 자동 백업, 장애 감지 및 복구을 통해서 높은 HA를 제공함(Auto Healing)
호환성
- 기존 MySQL 쿼리를 대부분 그대로 사용할 수 있음
- MySQL 관련 프레임워크들과 별다른 설정없이 연동됨
- 아주 간단하게 MySQL -> Vitess로의 데이터 마이그레이션이 가능함
How?
Keyspace
- Vitess에서 Logical한 데이터베이스를 의미
- 샤딩을 하면 keyspace는 여러 MySQL DB에 매핑됨
- 애플리케이션단에서는 하나의 DB로 보임
Keyspace ID
- 분산 DB의 Sharding Key과 같은 개념
- DB에 저장되는 것이 아니고, 런타임에 계산됨
- 따라서 별도의 컬럼이 없고, SQL Hint도 없음
VSchema
- 하나의 논리적인 DB를 어떻게 물리적으로 샤드할 것인지를 표현
- 샤드가 필요없으면 정리하지 않아도 됨
Vindex
- 레코드에 KeyspaceID를 찾아낼 수 있는 방법을 제공
- 질의를 어떤 샤드로 라우팅해야하는지 결정하는데 사용
Primary Vindex
- primary vindex를 잘 선정하는 것은 성능에 큰 영향을 미침
- 한번 선정되면 변경이 불가능하므로 가급적이면 변경되지 않을 컬럼 선택
- PK가 첫번째 후보지만, FK를 고려할 수도 있음(single column)
Lookup Vindex
- 개념적으로 RDBMS의 secondary index에 해당한다.
- primary vindex로 처리할 수 없는 쿼리에 대한 최적화 담당한다.
- Vitess가 내부적으로 transparent하게 관리한다. 예를들어, 새로운 row가 입력이 변경되면 vitess가 내부적으로 lookup vindex를 변경해준다.
VTGate
- VTTablet의 상위에서 프록시 서버 역할을 한다.
- 애플리케이션에게 하나의 데이터베이스로 보여지게 한다.
- 적절한 VTTablet으로 쿼리를 릴레이한다.
- Stateless하기 때문에, 개수를 늘려서 scale out이 가능하다.
VTTablet
- mysqld의 사이드카로 붙어서, mysqld를 컨트롤한다.
- 하나의 Pod로 띄워져 있다.
VStream
- VTGate를 통해서 접근할 수 있는 변경을 통보하는 서비스
- 손쉽게 change data 캡춰를 구성할 수 있다.
- 데이터에 변경이 있을때 구독자에게 VEvents를 보내서 변경을 알려준다.
VReplication
- VStream을 기반으로 한다.
- VStream의 조합으로 각 스트림은 source keyspace/shard -> target keyspace/shard로의 스트림이다.
- source에서 target으로 데이터를 복사하고, 복사 이후에 계속되는 복제로 구성된다.
- Vitess의 많은 built-in workflow가 VReplication을 기반으로 동작한다.
Built-in Workflows
Resharding
- 샤드를 copy하고, replication한다.
- 리샤딩할 애들인 source를 거의 따라잡으면 자동으로 절체한다.
- 완료되면 reverse replication을 돌려줘서, 필요시 다시 옛날 구조로 돌아갈 수 있다. drop source workflow를 실행하면, reverse replication이 삭제되고 다시 예전 구조로 돌아갈 수 없게된다.
- 응용단의 쿼리가 이미 샤딩에 대한 검토가 끝난 상태라면 간단한 명령어로 처리가 가능하다.
Materialized Views
- Golbal table(reference table)를 사용하면, target keyspace의 모든 샤드를 복제해주고, source에 변경이 일어나면 target에도 변경을 반영한다. 이를 통해서 샤드간에 이루어질 수 있는 cross shard join을 local shard join으로 처리할 수 있다.
- Aggregated table: source에서 집계해서 target에 복제하고 유지한다. count, sum과 같은 집계 함수와 gourp by를 제공한다.
그밖에 Realtime rollups, backfilling lookup indexes, schema deployment, data migration, change notification 등의 workflow가 있다.
Performance
- linear scale out이 가능하기 때문에, resharding으로 분할해가면 성능에 대한 걱정은 하지 않아도 된다.
- 성능 측면에서는 bare metal과 거의 차이가 없다.
- 데이터와 트랜잭션이 잘 분산될 수 있도록 모델링하는 것이 중요하다.
- 디스크의 성능이 중요하므로, 성능 향상을 위해서 local ephemeral 사용을 고려할 수 있다.
Scalability Philosophy
Small instances
- Vitess는 작은 크기의 샤드를 권고한다.
- 안정적인 latency를 제공하기 위해서 ephemeral storage의 사용을 권장한다.
- 장애시 항상 re-provision할 것을 권고한다.
- 따라서 DB가 죽었을때, 최대 15분내에 re-provision할 수 있도록 MySQL 서버당 250GB정도를 추천한다.
Durability through replication
- 적어도 3개 이상의 replicas(1 primary + 2 replicas)를 권장한다.
- semi-sync replication을 통해서 복제 지연을 최소화한다.
semi-sync replication: primary가 commit을 하기 위해서는 적어도 하나의 replicase가 같은 commit을 가지는 것
- 크래쉬가 발생하면 구지 복구하지 않고, 백업을 가져와서 새로띄우고 새로운 primary를 따라가는 방식으로 복구한다.
References
https://ko.wikipedia.org/wiki/ACID
https://blog.acolyer.org/2016/02/24/a-critique-of-ansi-sql-isolation-levels/