본문 바로가기
기술, 개발/Vitess

Vitess 수평 샤딩 1 (시퀀스)

by Jaejin Sim 2025. 8. 28.
반응형

Vitess 수평 샤딩 테스트

1. 개요

Vitess는 MySQL을 기반으로 하는 분산 데이터베이스 시스템으로, 대규모 트래픽을 처리하기 위한 샤딩(Sharding) 기능을 제공합니다. 샤딩에는 크게 두 가지 유형이 있습니다:

  • 수평 샤딩 (Horizontal Sharding): 키스페이스를 여러 샤드(Shard)로 나누거나 병합하는 방식
  • 수직 샤딩 (Vertical Sharding): 특정 테이블을 별도의 키스페이스로 이동하는 방식

이 문서에서는 수평 샤딩을 테스트한 내용을 정리합니다.

참고 문서

2. 수평 샤딩 개념

수평 샤딩은 동일한 테이블을 여러 샤드에 분산하여 저장하는 방식입니다. 예를 들어 payment 테이블이 여러 샤드에 분산되며, 특정 키를 기반으로 샤드가 결정됩니다.

Primary Key 문제

  • MySQL의 AUTO_INCREMENT를 사용하면 샤딩 환경에서 PK를 보장할 수 없음
  • ID 값이 순차적으로 증가하므로, 기밀 정보 유출 위험이 존재
  • 해결책: UUID 형식 또는 시퀀스(Sequence) 테이블 사용

3. 시퀀스 테이블 설정

Vitess는 AUTO_INCREMENT를 대체할 시퀀스(Sequence) 테이블을 지원합니다.

시퀀스 테이블 생성

CREATE TABLE customer_seq (
  id int,
  next_id bigint,
  cache bigint,
  PRIMARY KEY (id)
) COMMENT 'vitess_sequence';

INSERT INTO customer_seq (id, next_id, cache) VALUES (0, 1000, 100);

CREATE TABLE order_seq (
  id int,
  next_id bigint,
  cache bigint,
  PRIMARY KEY (id)
) COMMENT 'vitess_sequence';

INSERT INTO order_seq (id, next_id, cache) VALUES (0, 1000, 100);

시퀀스 테이블 컬럼 설명

  • id: 항상 0으로 설정됨
  • next_id: 현재 예약된 다음 ID 값 (기존 최대 AUTO_INCREMENT 값보다 커야 함)
  • cache: 사전에 할당할 ID 개수

4. VSchema 설정

Vitess에서 시퀀스 테이블을 인식하도록 VSchema를 설정해야 합니다.

{
  "tables": {
    "customer_seq": { "type": "sequence" },
    "order_seq": { "type": "sequence" },
    "product": {}
  }
}

5. Vindex 설정

샤딩된 테이블이 어느 샤드에 저장될지 결정하는 방법을 설정해야 합니다.

Vindex 개념

  • MySQL 인덱스와 달리 샤딩 키와 샤드 간의 매핑을 담당
  • 특정 컬럼 값이 어떤 샤드에 저장될지 결정

Vindex 유형

유형 설명

hash 키 값을 해시 함수로 변환하여 샤드 결정
unicode_loose_md5 UTF-8 문자열을 MD5 해시 후 샤드 결정
binary 값을 그대로 사용하여 샤드 결정
lookup 별도 테이블을 사용해 키와 샤드 매핑
reverse_bits 숫자 데이터를 비트 단위로 반전하여 샤드 결정

VSchema 설정 예제

{
  "sharded": true,
  "vindexes": {
    "hash": { "type": "hash" }
  },
  "tables": {
    "customer": {
      "column_vindexes": [{ "column": "customer_id", "name": "hash" }],
      "auto_increment": { "column": "customer_id", "sequence": "customer_seq" }
    },
    "corder": {
      "column_vindexes": [{ "column": "customer_id", "name": "hash" }],
      "auto_increment": { "column": "order_id", "sequence": "order_seq" }
    }
  }
}

6. 테이블 생성

CREATE TABLE `corder` (
  `order_id` bigint NOT NULL,
  `customer_id` bigint DEFAULT NULL,
  `sku` varchar(128) DEFAULT NULL,
  `price` bigint DEFAULT NULL,
  PRIMARY KEY (`order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

CREATE TABLE `customer` (
  `customer_id` bigint NOT NULL,
  `email` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`customer_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

7. xxHash란?

xxHash는 빠르고 고성능의 해시 함수로, 샤딩 키 생성 등에 사용됩니다.

  • 속도가 빠름 (SHA-1, MD5보다 빠름)
  • 충돌 가능성이 낮음
  • 다양한 비트 크기 제공 (xxHash32, xxHash64, xxHash128)

데이터 유형별 해시 추천

데이터 유형 해시 방법

VARCHAR unicode_loose_xxhash
VARBINARY xxhash
BIGINT hash

8. 샤딩 테스트 스크립트

DB 스키마와, VSchema 는 아래와 같은 방식으로 등록합니다.

DB 스키마를 직업 mysql 접속해서 등록하지 않습니다.

vtctldclient ApplySchema --sql-file create_commerce_seq.sql commerce || fail "Failed to create sequence tables in the commerce keyspace"
vtctldclient ApplyVSchema --vschema-file vschema_commerce_seq.json commerce || fail "Failed to create vschema sequences in the commerce keyspace"
vtctldclient ApplyVSchema --vschema-file vschema_customer_sharded.json customer || fail "Failed to create vschema in sharded customer keyspace"
vtctldclient ApplySchema --sql-file create_customer_sharded.sql customer || fail "Failed to create schema in sharded customer keyspace"

9. MySQL 데이터 확인

mysql> SHOW TABLES;
+--------------------+
| Tables_in_commerce |
+--------------------+
| customer_seq       |
| order_seq          |
| product            |
+--------------------+

mysql> SELECT * FROM customer_seq;
+----+---------+-------+
| id | next_id | cache |
+----+---------+-------+
|  0 |    1000 |   100 |
+----+---------+-------+

mysql> SELECT * FROM order_seq;
+----+---------+-------+
| id | next_id | cache |
+----+---------+-------+
|  0 |    1000 |   100 |
+----+---------+-------+

10. 시퀀스 자동증가 테스트

mysql> use customer;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
+--------------------+
| Tables_in_customer |
+--------------------+
| corder             |
| customer           |
+--------------------+
2 rows in set (0.00 sec)

mysql> select * from customer;
+-------------+--------------------+
| customer_id | email              |
+-------------+--------------------+
|           1 | alice@domain.com   |
|           2 | bob@domain.com     |
|           3 | charlie@domain.com |
|           4 | dan@domain.com     |
|           5 | eve@domain.com     |
+-------------+--------------------+
5 rows in set (0.00 sec)

mysql> select * from commerce.customer_seq;
+----+---------+-------+
| id | next_id | cache |
+----+---------+-------+
|  0 |    1000 |   100 |
+----+---------+-------+
1 row in set (0.00 sec)

mysql> insert into customer (email) values ('jack@domain.com');
Query OK, 1 row affected (0.04 sec)

mysql> select * from commerce.customer_seq;
+----+---------+-------+
| id | next_id | cache |
+----+---------+-------+
|  0 |    1100 |   100 |
+----+---------+-------+
1 row in set (0.00 sec)

mysql> select * from customer;
+-------------+--------------------+
| customer_id | email              |
+-------------+--------------------+
|           1 | alice@domain.com   |
|           2 | bob@domain.com     |
|           3 | charlie@domain.com |
|           4 | dan@domain.com     |
|           5 | eve@domain.com     |
|        1000 | jack@domain.com    |
+-------------+--------------------+
6 rows in set (0.00 sec)

mysql> insert into customer (email) values ('teemo@domain.com');
Query OK, 1 row affected (0.02 sec)

mysql> select * from customer;
+-------------+--------------------+
| customer_id | email              |
+-------------+--------------------+
|           1 | alice@domain.com   |
|           2 | bob@domain.com     |
|           3 | charlie@domain.com |
|           4 | dan@domain.com     |
|           5 | eve@domain.com     |
|        1000 | jack@domain.com    |
|        1001 | teemo@domain.com   |
+-------------+--------------------+
7 rows in set (0.00 sec)

mysql> select * from commerce.customer_seq;
+----+---------+-------+
| id | next_id | cache |
+----+---------+-------+
|  0 |    1100 |   100 |
+----+---------+-------+
1 row in set (0.00 sec)

10. 결론

  • AUTO_INCREMENT 제거 후 시퀀스 테이블을 활용
  • Vindex를 통해 데이터 분산 로직 설정
  • xxHash 등 해시 함수를 사용하여 샤드 결정
반응형

'기술, 개발 > Vitess' 카테고리의 다른 글

Vitess 수평샤딩 2 (리샤딩)  (2) 2025.08.28
Vitess MoveTables (수직샤딩)  (1) 2025.08.28
vtctld, vtgate, vttablet, vtorc  (0) 2025.08.28
Vitess 기본 개념  (0) 2025.08.28
로키리눅스 vitess 설치  (0) 2025.08.28