SlideShare a Scribd company logo
1
Deep Dive Spider Engine
날짜 : 2016.03.21
Ver. 1.0
작성 : DB실 전수진
 What is Spider Engine?
 Architecture
 How to Create Spider Engine
 Limitation of a Spider Engine
 Guideline
 Q&A
Agenda
 What is Spider Engine?
 Architecture
 How to Create Spider Engine
 Limitation of a Spider Engine
 Guideline
 Q&A
Agenda
What is Spider Engine ?
http://spiderformysql.com/
https://mariadb.com/kb/en/mariadb/spider-storage-engine-overview/
What is Spider Engine ?
Image Source : http://barrymieny.deviantart.com/art/Database-104013446
What is Spider Engine ?
Spider Node 를 통해 하나의 DB 로 보임
Spider Node 는 데이터를 갖지않음
 What is Spider Engine?
 Architecture
 How to Create Spider Engine
 Limitation of a Spider Engine
 Guideline
 Q&A
Agenda
Architecture
Architecture
use mysql
show tables like ‘spider%’
spider_link_failed_log : HA에서 사용되는 테이블로 스파이더에 구성된 노드가 에러가 발생하면 로그 기록
spider_link_mon_servers : HA에서 사용되는 테이블로 스파이더의 HA 모니터링하는 서버의 계정을 관리
spider_tables : 스파이더 엔진으로 구성된 테이블 리스트 출력
spider_xa : 서로 다른 노드에 분산 트랜잭션 관리
spider_xa_member : 서로 다른 노드에 분산 트랜잭션을 원격 관리하는 서버 정보 저장
 What is Spider Engine?
 Architecture
 How to Create Spider Engine
 Limitation of a Spider Engine
 Guideline
 Q&A
Agenda
■ Step by Step
1. 서버 준비
Spider node Node 1
Node 2
Node 3
Node 4
※ 5대 DB Server 준비
① Spider Node
(mariaDB 10.0.9)
② Data Node
⑴ MySQL 5.6.24
⑵ MySQL 5.5.30
⑶ MySQL 5.7.9
⑷ mariaDB 10.0.4
How to Create Spider Engine
■ Step by Step
2-1. 아래 링크에서 스파이더 엔진 설치 파일을 받아 설치
2-2. 스파이더 엔진을 사용하기 위한 소스 적용
mysql -uroot -p < ../mariadb/share/install_spider.sql
2-3. 스파이더 엔진 설치 완료확인
SELECT engine, support, transactions, xa
FROM information_schema.engines;
https://mariadb.com/kb/en/mariadb/spider-storage-engine-overview/
+--------------------+---------+--------------+------+
| engine | support | transactions | xa |
+--------------------+---------+--------------+------+
| SPIDER | YES | YES | YES |
| CSV | YES | NO | NO |
| MyISAM | YES | NO | NO |
| BLACKHOLE | YES | NO | NO |
| FEDERATED | YES | YES | NO |
| MRG_MyISAM | YES | NO | NO |
| ARCHIVE | YES | NO | NO |
| MEMORY | YES | NO | NO |
| PERFORMANCE_SCHEMA | YES | NO | NO |
| Aria | YES | NO | NO |
| InnoDB | DEFAULT | YES | YES |
+--------------------+---------+--------------+------+
How to Create Spider Engine
Spider Engine
Node 1 (mysql 5.7.9)
Node 2 (mysql 5.6.24)
Node 3 (mysql 5.5.30)
Node 4 (mariadb 10.0.4)
Local Server
Spider Table
*.frm
*.par
File
Remote Server
Spider Table
*.frm
File
Data
(*.ibd)
192.168.124.134
192.168.124.137
192.168.124.138
192.168.124.139
192.168.124.140
Schema info (O)
Partition info (O)
Index data (X)
How to Create Spider Engine
■ Step by Step II
1. 서버 준비
Spider Engine
1. 원격서버 등록
sheard_node1 : 192.168.124.137
sheard_node2 : 192.168.124.138
sheard_node3 : 192.168.124.139
sheard_node4 : 192.168.124.140
CREATE SERVER shard_node1 FOREIGN DATA WRAPPER mysql
OPTIONS(
HOST '192.168.124.137',
DATABASE 'log_db',
USER 'root',
PASSWORD '123qwe!@#',
PORT 3306
);
CREATE SERVER shard_node4 FOREIGN DATA WRAPPER mysql
OPTIONS(
HOST '192.168.124.140',
DATABASE 'log_db',
USER 'root',
PASSWORD '123qwe!@#',
PORT 3306
);
☞ Reference
https://dev.mysql.com/doc/refman/5.7/en/create-server.html
...
Spider node
Node 1
Node 2
Node 3
Node 4
How to Create Spider Engine
■ Step by Step II
CREATE TABLE log_db.shardTest
(
id int unsigned NOT NULL AUTO_INCREMENT
, name char(120) NOT NULL DEFAULT ''
, PRIMARY KEY (id)
)
ENGINE=spider
COMMENT='wrapper "mysql", table "shardTest"'
PARTITION BY KEY (id)
(
PARTITION shard1 COMMENT = 'srv "shard_node1"'
, PARTITION shard2 COMMENT = 'srv "shard_node2"'
, PARTITION shard3 COMMENT = 'srv "shard_node3"'
, PARTITION shard4 COMMENT = 'srv "shard_node4"'
) ;
2. Shard 테이블을 생성
1) 데이터가 저장될 실제 테이블 이름과
파티션 Key 값에 따라
저장될 원격 서버의 정보를 Comment 에 입력함
Spider node
Node 1
Node 2
Node 3
Node 4
How to Create Spider Engine
■ Step by Step II
Spider Engine
Node 1 Node 2 Node 3 Node 4
CREATE TABLE log_db.shardTest
(
id int unsigned NOT NULL AUTO_INCREMENT
, name char(120) NOT NULL DEFAULT ''
, PRIMARY KEY (id)
)
ENGINE=innodb;
Spider node
Node 1
Node 2
Node 3
Node 4
How to Create Spider Engine
■ Step by Step II
3. 각 노드에 Data 테이블 생성
insert into log_db.shardTest(name) values ('spider_01');
insert into log_db.shardTest(name) values ('spider_01');
insert into log_db.shardTest(name) values ('spider_01');
insert into log_db.shardTest(name) values ('spider_01');
select * from shardtest;
+----+-----------+
| id | name |
+----+-----------+
| 1 | spider_01 |
| 4 | spider_01 |
| 3 | spider_01 |
| 2 | spider_01 |
+----+-----------+
Spider node
Node 1
Node 2
Node 3
Node 4
How to Create Spider Engine
■ Step by Step II
4. Spider 노드에서 데이터 입력 및 확인
Spider Engine
Node 1 Node 2
Node 3 Node 4
select * from shardtest;
+----+-----------+
| id | name |
+----+-----------+
| 1 | spider_01 |
+----+-----------+
select * from shardtest;
+----+-----------+
| id | name |
+----+-----------+
| 3 | spider_01 |
+----+-----------+
select * from shardtest;
+----+-----------+
| id | name |
+----+-----------+
| 4 | spider_01 |
+----+-----------+
select * from shardtest;
+----+-----------+
| id | name |
+----+-----------+
| 2 | spider_01 |
+----+-----------+
Spider node
Node 1
Node 2
Node 3
Node 4
How to Create Spider Engine
■ Step by Step II
5. 각 Data 노드에서 데이터 확인
1) 데이터가 잘 분산 됐는지 체크
Spider node
Node 1
Node 2
Node 3
Node 4
CREATE TABLE shardTest_node1(id int unsigned NOT NULL AUTO_INCREMENT,name char(120) NOT NULL DEFAULT '',PRIMARY KEY (id) )
ENGINE=FEDERATED CONNECTION='shard_node1/shardTest';
CREATE TABLE shardTest_node2(id int unsigned NOT NULL AUTO_INCREMENT,name char(120) NOT NULL DEFAULT '',PRIMARY KEY (id) )
ENGINE=FEDERATED CONNECTION='shard_node2/shardTest';
CREATE TABLE shardTest_node3(id int unsigned NOT NULL AUTO_INCREMENT,name char(120) NOT NULL DEFAULT '',PRIMARY KEY (id) )
ENGINE=FEDERATED CONNECTION='shard_node3/shardTest';
CREATE TABLE shardTest_node4(id int unsigned NOT NULL AUTO_INCREMENT,name char(120) NOT NULL DEFAULT '',PRIMARY KEY (id) )
ENGINE=FEDERATED CONNECTION='shard_node4/shardTest';
How to Create Spider Engine
■ Step by Step II
Spider Engine
0. 테스트를 위해 FEDERATED Table 구성
[localhost] ((none)) 06:31> show storage engines;
+--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+
| SPIDER | YES | Spider storage engine | YES | YES | NO |
| MRG_MyISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| InnoDB | DEFAULT | Percona-XtraDB, Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| FEDERATED | NO | FederatedX pluggable storage engine | NULL | NULL | NULL |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| Aria | YES | Crash-safe tables with MyISAM heritage | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+
CREATE TABLE log_db.shardTest
(
id int(10) unsigned NOT NULL AUTO_INCREMENT
, name char(120) NOT NULL DEFAULT ''
, PRIMARY KEY (id)
)
ENGINE=spider
COMMENT='wrapper "mysql", table "shardTest"'
PARTITION BY KEY (id)
(
PARTITION shard1 COMMENT = 'srv "shard_node1"'
, PARTITION shard2 COMMENT = 'srv "shard_node2"'
, PARTITION shard3 COMMENT = 'srv "shard_node3"'
, PARTITION shard4 COMMENT = 'srv "shard_node4"'
) ;
SELECT * FROM log_db.shardtest;
+----+-----------+
| id | name |
+----+-----------+
| 1 | SPIDER_01 |
| 5 | key1 |
| 4 | SPIDER_01 |
…
| 6 | key1 |
+----+-----------+
(원격데이터 정상추출)
결론 :
FEDERATED 와 SPIDER ENGINES
간의 의존성 없슴!
How to Create Spider Engine
Q. Spider Engine 이 Federated Engine 과 의존성이 있는 것은 아닐까? (FEDERATED STORAGE ENGINES OFF?)
How to Create Spider Engine
■ spider_internal_sql_log_off
shard된 서버에 spider 엔진에서 보낸 Query를
general log 기록합니다.
구문
(show table status from `log_db` like 'v_shardtest_group‘)
(show index from `log_db`.`v_shardtest_group`)
■ spider_remote_sql_log_off
shard된 서버에 sql_log_off 를 설정합니다.
구문
(set session sql_log_off = 1; )
 What is Spider Engine?
 Architecture
 How to Create Spider Engine
 Limitation of a Spider Engine
 Guideline
 Q&A
Agenda
Spider Engine
insert into shardtest(name) values ('spider_01');
Node 1
root@192.168.124.137 on using TCP/IP
set session transaction isolation level read committed;
set session autocommit = 1;
start transaction
SET NAMES utf8
log_db
select `id`,`name` from `log_db`.`shardTest`order by `id` desc
limit 1 for update
insert into `log_db`.`shardTest`(`id`,`name`)values(5,'spider_01')
commit
Node 2 Node 3 Node 4
select `id`,`name` from `log_db`.`shardTest` order by `id` desc
limit 1 for update
UPDATE Lock?
UPDATE Lock?
Limitation of a Spider Engine
1. INSERT (Auto Increment 발번)
Spider Engine Node 1 Node 2 Node 3 Node 4
Limitation of a Spider Engine
1. INSERT (Auto Increment 발번)
Auto_increment = 1
insert into shardtest(name) values ('spider_01');
select `id`,`name` from `log_db`.`shardTest`order by
`id` desc limit 1 for update
각 노드 Auto_increment MAX 확인
Auto_increment = 2
노드 선택
insert into shardtest(id,name) values (1,'spider_01');
insert into shardtest(id,name) values
(1,'spider_01');
Auto_increment = 2
insert into shardtest(name) values ('spider_02');
Node 1
select `id`,`name` from `log_db`.`shardTest`order by
`id` desc limit 1 for update
각 노드 Auto_increment MAX 확인
Auto_increment = 3
노드 선택
insert into shardtest(id,name) values (2,'spider_01');
Node 3
insert into shardtest(id,name) values
(2,'spider_01');
Node 1 Node 2 Node 3 Node 4
Limitation of a Spider Engine
■ spider_auto_increment_mode
-1 : 테이블 매개 변수를 사용한다.
0 : 일반모드
자동 증가 값을 원격 서버에서 얻은 카운터를 사용한다.
1 : Quick 모드
자동 증가 값을 Spider Node 내부 카운터를 사용한다.
2 : Set Zero Value
자동 증가 값을 Data Node 내부 카운터를 사용한다.
3 : null 입력시 자동 증가 값은 원격 서버에서 생성
0을 입력하면 로컬 서버에서 생성
1. INSERT (Auto Increment 발번)
☞ Reference
https://mariadb.com/kb/en/mariadb/spider-server-system-variables/
Node 3Node 2Node 1
Node 4
Limitation of a Spider Engine
Spider Engine
set spider_auto_increment_mode = 1;
insert into shardtest(name) values ('spider_01');
root@192.168.124.137 on using TCP/IP
set session transaction isolation level read committed;
set session autocommit = 1;
start transaction
SET NAMES utf8
log_db
insert into `log_db`.`shardTest`(`id`,`name`)values(6,'spider_01')
commit
1. INSERT (Auto Increment 발번)
Limitation of a Spider Engine
1) spider_auto_increment_mode 설정별 성능
spider_auto_increment_mode QPS AVG Query sec
0 Avg : 45 0.021
1 Avg : 185 0.005
2 Avg : 184 0.005
1. INSERT (Auto Increment 발번)
Limitation of a Spider Engine
2) spider_auto_increment_mode = 0 문제 발생
1. INSERT (Auto Increment 발번)
응답이 없음
Spider Engine
?
Limitation of a Spider Engine
2) spider_auto_increment_mode = 0 문제 발생
1. INSERT (Auto Increment 발번)
Node 1 Node 2 Node 3 Node 4
Commit 이 없음
Limitation of a Spider Engine
2) spider_auto_increment_mode = 0 문제 발생
1. INSERT (Auto Increment 발번)
Node 1 Node 2 Node 3 Node 4
general_log Commit
( X )
Spider Engine
Node 1
update shardtest set id = 9 where id = 8;
(select 0,`id`,`name` from `log_db`.`shardTest` where `id` = 8 for update)
delete from `log_db`.`shardTest` where `id` = 8 and `name` = 'spider_01' limit 1
insert high_priority into `log_db`.`shardTest`(`id`,`name`)values(9,'spider_01')
Data Move
Data Move
Node 1Node 4
Data move
CREATE TABLE `shardtest` (
...
) ENGINE=SPIDER AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='wrapper
"mysql", table "shardTest" '
Limitation of a Spider Engine
2. Update (Shard Key Update)
Change
Auto
increment
Node 4
Spider Engine
update shardtest set id = 9 where id = 8;
(select 0,`id`,`name` from `log_db`.`shardTest` where `id` = 8 for update)
delete from `log_db`.`shardTest` where `id` = 8 and `name` = 'spider_01' limit 1
insert high_priority into `log_db`.`shardTest`(`id`,`name`)values(9,'spider_01')
update shardtest set id = 17 where id = 9; (select 0,`id`,`name` from `log_db`.`shardTest` where `id` = 9 for update)
update `shardTest` set `id` = 17 where `id` = 9 and `name` = 'spider_01' limit 1
Node 1Spider Engine
CREATE TABLE `shardtest` (
...
) ENGINE=SPIDER AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COMMENT='wrapper
"mysql", table "shardTest" '
Node 1 Data move
CREATE TABLE `shardtest` (
...
) ENGINE=SPIDER AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='wrapper
"mysql", table "shardTest" '
Change
Auto
increment
Limitation of a Spider Engine
2. Update (Shard Key Update)
Node 1Node 4
Data move
Change
Auto
increment
Node 1
Node 4
Data Move
Data Move
Node 1
update shardtest set name = 'spider_02' where id = 1;
update shardtest set name = 'spider_03' where name = 'spider_01';
Spider Engine
(select 0,`id`,`name` from `log_db`.`shardTest` where `id` = 1 for update)
update `log_db`.`shardTest` set `name` = 'spider_02' where `id` = 1 limit 1
update `log_db`.`shardTest` set `name` = 'spider_03' where `id` = 2 and
`name` = 'spider_01' limit 1
(select 0,`id`,`name` from `log_db`.`shardTest` where `name` = 'spider_01'
for update)
Node 2 Node 3 Node 4
Node 2 Node 3 Node 4
Shard key (X)
Node 1
Limitation of a Spider Engine
2. Update (Shard Key 가 아닌 컬럼의 Update)
Spider Engine
Node 3
update shardtest set name = 'spider_01' where name = 'spider_02';
Spider Engine
update `log_db`.`shardTest` set `name` = 'spider_01' where `id` = 1 and
`name` = 'spider_02' limit 1
update `log_db`.`shardTest` set `name` = 'spider_01' where `id` = 13 and
`name` = 'spider_02' limit 1
(select 0,`id`,`name` from `log_db`.`shardTest` where `name` = 'spider_02'
for update)
Shard key (X)
1 건 업데이트
Limitation of a Spider Engine
2. Update (Shard Key 가 아닌 컬럼의 Update)
update shardtest set name = 'spider_03' where name = 'spider_01';
Node 1
Spider Engine
update `log_db`.`shardTest` set `name` = 'spider_03' where `id` = 1 and
`name` = 'spider_01' limit 1
(select 0,`id`,`name` from `log_db`.`shardTest` where `name` = 'spider_01'
for update)
Node 2 Node 3 Node 4
Shard key (X)
Node 1
여러 건 업데이트
Node 1
Node 2 Node 3 Node 4Node 1
1건씩 처리됨
⇒ 운영시 binlog size 급증 이슈발생가능!
Truncate table shardTest; truncate table `log_db`.`shardTest`
Limitation of a Spider Engine
3. Truncate
Spider Engine Node 2 Node 3 Node 4Node 1
Alter table shardTest ADD COLUMN TEST_Col1 int;
Alter table shardTest DROP COLUMN TEST_Col1 int;
CREATE INDEX idx_shardtest ON shardtest(name);
DROP INDEX idx_shardtest ON shardtest;
Shard Shema 변경 없음
Limitation of a Spider Engine
4. Alter
Spider Engine Node 2 Node 3 Node 4Node 1
Shard Shema 변경 없음
Alter table shardtest ADD COLUMN (add_col1 int);
SELECT * FROM shardtest;
(ERROR 1054 (42S22): Unknown column 'add_col1' in 'field list‘)
SELECT id, name FROM shardtest;
+----+-----------+
| id | name |
+----+-----------+
| 1 | SPIDER_01 |
…
| 2 | SPIDER_01 |
+----+-----------+
4 rows in set (0.26 sec)
select `id`,`name` from `log_db`.`shardTest` order by `id`,`name`
General_log Query
Limitation of a Spider Engine
4. Alter
Spider Engine Node 2 Node 3 Node 4Node 1
Shard Shema 변경 없음
Alter table shardtest ADD COLUMN (add_col1 int);
Limitation of a Spider Engine
4. Alter
Spider Engine Node 2 Node 3 Node 4Node 1
INSERT INTO shardtest(name) VALUES('key2');
Query OK, 1 row affected (0.45 sec)
select id, name from shardtest;
+----+-----------+
| id | name |
+----+-----------+
| 1 | SPIDER_01 |
| 2 | SPIDER_01 |
| … |
| 5 | key2 |
+----+-----------+
UPDATE shardtest
set name = 'key3'
where id = 5;
ERROR 1054 (42S22): Unknown column 'add_col1' in 'field list'
insert into `log_db`.`shardTest`(`id`,`name`) values (5,'key2')
(select 0,`id`,`name`,`add_col1` from `shardTest` where `id` = 5 for update)
rollback
General_log Query
Alter table shardtest DROP COLUMN (add_col1 int);
Limitation of a Spider Engine
4. Alter
Spider Engine Node 2 Node 3 Node 4Node 1
General_log Query
select * from shardtest;
+----+-----------+
| id | name |
+----+-----------+
| 1 | SPIDER_01 |
| 2 | SPIDER_01 |
| 3 | SPIDER_01 |
| 4 | SPIDER_01 |
| 5 | key1 |
| 6 | key1 |
| 7 | SPIDER_01 |
| 8 | SPIDER_01 |
+----+-----------+
Select OK
Alter table shardtest ADD COLUMN (add_col1 int);
(각 Data 노드에 컬럼추가)
select `id`,`name` from `log_db`.`shardTest` order by `id`,`name`
※ Schema 수정 순서에 유의
1) Data node 수정
2) Spider node 수정
select `id`,`name` from `log_db`.`shardTest`select * from shardtest;
+----+-----------+
| id | name |
+----+-----------+
| 1 | spider_01 | -- shard1
| 4 | spider_01 | -- shard2
| 3 | spider_01 | -- shard3
| 2 | spider_01 | -- shard4
+----+-----------+
select `id`,`name` from `log_db`.`shardTest`
select * from shardtest order by id;
+----+-----------+
| id | name |
+----+-----------+
| 1 | spider_01 | -- shard1
| 2 | spider_01 | -- shard4
| 3 | spider_01 | -- shard3
| 4 | spider_01 | -- shard2
+----+-----------+
Limitation of a Spider Engine
5. SELECT (order by)
Spider Engine Node 2 Node 3 Node 4Node 1
PK 순서 ( X )
Spider Node 에서
Sort 발생
Spider Node
“Sort buffer size”
설정에 따른 성능테스트
약 100만 row TEST
+-----+--------------+-------------+
| int | varchar(120) | varchar(10) |
+-----+--------------+-------------+
| id | name | node_num |
+-----+--------------+-------------+
| 1 | aaa | node1 |
+-----+--------------+-------------+
TEST QUERY
select * from shardtest order by id;
Variables (sort_buffer_size) avg retun time
256K 16.612
512K 12.76
1M 10.562
2M 9.988
4M 7.812
8M 7.93
16M 7.508 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
256K 512K 1M 2M 4M 8M 16M
avg retun time
Limitation of a Spider Engine
5. SELECT (order by)
File Sort Algorithm
1. Single Pass
 SELECT되는 모든 컬럼
버퍼에 담아 정렬하여
바로 리턴
2. Two Pass
 정렬 대상 + KEY로 정렬
하여 해당 정렬 기준으
로 KEY값 리턴
※ Two Pass는 정렬을 위하여
temp file을 사용한다.
Sort_merge_passes는 Merge
횟수를 카운트 한다.
약 100만 row TEST
+-----+--------------+-------------+
| int | varchar(120) | varchar(10) |
+-----+--------------+-------------+
| id | name | node_num |
+-----+--------------+-------------+
| 1 | aaa | node1 |
+-----+--------------+-------------+
TEST QUERY
select * from shardtest order by id;
Variables (sort_buffer_size) avg retun time
256K 16.612
512K 12.76
1M 10.562
2M 9.988
4M 7.812
8M 7.93
16M 7.508
Limitation of a Spider Engine
5. SELECT (order by)
상태 확인 : show status like ‘%sort%’
INSERT INTO shardtest(name) values('SPIDER_01');
…
INSERT INTO shardtest(name) values('SPIDER_04’);
INSERT INTO shardtest(name) values('key1');
select `id`,`name` from `log_db`.`shardTest`SELECT * FROM shardtest where name = 'key1';
+----+------+
| id | name |
+----+------+
| 5 | key1 |
+----+------+
Spider Engine
Filtering
Shard DB Filter ? ?
Limitation of a Spider Engine
5. SELECT (where)
Spider Engine Node 2 Node 3 Node 4Node 1
CREATE TABLE `shardtest` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` char(120) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table
"shardTest" '
/*!50100 PARTITION BY KEY (`id`)
(PARTITION shard1 COMMENT = 'srv "shard_node1" ' ENGINE = SPIDER,
…
PARTITION shard4 COMMENT = 'srv "shard_node4" ' ENGINE = SPIDER) */
select `id`,`name` from `log_db`.`shardTest` where `name` = 'key1'
Shard DB Filtering !!!
CREATE INDEX idx_shardtest_01 ON shardtest(name);
SELECT * FROM shardtest where name = 'key1';
+----+------+
| id | name |
+----+------+
| 5 | key1 |
+----+------+
CREATE TABLE `shardtest` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` char(120) NOT NULL DEFAULT '',
PRIMARY KEY (`id`),
KEY `idx_shardtest_01` (`name`)
) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table
"shardTest" '
/*!50100 PARTITION BY KEY (`id`)
(PARTITION shard1 COMMENT = 'srv "shard_node1" ' ENGINE = SPIDER,
PARTITION shard2 COMMENT = 'srv "shard_node2" ' ENGINE = SPIDER,
PARTITION shard3 COMMENT = 'srv "shard_node3" ' ENGINE = SPIDER,
PARTITION shard4 COMMENT = 'srv "shard_node4" ' ENGINE = SPIDER)
*/
Limitation of a Spider Engine
5. SELECT (where)
Spider Engine Node 2 Node 3 Node 4Node 1
select name from shardtest group by name;
KEY `idx_shardtest_01` (`name`) 있는 상태
select count(*) from `log_db`.`shardTest`
select `name` from `log_db`.`shardTest` order by `name` desc
select `name` from `log_db`.`shardTest` order by `name`
select `name` from `log_db`.`shardTest` where `name` > 'key1' order by `name`
select `name` from `log_db`.`shardTest` where `name` > 'SPIDER_01' order by `name`
+-----------+
| name |
+-----------+
| key1 |
| SPIDER_01 |
+-----------+
KEY `idx_shardtest_01` (`name`) 를 제거하면…
DROP INDEX idx_shardtest_01 ON shardtest;
select name from shardtest group by name;
+-----------+
| name |
+-----------+
| key1 |
| SPIDER_01 |
+-----------+
select `name` from `log_db`.`shardTest`
Shard DB Grouping??
Limitation of a Spider Engine
Spider Engine Node 2 Node 3 Node 4Node 1
5. SELECT (Group By)
Shard DB Full ScanShard DB Grouping
select id from shardtest group by name;
+----+
| id |
+----+
| 5 |
| 1 |
+----+
Shard DB Sorting
select `id`,`name` from `log_db`.`shardTest` order by `name`
Shard DB Grouping
select name, count(*) from shardtest group by name;
+-----------+----------+
| name | count(*) |
+-----------+----------+
| key1 | 2 |
| SPIDER_01 | 6 |
+-----------+----------+
select `name` from `log_db`.`shardTest` order by `name`
select count(*) from `log_db`.`shardTest`
select count(*) from `log_db`.`shardTest` ?
Limitation of a Spider Engine
5. SELECT (Group By)
Spider Engine Node 2 Node 3 Node 4Node 1
CREATE TABLE `shardtest` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` char(120) NOT NULL DEFAULT '',
`node_num` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB AUTO_INCREMENT=1048576 DEFAULT CHARSET=utf8
Limitation of a Spider Engine
5. SELECT (Group By MIN, MAX, COUNT(*) {INDEX (O)})
Spider Engine Node 2 Node 3 Node 4Node 1
select max(id) from shardtest;
select min(id) from shardtest;
select count(id) from shardtest;
select count(*) from shardtest;
select name, min(id) from shardtest;
select name, max(id) from shardtest;
select name, count(*) from shardtest;
select name, count(id) from shardtest;
select `id` from `log_db`.`shardTest` order by `id` desc limit 1;
select `id` from `log_db`.`shardTest` order by `id` limit 1;
select count(*) from `log_db`.`shardTest`;
select count(*) from `log_db`.`shardTest`;
select `id`,`name` from `log_db`.`shardTest` order by `id`,`name`;
select `id`,`name` from `log_db`.`shardTest` order by `id`,`name`;
select `name` from `log_db`.`shardTest` order by `name`;
select `id`,`name` from `log_db`.`shardTest` order by `id`,`name`;
“Name”
index (X)
CREATE TABLE `shardtest` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` char(120) NOT NULL DEFAULT '',
`node_num` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `idx_shardtest_01` (`name`),
KEY `idx_shardtest_02` (`id`,`name`)
) …
Limitation of a Spider Engine
5. SELECT (Group By MIN, MAX, COUNT(*) {INDEX (X)})
Spider Engine Node 2 Node 3 Node 4Node 1
select max(name) from shardtest;
select min(name) from shardtest;
select count(name) from shardtest;
select count(*) from shardtest;
select name, min(id) from shardtest;
select name, max(id) from shardtest;
select name, count(*) from shardtest;
select name, count(id) from shardtest;
select `name` from `log_db`.`shardTest`;
select `name` from `log_db`.`shardTest`;
select count(*) from `log_db`.`shardTest`;
select count(*) from `log_db`.`shardTest`;
select `id`,`name` from `log_db`.`shardTest`;
select `id`,`name` from `log_db`.`shardTest`;
select `id`,`name` from `log_db`.`shardTest`;
select `id`,`name` from `log_db`.`shardTest`;
CREATE TABLE `shardtest` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` char(120) NOT NULL DEFAULT '',
`node_num` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB AUTO_INCREMENT=1048576 DEFAULT CHARSET=utf8
CREATE TABLE `shardtest` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` char(120) NOT NULL DEFAULT '',
`node_num` varchar(10) DEFAULT NULL,
PRIMARY KEY (`id`)
) …
Full Scan
CREATE VIEW v_shardtest_group
AS
select name, max(id) as id, count(*) as cnt
from shardtest
group by name;
CREATE TABLE `v_shardtest_group` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` CHAR(120) NOT NULL DEFAULT '',
`cnt` INT NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_shardtest_01` (`name`)
)
ENGINE=SPIDER
DEFAULT CHARSET=utf8
COMMENT='wrapper "mysql", table "v_shardtest_group" '
/*!50100 PARTITION BY KEY (`id`)
(PARTITION shard1 COMMENT = 'srv "shard_node1"' ENGINE = SPIDER,
PARTITION shard2 COMMENT = 'srv "shard_node2"' ENGINE = SPIDER,
PARTITION shard3 COMMENT = 'srv "shard_node3"' ENGINE = SPIDER,
PARTITION shard4 COMMENT = 'srv "shard_node4"' ENGINE = SPIDER) */ ;
select name, sum(cnt) from v_shardtest_group group by name; select `name`,`cnt` from `log_db`.`v_shardtest_group` order by `name`
Limitation of a Spider Engine
5. SELECT (Group By)
Spider Engine Node 2 Node 3 Node 4Node 1
select * from shardtest order by id;
select * from shardtest order by name;
select id from shardtest order by id;
select name from shardtest order by id;
select id from shardtest order by name;
select name from shardtest order by name;
Limitation of a Spider Engine
5. SELECT (Order By)
Spider Engine Node 2 Node 3 Node 4Node 1
select `id`,`name` from `log_db`.`shardTest`
select `id`,`name` from `log_db`.`shardTest`
select count(*) from `log_db`.`shardTest`
select `id` from `log_db`.`shardTest` order by `id`
select `id`,`name` from `log_db`.`shardTest`
select `id`,`name` from `log_db`.`shardTest`
select count(*) from `log_db`.`shardTest`
select `name` from `log_db`.`shardTest` order by `name`
Shard DB DataSpider DB Sorting
create table join_tb(
jt_no int auto_increment
, ct_code char(4)
, ct_cnt int
, primary key(jt_no)
);
create table common_tb(
ct_no int auto_increment
, ct_code char(4)
, ct_name varchar(30)
, primary key (ct_no)
, key (ct_code)
)
ENGINE=SPIDER DEFAULT CHARSET=utf8
COMMENT='wrapper "mysql", table "common_tb" '
/*!50100 PARTITION BY KEY (ct_no)
(PARTITION shard1 COMMENT = 'srv "shard_node1"' ENGINE = SPIDER) */
create table join_tb(
jt_no int auto_increment
, ct_ code char(4)
, ct_ cnt int
, primary key(jt_no)
)
ENGINE=SPIDER DEFAULT CHARSET=utf8
COMMENT='wrapper "mysql", table "join_tb" '
/*!50100 PARTITION BY KEY (`jt_no`)
(PARTITION shard1 COMMENT = 'srv "shard_node1"' ENGINE = SPIDER,
PARTITION shard2 COMMENT = 'srv "shard_node2"' ENGINE = SPIDER,
PARTITION shard3 COMMENT = 'srv "shard_node3"' ENGINE = SPIDER,
PARTITION shard4 COMMENT = 'srv "shard_node4"' ENGINE = SPIDER) */
create table common_tb(
ct_no int auto_increment
, ct_code char(4)
, ct_name varchar(30)
, primary key (ct_no)
);
Limitation of a Spider Engine
5. SELECT (Join)
Spider Engine Node 1
Node 2 Node 3 Node 4Node 1
insert into join_tb(ct_code, ct_cnt) values ('A001',1);
insert into join_tb(ct_code, ct_cnt) values ('A002',2);
insert into join_tb(ct_code, ct_cnt) values ('A003',3);
…
insert into join_tb(ct_code, ct_cnt) values ('A009',49);
insert into join_tb(ct_code, ct_cnt) values ('A010',50);
insert into common_tb(ct_code, ct_name) values ('A001','TEST1');
insert into common_tb(ct_code, ct_name) values ('A002','TEST2');
insert into common_tb(ct_code, ct_name) values ('A003','TEST3');
…
insert into common_tb(ct_code, ct_name) values ('A011','TEST11');
insert into common_tb(ct_code, ct_name) values ('A012','TEST12');
insert into common_tb(ct_code, ct_name) values ('A013','TEST13');
select a.ct_cnt, a.ct_code, b.ct_name
from join_tb a
, common_tb b
where a.ct_code = b.ct_code;
select `ct_code`,`ct_cnt` from `log_db`.`join_tb`
select `ct_code`,`ct_name` from `log_db`.`common_tb` where `ct_code` = 'A010'
select `ct_code`,`ct_name` from `log_db`.`common_tb` where `ct_code` = 'A006'
select `ct_code`,`ct_name` from `log_db`.`common_tb` where `ct_code` = 'A012'
…
select `ct_code`,`ct_name` from `log_db`.`common_tb` where `ct_code` = 'A007'
select `ct_code`,`ct_name` from `log_db`.`common_tb` where `ct_code` = 'A013'
select `ct_code`,`ct_name` from `log_db`.`common_tb` where `ct_code` = 'A009'
…
Limitation of a Spider Engine
5. SELECT (Join)
Spider Engine Node 2 Node 3 Node 4Node 1
join_tb
common_tb
join_tb join_tb join_tb
1단계 : join_tb 데이터 스캔
2단계 : 1단계에서 읽은 데이터를 대상
으로 common_tb 데이터 확인
Spider Engine
Node 1
join
Node 2
join
Node 3
join
Node 4
join
Spider Engine
join
Node 1
Node 2
Node 3
Node 4
Limitation of a Spider Engine
5. SELECT (Join)
Insert common_tb
common_tb
DATA
common_tb
DATA
common_tb
DATA
common_tb
DATA
?
Global table Join View
View ?
Limitation of a Spider Engine
5. SELECT (Join)
Node 2 Node 3 Node 4Node 1
Spider Engine Node 2 Node 3 Node 4Node 1
alter table common_tb
COMMENT='wrapper "mysql", table "common_tb" '
/*!50100 PARTITION BY KEY (ct_no)
(PARTITION shard1
COMMENT = 'srv "shard_node2 shard_node3 shard_node4 shard_node1"'
ENGINE = SPIDER)
*/
TRUNCATE TABLE common_tb;
insert into common_tb(ct_code, ct_name) values ('A001','TEST1');
insert into common_tb(ct_code, ct_name) values ('A002','TEST2');
insert into common_tb(ct_code, ct_name) values ('A003','TEST3');
…
insert into common_tb(ct_code, ct_name) values ('A011','TEST11');
insert into common_tb(ct_code, ct_name) values ('A012','TEST12');
insert into common_tb(ct_code, ct_name) values ('A013','TEST13');
insert into `common_tb`(`ct_no`,`ct_code`,`ct_name`)values(1,'A001','TEST01')
insert into `common_tb`(`ct_no`,`ct_code`,`ct_name`)values(2,'A002','TEST02')
insert into `common_tb`(`ct_no`,`ct_code`,`ct_name`)values(3,'A003','TEST03')
…
insert into `common_tb`(`ct_no`,`ct_code`,`ct_name`)values(11,'A011','TEST11')
insert into `common_tb`(`ct_no`,`ct_code`,`ct_name`)values(12,'A012','TEST12')
insert into `common_tb`(`ct_no`,`ct_code`,`ct_name`)values(13,'A013','TEST13')
Limitation of a Spider Engine
5. SELECT (Join)
Spider Engine Node 2 Node 3 Node 4Node 1
CREATE ALGORITHM = MERGE VIEW v_join_tb
as
select a.jt_no, a.ct_cnt, a.ct_code a_ct_code, b.ct_code b_ct_code, b.ct_name
from join_tb a
, common_tb b
where a.ct_code = b.ct_code;
CREATE TABLE v_join_tb(
jt_no int
, ct_cnt int
, a_ct_code char(4)
, b_ct_code char(4)
, ct_name varchar(30)
, primary key (jt_no)
, key (a_ct_code, b_ct_code)
)
ENGINE=SPIDER DEFAULT CHARSET=utf8
COMMENT='wrapper "mysql", table "v_join_tb" '
/*!50100 PARTITION BY KEY (`jt_no`)
(PARTITION shard1 COMMENT = 'srv "shard_node1"' ENGINE = SPIDER,
..
PARTITION shard4 COMMENT = 'srv "shard_node4"' ENGINE = SPIDER) */;
select * from v_join_tb
where a_ct_code = 'A001' and b_ct_code = 'A001';
select `jt_no`,`ct_cnt`,`a_ct_code`,`b_ct_code`,`ct_name`
from `log_db`.`v_join_tb`
where `a_ct_code` = 'A001' and `b_ct_code` = 'A001'
Key Point !!
Limitation of a Spider Engine
5. SELECT (Join)
Spider Engine Node 2 Node 3 Node 4Node 1
CREATE VIEW ALGORITHM
1) MERGE
2) TEMPTABLE
select * from v_join_tb
where a_ct_code = 'A001’and b_ct_code = 'A001'; select `jt_no`,`ct_cnt`,`a_ct_code`,`b_ct_code`,`ct_name`
from `log_db`.`v_join_tb`
where `a_ct_code` = 'A001' and `b_ct_code` = 'A001'
Limitation of a Spider Engine
5. SELECT (Join)
Spider Engine Node 2 Node 3 Node 4Node 1
INDEX Access OK !
SELECT *
FROM shardtest
WHERE name IN ('key1','SPIDER_01');
+----+-----------+
| id | name |
+----+-----------+
| 1 | SPIDER_01 |
| 5 | key1 |
| 4 | SPIDER_01 |
| 8 | SPIDER_01 |
| 3 | SPIDER_01 |
| 7 | SPIDER_01 |
| 2 | SPIDER_01 |
| 6 | key1 |
+----+-----------+
Temporary Table ← IN KEY
?
Spider Engine Node 2 Node 3 Node 4Node 1
Limitation of a Spider Engine
5. SELECT ( IN( ) )
drop temporary table if exists log_db.tmp_spider_bka_0x7f5ba7f23420_shardTest;
create temporary table log_db.tmp_spider_bka_0x7f5ba7f23420_shardTest(
id bigint
, c0 char(120) collate utf8_general_ci
)
engine=memory default charset=utf8 collate utf8_general_ci;
insert into log_db.tmp_spider_bka_0x7f5ba7f23420_shardTest(id,c0)values(0,'key1'),(1,'SPIDER_01');
select a.id,b.`id`,b.`name`
from log_db.tmp_spider_bka_0x7f5ba7f23420_shardTest a,`log_db`.`shardTest` b
where a.c0 <=> b.`name`;
drop temporary table if exists log_db.tmp_spider_bka_0x7f5ba7f23420_shardTest;
OR equal
Spider Engine Node 2 Node 3 Node 4Node 1
Limitation of a Spider Engine
5. SELECT ( IN( ) )
SELECT * FROM shardtest WHERE name = 'key1'
UNION ALL
SELECT * FROM shardtest WHERE name = 'SPIDER_01';
+----+-----------+
| id | name |
+----+-----------+
| 5 | key1 |
| 6 | key1 |
| 1 | SPIDER_01 |
| 4 | SPIDER_01 |
| 8 | SPIDER_01 |
| 3 | SPIDER_01 |
| 7 | SPIDER_01 |
| 2 | SPIDER_01 |
+----+-----------+
select `id`,`name` from `log_db`.`shardTest` where `name` = 'SPIDER_01'
select `id`,`name` from `log_db`.`shardTest` where `name` = 'key1'
create table shardtest_key (
shard_key int
, shard_no int NOT NULL AUTO_INCREMENT
, val varchar(100)
, PRIMARY KEY (shard_no, shard_key)
)
ENGINE=SPIDER DEFAULT CHARSET=utf8
COMMENT='wrapper "mysql", table "shardtest_key" '
/*!50100 PARTITION BY LIST (`shard_key`)
(PARTITION shard1 VALUES IN (1) COMMENT = 'srv "shard_node1"' ENGINE = SPIDER,
PARTITION shard3 VALUES IN (3) COMMENT = 'srv "shard_node3"' ENGINE = SPIDER,
PARTITION shard4 VALUES IN (4) COMMENT = 'srv "shard_node4"' ENGINE = SPIDER,
PARTITION shard2 VALUES IN (2) COMMENT = 'srv "shard_node2"' ENGINE = SPIDER) */
create table shardtest_key (
shard_key int
, shard_no int NOT NULL AUTO_INCREMENT
, val varchar(100)
, PRIMARY KEY (shard_no)
);
insert into shardtest_key(shard_key, val) values (1,'node1');
insert into shardtest_key(shard_key, val) values (2,'node2');
insert into shardtest_key(shard_key, val) values (3,'node3');
insert into shardtest_key(shard_key, val) values (4,'node4');
…
insert into shardtest_key(shard_key, val) values (2,'node2');
insert into shardtest_key(shard_key, val) values (3,'node3');
insert into shardtest_key(shard_key, val) values (4,'node4');
Spider Engine Node 2 Node 3 Node 4Node 1
Limitation of a Spider Engine
5. SELECT ( IN( ) + shardkey)
SELECT *
FROM shardtest_key
WHERE shard_key in (1,2)
AND shard_no in (1,5,9,2,26);
+-----------+----------+-------+
| shard_key | shard_no | val |
+-----------+----------+-------+
| 1 | 1 | node1 |
| 1 | 5 | node1 |
| 1 | 9 | node1 |
| 2 | 2 | node2 |
| 2 | 26 | node2 |
+-----------+----------+-------+
Spider Engine Node 2
Node 3 Node 4
Node 1
Limitation of a Spider Engine
5. SELECT ( IN( ) + shardkey )
drop temporary table if exists log_db.tmp_spider_bka_0x7f0c403d1820_shardtest_key;
create temporary table log_db.tmp_spider_bka_0x7f0c403d1820_shardtest_key(
id bigint
, c0 int(11)
, c1 int(11)
)
engine=memory default charset=utf8 collate utf8_general_ci;
insert into log_db.tmp_spider_bka_0x7f0c403d1820_shardtest_key(id,c0,c1)
values(0,1,1),(1,2,1),(2,5,1),(3,9,1),(4,26,1)
select a.id,b.`shard_key`,b.`shard_no`,b.`val`
from log_db.tmp_spider_bka_0x7f0c403d1820_shardtest_key a
,`log_db`.`shardtest_key` b
where a.c0 <=> b.`shard_no` and a.c1 <=> b.`shard_key`
drop temporary table if exists log_db.tmp_spider_bka_0x7f0c403d1820_shardtest_key
values(0,1,2),(1,2,2),(2,5,2),(3,9,2),(4,26,2)
id >= 1 and id <= 6
equal
Spider Engine Node 2 Node 3 Node 4Node 1
Limitation of a Spider Engine
5. SELECT ( BETWEEN )
SELECT * FROM shardtest where id between 1 and 6;
+----+-----------+
| id | name |
+----+-----------+
| 1 | SPIDER_01 |
| 5 | key1 |
| 4 | SPIDER_01 |
| 3 | SPIDER_01 |
| 2 | SPIDER_01 |
| 6 | key1 |
+----+-----------+
(select 0,`id`,`name`
from `log_db`.`shardTest`
where `id` >= 1 and `id` <= 6
order by `id`)
order by `id`
explain SELECT * FROM shardtest where name = 'key1' and id >= 1 and id <= 6;
+------+-------------+-----------+-------+--------------------------+---------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+-------+--------------------------+---------+---------+------+------+-------------+
| 1 | SIMPLE | shardtest | range | PRIMARY,idx_shardtest_01 | PRIMARY | 4 | NULL | 8 | Using where |
+------+-------------+-----------+-------+--------------------------+---------+---------+------+------+-------------+
Spider Engine Node 2 Node 3 Node 4Node 1
Limitation of a Spider Engine
5. SELECT ( BETWEEN )
SELECT *
FROM shardtest
WHERE name = 'key1‘
AND id >= 1 and id <= 6;
+----+------+
| id | name |
+----+------+
| 5 | key1 |
| 6 | key1 |
+----+------+
(select 0,`id`,`name`
from `log_db`.`shardTest`
where `id` >= 1 and `id` <= 6
order by `id`)
order by `id`
Spider Engine
“name” filter
Shard DB Data
Index PRIMARY KEY
explain SELECT * FROM shardtest use index(idx_shardtest_01) where name = 'key1' and id >= 1 and id <= 6;
+------+-------------+-----------+------+------------------+------------------+---------+-------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+------+------------------+------------------+---------+-------+------+-------------+
| 1 | SIMPLE | shardtest | ref | idx_shardtest_01 | idx_shardtest_01 | 360 | const | 9687 | Using where |
+------+-------------+-----------+------+------------------+------------------+---------+-------+------+-------------+
idx_shardtest_01 : name
Spider Engine Node 2 Node 3 Node 4Node 1
Limitation of a Spider Engine
5. SELECT ( BETWEEN )
SELECT *
FROM shardtest use index(idx_shardtest_01)
WHERE name = 'key1‘
AND id >= 1 and id <= 6;
+----+------+
| id | name |
+----+------+
| 5 | key1 |
| 6 | key1 |
+----+------+
select `id`,`name` from `log_db`.`shardTest` where `name` = 'key1'
Spider Engine
“id” filter
Shard DB Data
Spider Engine Node 2 Node 3 Node 4Node 1
Limitation of a Spider Engine
5. SELECT ( BETWEEN )
create index idx_shardtest_03 on shardtest(name, id);
explain SELECT * FROM shardtest use index(idx_shardtest_03) where name = 'key1' and id between 1 and 6;
+------+-------------+-----------+-------+------------------+------------------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+------+-------------+-----------+-------+------------------+------------------+---------+------+------+--------------------------+
| 1 | SIMPLE | shardtest | range | idx_shardtest_03 | idx_shardtest_03 | 364 | NULL | 8 | Using where; Using index |
+------+-------------+-----------+-------+------------------+------------------+---------+------+------+--------------------------+
SELECT *
FROM shardtest use index(idx_shardtest_03)
WHERE name = 'key1‘
AND id between 1 and 6;
+----+------+
| id | name |
+----+------+
| 5 | key1 |
| 6 | key1 |
+----+------+
(select 0,`id`,`name`
from `log_db`.`shardTest`
where `id` >= 1 and `id` <= 6
and `name` = 'key1'
order by `id`,`name`
)
order by `id`,`name`
 What is Spider Engine?
 Architecture
 How to Create Spider Engine
 Limitation of a Spider Engine
 Guideline
 Q&A
Agenda
Schema
• Shard 별로 스키마 구성 (물리적으로 같은 위치에)
• 자동 증가값은 Spider Engine 에서 처리하도록 구성
• Global 스카마의 경우 HA 기능을 사용하여 각 서버에 복제본 구성
• Index 는, Data node 에는 전통적으로 필요한 index 생성
Spider node 에는 필요한 모든 컬럼 index 생성
Performance
• 각 Node에서 가장 성능이 나쁜 서버의 속도가 전체 성능을 결정한다.
(아쉽게도 각 Node에 Query를 parallel 하게 전달하지는 않는다.)
Query
• IN절과 ORDER BY 절은 최소화
• 조건절에 Filter 위치를 확실히 확인
• 설계 및 개발단계에 선반영 검토 (ex. 모든 쿼리에 Shard Key 조건을 추가하여 개발)
Guideline
 What is Spider Engine?
 Architecture
 How to Create Spider Engine
 Limitation of a Spider Engine
 Guideline
 Q&A
Agenda
Q & A
■ Spider_internal_limit
shard node에 레코드 LIMIT 제한을 준다.
■ Spider_internal_limit = 100
Query : SELECT * FROM shardtest limit 101
Node 2
Node 3
Node 4
Node 1
Q & A
■ Spider_internal_limit = 100
Query : SELECT * FROM shardtest order by id limit 101
Node 2 Node 3 Node 4Node 1
■ Spider_internal_limit = -1
Query : SELECT * FROM shardtest order by id limit 100
Node 2 Node 3 Node 4Node 1
Q & A
■ Spider_internal_limit = 100
Query : SELECT * FROM shardtest limit 1000
Node 2 Node 3 Node 4Node 1
■ 결과
Q & A
■ 스키마 변경은 각 노트에 상태와 무관한가?
Node 4
Shutdown
Spider Engine
Q & A
■ 스키마 변경은 각 노트에 상태와 무관한가?
Node4에 접속 불가
Q & A
■ 스키마 변경은 각 노트에 상태와 무관한가?
ALL Node
Shutdown
Q & A
■ Spider node에 shard_key Partition + 각 노드 Partition 구조 및 인덱스 설계 고려 사항이 있는가?
Node 2 Node 3 Node 4Node 1
CREATE TABLE `shardtest_key` (
`shard_key` int(11) DEFAULT NULL,
`shard_no` int(11) NOT NULL AUTO_INCREMENT,
Partkey_week INT,
`val` varchar(100) DEFAULT NULL,
PRIMARY KEY (`shard_no`,Partkey_week)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
/*!50100 PARTITION BY LIST (Partkey_week)
(PARTITION character_crud_log_P00 VALUES IN (0) ENGINE = InnoDB,
PARTITION character_crud_log_P01 VALUES IN (1) ENGINE = InnoDB,
PARTITION character_crud_log_P02 VALUES IN (2) ENGINE = InnoDB,
PARTITION character_crud_log_P03 VALUES IN (3) ENGINE = InnoDB,
PARTITION character_crud_log_P04 VALUES IN (4) ENGINE = InnoDB,
PARTITION character_crud_log_P05 VALUES IN (5) ENGINE = InnoDB) */;
Spider Engine
CREATE TABLE `shardtest_key` (
`shard_key` int(11) NOT NULL DEFAULT '0',
`shard_no` int(11) NOT NULL AUTO_INCREMENT,
Partkey_week int,
`val` varchar(100) DEFAULT NULL,
PRIMARY KEY (`shard_no`,shard_key, Partkey_week),
key (shard_key, Partkey_week)
) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "shardtest_key" '
/*!50100 PARTITION BY LIST (`shard_key`)
(PARTITION shard1 VALUES IN (1) COMMENT = 'srv "shard_node1"' ENGINE = SPIDER,
PARTITION shard3 VALUES IN (3) COMMENT = 'srv "shard_node3"' ENGINE = SPIDER,
PARTITION shard4 VALUES IN (4) COMMENT = 'srv "shard_node4"' ENGINE = SPIDER,
PARTITION shard2 VALUES IN (2) COMMENT = 'srv "shard_node2"' ENGINE = SPIDER) */
■ 결론
위에서 이야기 했던 것 처럼 각 노드에 필요한 조건이 모두 전달되려면 Spider에 인덱스가 존재해야 한다.
결국 partition을 제대로 사용하려면 spider 쪽에 (shard_key + Partition_key + 필요한 인덱스) 구조로 인덱스를 만들어야 한다.
Q & A
Spider Engine
Node 2 Node 3 Node 4Node 1
실행 계획
1,2,3
1,2,3
■ Spider node에 shard_key Partition + 각 노드 Partition 구조 및 인덱스 설계 고려 사항이 있는가?
Q & A
■ Spider 복제 구성에서 SELECT 되는 기준 노드는?
Spider Engine
Node 2
Node 3
Node 4
Node 1
Client
insert
insert
Client
select
select
Insert
부하
Insert & Select
부하
Q & A
■ Spider 복제 구성에서 SELECT 되는 기준 노드는?
Spider Engine
CREATE TABLE `common_tb` (
`ct_no` int(11) NOT NULL AUTO_INCREMENT,
`ct_code` char(4) DEFAULT NULL,
`ct_name` varchar(30) DEFAULT NULL,
`node_name` varchar(6),
PRIMARY KEY (`ct_no`),
KEY `ct_code` (`ct_code`)
) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "common_tb" '
/*!50100 PARTITION BY KEY (ct_no)
(PARTITION shard1 COMMENT = 'srv "shard_node1 shard_node2 shard_node3 shard_node4"' ENGINE = SPIDER) */
CREATE TABLE `common_tb` (
`ct_no` int(11) NOT NULL AUTO_INCREMENT,
`ct_code` char(4) DEFAULT NULL,
`ct_name` varchar(30) DEFAULT NULL,
`node_name` varchar(6) DEFAULT 'node4',
PRIMARY KEY (`ct_no`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
Node 1
Node 2
Node 3
Node 4
Node1, Node2, Node3, Node4
Q & A
■ Spider 복제 구성에서 SELECT 되는 기준 노드는?
Spider Engine
Node 1 Node 2 Node 3 Node 4
General_log
Deep Dive Spider Engine

More Related Content

PDF
Velocity 2015 linux perf tools
PDF
MySQL Spider Architecture
PDF
Transparent sharding with Spider: what's new and getting started
PDF
[2019] 200만 동접 게임을 위한 MySQL 샤딩
PDF
SR-IOV+KVM on Debian/Stable
PPT
Finite State Queries In Lucene
PPTX
HAProxy
PDF
PostgreSQL Deep Internal
Velocity 2015 linux perf tools
MySQL Spider Architecture
Transparent sharding with Spider: what's new and getting started
[2019] 200만 동접 게임을 위한 MySQL 샤딩
SR-IOV+KVM on Debian/Stable
Finite State Queries In Lucene
HAProxy
PostgreSQL Deep Internal

What's hot (20)

PDF
MongoDB WiredTiger Internals: Journey To Transactions
PDF
Introduction to MariaDB
PDF
5 Steps to PostgreSQL Performance
PDF
Redis persistence in practice
PDF
InnoDB MVCC Architecture (by 권건우)
PPTX
Apache Hive Tutorial
PPTX
mongodb와 mysql의 CRUD 연산의 성능 비교
PDF
MySQL GTID 시작하기
PPTX
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
PDF
스프링 시큐리티 구조 이해
PDF
The Great Debate: PostgreSQL vs MySQL
 
PDF
A Technical Introduction to WiredTiger
PPTX
Maria db 이중화구성_고민하기
PPTX
Open Source MANO(OSM)
PPT
Xampp Ppt
PDF
Zabbix Performance Tuning
PDF
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
PDF
PDF
DB Time, Average Active Sessions, and ASH Math - Oracle performance fundamentals
PDF
Apache Pig: A big data processor
MongoDB WiredTiger Internals: Journey To Transactions
Introduction to MariaDB
5 Steps to PostgreSQL Performance
Redis persistence in practice
InnoDB MVCC Architecture (by 권건우)
Apache Hive Tutorial
mongodb와 mysql의 CRUD 연산의 성능 비교
MySQL GTID 시작하기
Going Beyond Microsoft IIS Short File Name Disclosure - NahamCon 2023 Edition
스프링 시큐리티 구조 이해
The Great Debate: PostgreSQL vs MySQL
 
A Technical Introduction to WiredTiger
Maria db 이중화구성_고민하기
Open Source MANO(OSM)
Xampp Ppt
Zabbix Performance Tuning
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
DB Time, Average Active Sessions, and ASH Math - Oracle performance fundamentals
Apache Pig: A big data processor
Ad

Similar to Deep Dive Spider Engine (18)

PDF
Spider Setup with AWS/sandbox
PDF
M|18 How MariaDB Server Scales with Spider
PDF
Newest topic of spider 20131016 in Buenos Aires Argentina
PDF
Sharding with spider solutions 20160721
PDF
Amazed by aws 1st session
PDF
Oracle NoSQL
PDF
Oracle cloud data interface
PPTX
in-memory database system and low latency
PDF
Configuring workload-based storage and topologies
PPTX
Database storage engines
PPTX
MariaDB pres at LeMUG
PDF
Using spider for sharding in production
PDF
My sql cluster case study apr16
PDF
PostgreSQL 9.6 새 기능 소개
PPTX
SQream-GPU가속 초거대 정형데이타 분석용 SQL DB-제품소개-박문기@메가존클라우드
PPTX
What is persistence in java
PPTX
Postgres-BDR with Google Cloud Platform
PPTX
MySQL InnoDB Cluster 미리보기 (remote cluster test)
Spider Setup with AWS/sandbox
M|18 How MariaDB Server Scales with Spider
Newest topic of spider 20131016 in Buenos Aires Argentina
Sharding with spider solutions 20160721
Amazed by aws 1st session
Oracle NoSQL
Oracle cloud data interface
in-memory database system and low latency
Configuring workload-based storage and topologies
Database storage engines
MariaDB pres at LeMUG
Using spider for sharding in production
My sql cluster case study apr16
PostgreSQL 9.6 새 기능 소개
SQream-GPU가속 초거대 정형데이타 분석용 SQL DB-제품소개-박문기@메가존클라우드
What is persistence in java
Postgres-BDR with Google Cloud Platform
MySQL InnoDB Cluster 미리보기 (remote cluster test)
Ad

More from I Goo Lee (20)

PDF
MySQL_Fabric_운영시유의사항
PDF
MySQL Deep dive with FusionIO
PDF
From MSSQL to MySQL
PDF
From MSSQL to MariaDB
PDF
AWS Aurora 100% 활용하기
PDF
Backup automation in KAKAO
PDF
텔레그램을 이용한 양방향 모니터링 시스템 구축
PDF
Federated Engine 실무적용사례
PDF
MySQL 상태 메시지 분석 및 활용
PDF
MySQL 5.7 NF – Optimizer Improvement
PDF
MySQL 5.7 NF – JSON Datatype 활용
PDF
Intro KaKao MRTE (MySQL Realtime Traffic Emulator)
PDF
MS 빅데이터 서비스 및 게임사 PoC 사례 소개
PDF
AWS 환경에서 MySQL Infra 설계하기-2본론
PDF
AWS 환경에서 MySQL Infra 설계하기-1도입부분
PDF
AWS 환경에서 MySQL BMT
PDF
MySQL Slow Query log Monitoring using Beats & ELK
PDF
MySQL Audit using Percona audit plugin and ELK
PDF
PostgreSQL 이야기
PDF
Intro KaKao ADT (Almighty Data Transmitter)
MySQL_Fabric_운영시유의사항
MySQL Deep dive with FusionIO
From MSSQL to MySQL
From MSSQL to MariaDB
AWS Aurora 100% 활용하기
Backup automation in KAKAO
텔레그램을 이용한 양방향 모니터링 시스템 구축
Federated Engine 실무적용사례
MySQL 상태 메시지 분석 및 활용
MySQL 5.7 NF – Optimizer Improvement
MySQL 5.7 NF – JSON Datatype 활용
Intro KaKao MRTE (MySQL Realtime Traffic Emulator)
MS 빅데이터 서비스 및 게임사 PoC 사례 소개
AWS 환경에서 MySQL Infra 설계하기-2본론
AWS 환경에서 MySQL Infra 설계하기-1도입부분
AWS 환경에서 MySQL BMT
MySQL Slow Query log Monitoring using Beats & ELK
MySQL Audit using Percona audit plugin and ELK
PostgreSQL 이야기
Intro KaKao ADT (Almighty Data Transmitter)

Recently uploaded (20)

PPTX
Introduction to cybersecurity and digital nettiquette
PPTX
artificial intelligence overview of it and more
PDF
An introduction to the IFRS (ISSB) Stndards.pdf
PDF
The New Creative Director: How AI Tools for Social Media Content Creation Are...
PPTX
Introduction to Information and Communication Technology
PPTX
SAP Ariba Sourcing PPT for learning material
PPTX
E -tech empowerment technologies PowerPoint
PDF
Exploring VPS Hosting Trends for SMBs in 2025
PPTX
Power Point - Lesson 3_2.pptx grad school presentation
PPTX
artificialintelligenceai1-copy-210604123353.pptx
PDF
Vigrab.top – Online Tool for Downloading and Converting Social Media Videos a...
PPTX
INTERNET------BASICS-------UPDATED PPT PRESENTATION
PDF
Tenda Login Guide: Access Your Router in 5 Easy Steps
PPTX
Mathew Digital SEO Checklist Guidlines 2025
PDF
Unit-1 introduction to cyber security discuss about how to secure a system
PDF
Smart Home Technology for Health Monitoring (www.kiu.ac.ug)
PPT
isotopes_sddsadsaadasdasdasdasdsa1213.ppt
PPTX
June-4-Sermon-Powerpoint.pptx USE THIS FOR YOUR MOTIVATION
PDF
💰 𝐔𝐊𝐓𝐈 𝐊𝐄𝐌𝐄𝐍𝐀𝐍𝐆𝐀𝐍 𝐊𝐈𝐏𝐄𝐑𝟒𝐃 𝐇𝐀𝐑𝐈 𝐈𝐍𝐈 𝟐𝟎𝟐𝟓 💰
PPT
FIRE PREVENTION AND CONTROL PLAN- LUS.FM.MQ.OM.UTM.PLN.00014.ppt
Introduction to cybersecurity and digital nettiquette
artificial intelligence overview of it and more
An introduction to the IFRS (ISSB) Stndards.pdf
The New Creative Director: How AI Tools for Social Media Content Creation Are...
Introduction to Information and Communication Technology
SAP Ariba Sourcing PPT for learning material
E -tech empowerment technologies PowerPoint
Exploring VPS Hosting Trends for SMBs in 2025
Power Point - Lesson 3_2.pptx grad school presentation
artificialintelligenceai1-copy-210604123353.pptx
Vigrab.top – Online Tool for Downloading and Converting Social Media Videos a...
INTERNET------BASICS-------UPDATED PPT PRESENTATION
Tenda Login Guide: Access Your Router in 5 Easy Steps
Mathew Digital SEO Checklist Guidlines 2025
Unit-1 introduction to cyber security discuss about how to secure a system
Smart Home Technology for Health Monitoring (www.kiu.ac.ug)
isotopes_sddsadsaadasdasdasdasdsa1213.ppt
June-4-Sermon-Powerpoint.pptx USE THIS FOR YOUR MOTIVATION
💰 𝐔𝐊𝐓𝐈 𝐊𝐄𝐌𝐄𝐍𝐀𝐍𝐆𝐀𝐍 𝐊𝐈𝐏𝐄𝐑𝟒𝐃 𝐇𝐀𝐑𝐈 𝐈𝐍𝐈 𝟐𝟎𝟐𝟓 💰
FIRE PREVENTION AND CONTROL PLAN- LUS.FM.MQ.OM.UTM.PLN.00014.ppt

Deep Dive Spider Engine

  • 1. 1 Deep Dive Spider Engine 날짜 : 2016.03.21 Ver. 1.0 작성 : DB실 전수진
  • 2.  What is Spider Engine?  Architecture  How to Create Spider Engine  Limitation of a Spider Engine  Guideline  Q&A Agenda
  • 3.  What is Spider Engine?  Architecture  How to Create Spider Engine  Limitation of a Spider Engine  Guideline  Q&A Agenda
  • 4. What is Spider Engine ? http://spiderformysql.com/ https://mariadb.com/kb/en/mariadb/spider-storage-engine-overview/
  • 5. What is Spider Engine ? Image Source : http://barrymieny.deviantart.com/art/Database-104013446
  • 6. What is Spider Engine ? Spider Node 를 통해 하나의 DB 로 보임 Spider Node 는 데이터를 갖지않음
  • 7.  What is Spider Engine?  Architecture  How to Create Spider Engine  Limitation of a Spider Engine  Guideline  Q&A Agenda
  • 9. Architecture use mysql show tables like ‘spider%’ spider_link_failed_log : HA에서 사용되는 테이블로 스파이더에 구성된 노드가 에러가 발생하면 로그 기록 spider_link_mon_servers : HA에서 사용되는 테이블로 스파이더의 HA 모니터링하는 서버의 계정을 관리 spider_tables : 스파이더 엔진으로 구성된 테이블 리스트 출력 spider_xa : 서로 다른 노드에 분산 트랜잭션 관리 spider_xa_member : 서로 다른 노드에 분산 트랜잭션을 원격 관리하는 서버 정보 저장
  • 10.  What is Spider Engine?  Architecture  How to Create Spider Engine  Limitation of a Spider Engine  Guideline  Q&A Agenda
  • 11. ■ Step by Step 1. 서버 준비 Spider node Node 1 Node 2 Node 3 Node 4 ※ 5대 DB Server 준비 ① Spider Node (mariaDB 10.0.9) ② Data Node ⑴ MySQL 5.6.24 ⑵ MySQL 5.5.30 ⑶ MySQL 5.7.9 ⑷ mariaDB 10.0.4 How to Create Spider Engine
  • 12. ■ Step by Step 2-1. 아래 링크에서 스파이더 엔진 설치 파일을 받아 설치 2-2. 스파이더 엔진을 사용하기 위한 소스 적용 mysql -uroot -p < ../mariadb/share/install_spider.sql 2-3. 스파이더 엔진 설치 완료확인 SELECT engine, support, transactions, xa FROM information_schema.engines; https://mariadb.com/kb/en/mariadb/spider-storage-engine-overview/ +--------------------+---------+--------------+------+ | engine | support | transactions | xa | +--------------------+---------+--------------+------+ | SPIDER | YES | YES | YES | | CSV | YES | NO | NO | | MyISAM | YES | NO | NO | | BLACKHOLE | YES | NO | NO | | FEDERATED | YES | YES | NO | | MRG_MyISAM | YES | NO | NO | | ARCHIVE | YES | NO | NO | | MEMORY | YES | NO | NO | | PERFORMANCE_SCHEMA | YES | NO | NO | | Aria | YES | NO | NO | | InnoDB | DEFAULT | YES | YES | +--------------------+---------+--------------+------+ How to Create Spider Engine
  • 13. Spider Engine Node 1 (mysql 5.7.9) Node 2 (mysql 5.6.24) Node 3 (mysql 5.5.30) Node 4 (mariadb 10.0.4) Local Server Spider Table *.frm *.par File Remote Server Spider Table *.frm File Data (*.ibd) 192.168.124.134 192.168.124.137 192.168.124.138 192.168.124.139 192.168.124.140 Schema info (O) Partition info (O) Index data (X) How to Create Spider Engine ■ Step by Step II 1. 서버 준비
  • 14. Spider Engine 1. 원격서버 등록 sheard_node1 : 192.168.124.137 sheard_node2 : 192.168.124.138 sheard_node3 : 192.168.124.139 sheard_node4 : 192.168.124.140 CREATE SERVER shard_node1 FOREIGN DATA WRAPPER mysql OPTIONS( HOST '192.168.124.137', DATABASE 'log_db', USER 'root', PASSWORD '123qwe!@#', PORT 3306 ); CREATE SERVER shard_node4 FOREIGN DATA WRAPPER mysql OPTIONS( HOST '192.168.124.140', DATABASE 'log_db', USER 'root', PASSWORD '123qwe!@#', PORT 3306 ); ☞ Reference https://dev.mysql.com/doc/refman/5.7/en/create-server.html ... Spider node Node 1 Node 2 Node 3 Node 4 How to Create Spider Engine ■ Step by Step II
  • 15. CREATE TABLE log_db.shardTest ( id int unsigned NOT NULL AUTO_INCREMENT , name char(120) NOT NULL DEFAULT '' , PRIMARY KEY (id) ) ENGINE=spider COMMENT='wrapper "mysql", table "shardTest"' PARTITION BY KEY (id) ( PARTITION shard1 COMMENT = 'srv "shard_node1"' , PARTITION shard2 COMMENT = 'srv "shard_node2"' , PARTITION shard3 COMMENT = 'srv "shard_node3"' , PARTITION shard4 COMMENT = 'srv "shard_node4"' ) ; 2. Shard 테이블을 생성 1) 데이터가 저장될 실제 테이블 이름과 파티션 Key 값에 따라 저장될 원격 서버의 정보를 Comment 에 입력함 Spider node Node 1 Node 2 Node 3 Node 4 How to Create Spider Engine ■ Step by Step II Spider Engine
  • 16. Node 1 Node 2 Node 3 Node 4 CREATE TABLE log_db.shardTest ( id int unsigned NOT NULL AUTO_INCREMENT , name char(120) NOT NULL DEFAULT '' , PRIMARY KEY (id) ) ENGINE=innodb; Spider node Node 1 Node 2 Node 3 Node 4 How to Create Spider Engine ■ Step by Step II 3. 각 노드에 Data 테이블 생성
  • 17. insert into log_db.shardTest(name) values ('spider_01'); insert into log_db.shardTest(name) values ('spider_01'); insert into log_db.shardTest(name) values ('spider_01'); insert into log_db.shardTest(name) values ('spider_01'); select * from shardtest; +----+-----------+ | id | name | +----+-----------+ | 1 | spider_01 | | 4 | spider_01 | | 3 | spider_01 | | 2 | spider_01 | +----+-----------+ Spider node Node 1 Node 2 Node 3 Node 4 How to Create Spider Engine ■ Step by Step II 4. Spider 노드에서 데이터 입력 및 확인 Spider Engine
  • 18. Node 1 Node 2 Node 3 Node 4 select * from shardtest; +----+-----------+ | id | name | +----+-----------+ | 1 | spider_01 | +----+-----------+ select * from shardtest; +----+-----------+ | id | name | +----+-----------+ | 3 | spider_01 | +----+-----------+ select * from shardtest; +----+-----------+ | id | name | +----+-----------+ | 4 | spider_01 | +----+-----------+ select * from shardtest; +----+-----------+ | id | name | +----+-----------+ | 2 | spider_01 | +----+-----------+ Spider node Node 1 Node 2 Node 3 Node 4 How to Create Spider Engine ■ Step by Step II 5. 각 Data 노드에서 데이터 확인 1) 데이터가 잘 분산 됐는지 체크
  • 19. Spider node Node 1 Node 2 Node 3 Node 4 CREATE TABLE shardTest_node1(id int unsigned NOT NULL AUTO_INCREMENT,name char(120) NOT NULL DEFAULT '',PRIMARY KEY (id) ) ENGINE=FEDERATED CONNECTION='shard_node1/shardTest'; CREATE TABLE shardTest_node2(id int unsigned NOT NULL AUTO_INCREMENT,name char(120) NOT NULL DEFAULT '',PRIMARY KEY (id) ) ENGINE=FEDERATED CONNECTION='shard_node2/shardTest'; CREATE TABLE shardTest_node3(id int unsigned NOT NULL AUTO_INCREMENT,name char(120) NOT NULL DEFAULT '',PRIMARY KEY (id) ) ENGINE=FEDERATED CONNECTION='shard_node3/shardTest'; CREATE TABLE shardTest_node4(id int unsigned NOT NULL AUTO_INCREMENT,name char(120) NOT NULL DEFAULT '',PRIMARY KEY (id) ) ENGINE=FEDERATED CONNECTION='shard_node4/shardTest'; How to Create Spider Engine ■ Step by Step II Spider Engine 0. 테스트를 위해 FEDERATED Table 구성
  • 20. [localhost] ((none)) 06:31> show storage engines; +--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+ | Engine | Support | Comment | Transactions | XA | Savepoints | +--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+ | SPIDER | YES | Spider storage engine | YES | YES | NO | | MRG_MyISAM | YES | Collection of identical MyISAM tables | NO | NO | NO | | MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO | | BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO | | MyISAM | YES | MyISAM storage engine | NO | NO | NO | | InnoDB | DEFAULT | Percona-XtraDB, Supports transactions, row-level locking, and foreign keys | YES | YES | YES | | ARCHIVE | YES | Archive storage engine | NO | NO | NO | | FEDERATED | NO | FederatedX pluggable storage engine | NULL | NULL | NULL | | PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO | | Aria | YES | Crash-safe tables with MyISAM heritage | NO | NO | NO | | CSV | YES | CSV storage engine | NO | NO | NO | +--------------------+---------+----------------------------------------------------------------------------+--------------+------+------------+ CREATE TABLE log_db.shardTest ( id int(10) unsigned NOT NULL AUTO_INCREMENT , name char(120) NOT NULL DEFAULT '' , PRIMARY KEY (id) ) ENGINE=spider COMMENT='wrapper "mysql", table "shardTest"' PARTITION BY KEY (id) ( PARTITION shard1 COMMENT = 'srv "shard_node1"' , PARTITION shard2 COMMENT = 'srv "shard_node2"' , PARTITION shard3 COMMENT = 'srv "shard_node3"' , PARTITION shard4 COMMENT = 'srv "shard_node4"' ) ; SELECT * FROM log_db.shardtest; +----+-----------+ | id | name | +----+-----------+ | 1 | SPIDER_01 | | 5 | key1 | | 4 | SPIDER_01 | … | 6 | key1 | +----+-----------+ (원격데이터 정상추출) 결론 : FEDERATED 와 SPIDER ENGINES 간의 의존성 없슴! How to Create Spider Engine Q. Spider Engine 이 Federated Engine 과 의존성이 있는 것은 아닐까? (FEDERATED STORAGE ENGINES OFF?)
  • 21. How to Create Spider Engine ■ spider_internal_sql_log_off shard된 서버에 spider 엔진에서 보낸 Query를 general log 기록합니다. 구문 (show table status from `log_db` like 'v_shardtest_group‘) (show index from `log_db`.`v_shardtest_group`) ■ spider_remote_sql_log_off shard된 서버에 sql_log_off 를 설정합니다. 구문 (set session sql_log_off = 1; )
  • 22.  What is Spider Engine?  Architecture  How to Create Spider Engine  Limitation of a Spider Engine  Guideline  Q&A Agenda
  • 23. Spider Engine insert into shardtest(name) values ('spider_01'); Node 1 root@192.168.124.137 on using TCP/IP set session transaction isolation level read committed; set session autocommit = 1; start transaction SET NAMES utf8 log_db select `id`,`name` from `log_db`.`shardTest`order by `id` desc limit 1 for update insert into `log_db`.`shardTest`(`id`,`name`)values(5,'spider_01') commit Node 2 Node 3 Node 4 select `id`,`name` from `log_db`.`shardTest` order by `id` desc limit 1 for update UPDATE Lock? UPDATE Lock? Limitation of a Spider Engine 1. INSERT (Auto Increment 발번)
  • 24. Spider Engine Node 1 Node 2 Node 3 Node 4 Limitation of a Spider Engine 1. INSERT (Auto Increment 발번) Auto_increment = 1 insert into shardtest(name) values ('spider_01'); select `id`,`name` from `log_db`.`shardTest`order by `id` desc limit 1 for update 각 노드 Auto_increment MAX 확인 Auto_increment = 2 노드 선택 insert into shardtest(id,name) values (1,'spider_01'); insert into shardtest(id,name) values (1,'spider_01'); Auto_increment = 2 insert into shardtest(name) values ('spider_02'); Node 1 select `id`,`name` from `log_db`.`shardTest`order by `id` desc limit 1 for update 각 노드 Auto_increment MAX 확인 Auto_increment = 3 노드 선택 insert into shardtest(id,name) values (2,'spider_01'); Node 3 insert into shardtest(id,name) values (2,'spider_01'); Node 1 Node 2 Node 3 Node 4
  • 25. Limitation of a Spider Engine ■ spider_auto_increment_mode -1 : 테이블 매개 변수를 사용한다. 0 : 일반모드 자동 증가 값을 원격 서버에서 얻은 카운터를 사용한다. 1 : Quick 모드 자동 증가 값을 Spider Node 내부 카운터를 사용한다. 2 : Set Zero Value 자동 증가 값을 Data Node 내부 카운터를 사용한다. 3 : null 입력시 자동 증가 값은 원격 서버에서 생성 0을 입력하면 로컬 서버에서 생성 1. INSERT (Auto Increment 발번) ☞ Reference https://mariadb.com/kb/en/mariadb/spider-server-system-variables/
  • 26. Node 3Node 2Node 1 Node 4 Limitation of a Spider Engine Spider Engine set spider_auto_increment_mode = 1; insert into shardtest(name) values ('spider_01'); root@192.168.124.137 on using TCP/IP set session transaction isolation level read committed; set session autocommit = 1; start transaction SET NAMES utf8 log_db insert into `log_db`.`shardTest`(`id`,`name`)values(6,'spider_01') commit 1. INSERT (Auto Increment 발번)
  • 27. Limitation of a Spider Engine 1) spider_auto_increment_mode 설정별 성능 spider_auto_increment_mode QPS AVG Query sec 0 Avg : 45 0.021 1 Avg : 185 0.005 2 Avg : 184 0.005 1. INSERT (Auto Increment 발번)
  • 28. Limitation of a Spider Engine 2) spider_auto_increment_mode = 0 문제 발생 1. INSERT (Auto Increment 발번) 응답이 없음 Spider Engine ?
  • 29. Limitation of a Spider Engine 2) spider_auto_increment_mode = 0 문제 발생 1. INSERT (Auto Increment 발번) Node 1 Node 2 Node 3 Node 4 Commit 이 없음
  • 30. Limitation of a Spider Engine 2) spider_auto_increment_mode = 0 문제 발생 1. INSERT (Auto Increment 발번) Node 1 Node 2 Node 3 Node 4 general_log Commit ( X )
  • 31. Spider Engine Node 1 update shardtest set id = 9 where id = 8; (select 0,`id`,`name` from `log_db`.`shardTest` where `id` = 8 for update) delete from `log_db`.`shardTest` where `id` = 8 and `name` = 'spider_01' limit 1 insert high_priority into `log_db`.`shardTest`(`id`,`name`)values(9,'spider_01') Data Move Data Move Node 1Node 4 Data move CREATE TABLE `shardtest` ( ... ) ENGINE=SPIDER AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "shardTest" ' Limitation of a Spider Engine 2. Update (Shard Key Update) Change Auto increment Node 4
  • 32. Spider Engine update shardtest set id = 9 where id = 8; (select 0,`id`,`name` from `log_db`.`shardTest` where `id` = 8 for update) delete from `log_db`.`shardTest` where `id` = 8 and `name` = 'spider_01' limit 1 insert high_priority into `log_db`.`shardTest`(`id`,`name`)values(9,'spider_01') update shardtest set id = 17 where id = 9; (select 0,`id`,`name` from `log_db`.`shardTest` where `id` = 9 for update) update `shardTest` set `id` = 17 where `id` = 9 and `name` = 'spider_01' limit 1 Node 1Spider Engine CREATE TABLE `shardtest` ( ... ) ENGINE=SPIDER AUTO_INCREMENT=18 DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "shardTest" ' Node 1 Data move CREATE TABLE `shardtest` ( ... ) ENGINE=SPIDER AUTO_INCREMENT=10 DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "shardTest" ' Change Auto increment Limitation of a Spider Engine 2. Update (Shard Key Update) Node 1Node 4 Data move Change Auto increment Node 1 Node 4 Data Move Data Move
  • 33. Node 1 update shardtest set name = 'spider_02' where id = 1; update shardtest set name = 'spider_03' where name = 'spider_01'; Spider Engine (select 0,`id`,`name` from `log_db`.`shardTest` where `id` = 1 for update) update `log_db`.`shardTest` set `name` = 'spider_02' where `id` = 1 limit 1 update `log_db`.`shardTest` set `name` = 'spider_03' where `id` = 2 and `name` = 'spider_01' limit 1 (select 0,`id`,`name` from `log_db`.`shardTest` where `name` = 'spider_01' for update) Node 2 Node 3 Node 4 Node 2 Node 3 Node 4 Shard key (X) Node 1 Limitation of a Spider Engine 2. Update (Shard Key 가 아닌 컬럼의 Update) Spider Engine Node 3
  • 34. update shardtest set name = 'spider_01' where name = 'spider_02'; Spider Engine update `log_db`.`shardTest` set `name` = 'spider_01' where `id` = 1 and `name` = 'spider_02' limit 1 update `log_db`.`shardTest` set `name` = 'spider_01' where `id` = 13 and `name` = 'spider_02' limit 1 (select 0,`id`,`name` from `log_db`.`shardTest` where `name` = 'spider_02' for update) Shard key (X) 1 건 업데이트 Limitation of a Spider Engine 2. Update (Shard Key 가 아닌 컬럼의 Update) update shardtest set name = 'spider_03' where name = 'spider_01'; Node 1 Spider Engine update `log_db`.`shardTest` set `name` = 'spider_03' where `id` = 1 and `name` = 'spider_01' limit 1 (select 0,`id`,`name` from `log_db`.`shardTest` where `name` = 'spider_01' for update) Node 2 Node 3 Node 4 Shard key (X) Node 1 여러 건 업데이트 Node 1 Node 2 Node 3 Node 4Node 1 1건씩 처리됨 ⇒ 운영시 binlog size 급증 이슈발생가능!
  • 35. Truncate table shardTest; truncate table `log_db`.`shardTest` Limitation of a Spider Engine 3. Truncate Spider Engine Node 2 Node 3 Node 4Node 1
  • 36. Alter table shardTest ADD COLUMN TEST_Col1 int; Alter table shardTest DROP COLUMN TEST_Col1 int; CREATE INDEX idx_shardtest ON shardtest(name); DROP INDEX idx_shardtest ON shardtest; Shard Shema 변경 없음 Limitation of a Spider Engine 4. Alter Spider Engine Node 2 Node 3 Node 4Node 1
  • 37. Shard Shema 변경 없음 Alter table shardtest ADD COLUMN (add_col1 int); SELECT * FROM shardtest; (ERROR 1054 (42S22): Unknown column 'add_col1' in 'field list‘) SELECT id, name FROM shardtest; +----+-----------+ | id | name | +----+-----------+ | 1 | SPIDER_01 | … | 2 | SPIDER_01 | +----+-----------+ 4 rows in set (0.26 sec) select `id`,`name` from `log_db`.`shardTest` order by `id`,`name` General_log Query Limitation of a Spider Engine 4. Alter Spider Engine Node 2 Node 3 Node 4Node 1
  • 38. Shard Shema 변경 없음 Alter table shardtest ADD COLUMN (add_col1 int); Limitation of a Spider Engine 4. Alter Spider Engine Node 2 Node 3 Node 4Node 1 INSERT INTO shardtest(name) VALUES('key2'); Query OK, 1 row affected (0.45 sec) select id, name from shardtest; +----+-----------+ | id | name | +----+-----------+ | 1 | SPIDER_01 | | 2 | SPIDER_01 | | … | | 5 | key2 | +----+-----------+ UPDATE shardtest set name = 'key3' where id = 5; ERROR 1054 (42S22): Unknown column 'add_col1' in 'field list' insert into `log_db`.`shardTest`(`id`,`name`) values (5,'key2') (select 0,`id`,`name`,`add_col1` from `shardTest` where `id` = 5 for update) rollback General_log Query
  • 39. Alter table shardtest DROP COLUMN (add_col1 int); Limitation of a Spider Engine 4. Alter Spider Engine Node 2 Node 3 Node 4Node 1 General_log Query select * from shardtest; +----+-----------+ | id | name | +----+-----------+ | 1 | SPIDER_01 | | 2 | SPIDER_01 | | 3 | SPIDER_01 | | 4 | SPIDER_01 | | 5 | key1 | | 6 | key1 | | 7 | SPIDER_01 | | 8 | SPIDER_01 | +----+-----------+ Select OK Alter table shardtest ADD COLUMN (add_col1 int); (각 Data 노드에 컬럼추가) select `id`,`name` from `log_db`.`shardTest` order by `id`,`name` ※ Schema 수정 순서에 유의 1) Data node 수정 2) Spider node 수정
  • 40. select `id`,`name` from `log_db`.`shardTest`select * from shardtest; +----+-----------+ | id | name | +----+-----------+ | 1 | spider_01 | -- shard1 | 4 | spider_01 | -- shard2 | 3 | spider_01 | -- shard3 | 2 | spider_01 | -- shard4 +----+-----------+ select `id`,`name` from `log_db`.`shardTest` select * from shardtest order by id; +----+-----------+ | id | name | +----+-----------+ | 1 | spider_01 | -- shard1 | 2 | spider_01 | -- shard4 | 3 | spider_01 | -- shard3 | 4 | spider_01 | -- shard2 +----+-----------+ Limitation of a Spider Engine 5. SELECT (order by) Spider Engine Node 2 Node 3 Node 4Node 1 PK 순서 ( X ) Spider Node 에서 Sort 발생
  • 41. Spider Node “Sort buffer size” 설정에 따른 성능테스트 약 100만 row TEST +-----+--------------+-------------+ | int | varchar(120) | varchar(10) | +-----+--------------+-------------+ | id | name | node_num | +-----+--------------+-------------+ | 1 | aaa | node1 | +-----+--------------+-------------+ TEST QUERY select * from shardtest order by id; Variables (sort_buffer_size) avg retun time 256K 16.612 512K 12.76 1M 10.562 2M 9.988 4M 7.812 8M 7.93 16M 7.508 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 256K 512K 1M 2M 4M 8M 16M avg retun time Limitation of a Spider Engine 5. SELECT (order by)
  • 42. File Sort Algorithm 1. Single Pass  SELECT되는 모든 컬럼 버퍼에 담아 정렬하여 바로 리턴 2. Two Pass  정렬 대상 + KEY로 정렬 하여 해당 정렬 기준으 로 KEY값 리턴 ※ Two Pass는 정렬을 위하여 temp file을 사용한다. Sort_merge_passes는 Merge 횟수를 카운트 한다. 약 100만 row TEST +-----+--------------+-------------+ | int | varchar(120) | varchar(10) | +-----+--------------+-------------+ | id | name | node_num | +-----+--------------+-------------+ | 1 | aaa | node1 | +-----+--------------+-------------+ TEST QUERY select * from shardtest order by id; Variables (sort_buffer_size) avg retun time 256K 16.612 512K 12.76 1M 10.562 2M 9.988 4M 7.812 8M 7.93 16M 7.508 Limitation of a Spider Engine 5. SELECT (order by) 상태 확인 : show status like ‘%sort%’
  • 43. INSERT INTO shardtest(name) values('SPIDER_01'); … INSERT INTO shardtest(name) values('SPIDER_04’); INSERT INTO shardtest(name) values('key1'); select `id`,`name` from `log_db`.`shardTest`SELECT * FROM shardtest where name = 'key1'; +----+------+ | id | name | +----+------+ | 5 | key1 | +----+------+ Spider Engine Filtering Shard DB Filter ? ? Limitation of a Spider Engine 5. SELECT (where) Spider Engine Node 2 Node 3 Node 4Node 1 CREATE TABLE `shardtest` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` char(120) NOT NULL DEFAULT '', PRIMARY KEY (`id`), ) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "shardTest" ' /*!50100 PARTITION BY KEY (`id`) (PARTITION shard1 COMMENT = 'srv "shard_node1" ' ENGINE = SPIDER, … PARTITION shard4 COMMENT = 'srv "shard_node4" ' ENGINE = SPIDER) */
  • 44. select `id`,`name` from `log_db`.`shardTest` where `name` = 'key1' Shard DB Filtering !!! CREATE INDEX idx_shardtest_01 ON shardtest(name); SELECT * FROM shardtest where name = 'key1'; +----+------+ | id | name | +----+------+ | 5 | key1 | +----+------+ CREATE TABLE `shardtest` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` char(120) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `idx_shardtest_01` (`name`) ) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "shardTest" ' /*!50100 PARTITION BY KEY (`id`) (PARTITION shard1 COMMENT = 'srv "shard_node1" ' ENGINE = SPIDER, PARTITION shard2 COMMENT = 'srv "shard_node2" ' ENGINE = SPIDER, PARTITION shard3 COMMENT = 'srv "shard_node3" ' ENGINE = SPIDER, PARTITION shard4 COMMENT = 'srv "shard_node4" ' ENGINE = SPIDER) */ Limitation of a Spider Engine 5. SELECT (where) Spider Engine Node 2 Node 3 Node 4Node 1
  • 45. select name from shardtest group by name; KEY `idx_shardtest_01` (`name`) 있는 상태 select count(*) from `log_db`.`shardTest` select `name` from `log_db`.`shardTest` order by `name` desc select `name` from `log_db`.`shardTest` order by `name` select `name` from `log_db`.`shardTest` where `name` > 'key1' order by `name` select `name` from `log_db`.`shardTest` where `name` > 'SPIDER_01' order by `name` +-----------+ | name | +-----------+ | key1 | | SPIDER_01 | +-----------+ KEY `idx_shardtest_01` (`name`) 를 제거하면… DROP INDEX idx_shardtest_01 ON shardtest; select name from shardtest group by name; +-----------+ | name | +-----------+ | key1 | | SPIDER_01 | +-----------+ select `name` from `log_db`.`shardTest` Shard DB Grouping?? Limitation of a Spider Engine Spider Engine Node 2 Node 3 Node 4Node 1 5. SELECT (Group By) Shard DB Full ScanShard DB Grouping
  • 46. select id from shardtest group by name; +----+ | id | +----+ | 5 | | 1 | +----+ Shard DB Sorting select `id`,`name` from `log_db`.`shardTest` order by `name` Shard DB Grouping select name, count(*) from shardtest group by name; +-----------+----------+ | name | count(*) | +-----------+----------+ | key1 | 2 | | SPIDER_01 | 6 | +-----------+----------+ select `name` from `log_db`.`shardTest` order by `name` select count(*) from `log_db`.`shardTest` select count(*) from `log_db`.`shardTest` ? Limitation of a Spider Engine 5. SELECT (Group By) Spider Engine Node 2 Node 3 Node 4Node 1
  • 47. CREATE TABLE `shardtest` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` char(120) NOT NULL DEFAULT '', `node_num` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1048576 DEFAULT CHARSET=utf8 Limitation of a Spider Engine 5. SELECT (Group By MIN, MAX, COUNT(*) {INDEX (O)}) Spider Engine Node 2 Node 3 Node 4Node 1 select max(id) from shardtest; select min(id) from shardtest; select count(id) from shardtest; select count(*) from shardtest; select name, min(id) from shardtest; select name, max(id) from shardtest; select name, count(*) from shardtest; select name, count(id) from shardtest; select `id` from `log_db`.`shardTest` order by `id` desc limit 1; select `id` from `log_db`.`shardTest` order by `id` limit 1; select count(*) from `log_db`.`shardTest`; select count(*) from `log_db`.`shardTest`; select `id`,`name` from `log_db`.`shardTest` order by `id`,`name`; select `id`,`name` from `log_db`.`shardTest` order by `id`,`name`; select `name` from `log_db`.`shardTest` order by `name`; select `id`,`name` from `log_db`.`shardTest` order by `id`,`name`; “Name” index (X) CREATE TABLE `shardtest` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` char(120) NOT NULL DEFAULT '', `node_num` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`), KEY `idx_shardtest_01` (`name`), KEY `idx_shardtest_02` (`id`,`name`) ) …
  • 48. Limitation of a Spider Engine 5. SELECT (Group By MIN, MAX, COUNT(*) {INDEX (X)}) Spider Engine Node 2 Node 3 Node 4Node 1 select max(name) from shardtest; select min(name) from shardtest; select count(name) from shardtest; select count(*) from shardtest; select name, min(id) from shardtest; select name, max(id) from shardtest; select name, count(*) from shardtest; select name, count(id) from shardtest; select `name` from `log_db`.`shardTest`; select `name` from `log_db`.`shardTest`; select count(*) from `log_db`.`shardTest`; select count(*) from `log_db`.`shardTest`; select `id`,`name` from `log_db`.`shardTest`; select `id`,`name` from `log_db`.`shardTest`; select `id`,`name` from `log_db`.`shardTest`; select `id`,`name` from `log_db`.`shardTest`; CREATE TABLE `shardtest` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` char(120) NOT NULL DEFAULT '', `node_num` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1048576 DEFAULT CHARSET=utf8 CREATE TABLE `shardtest` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` char(120) NOT NULL DEFAULT '', `node_num` varchar(10) DEFAULT NULL, PRIMARY KEY (`id`) ) … Full Scan
  • 49. CREATE VIEW v_shardtest_group AS select name, max(id) as id, count(*) as cnt from shardtest group by name; CREATE TABLE `v_shardtest_group` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `name` CHAR(120) NOT NULL DEFAULT '', `cnt` INT NOT NULL, PRIMARY KEY (`id`), KEY `idx_shardtest_01` (`name`) ) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "v_shardtest_group" ' /*!50100 PARTITION BY KEY (`id`) (PARTITION shard1 COMMENT = 'srv "shard_node1"' ENGINE = SPIDER, PARTITION shard2 COMMENT = 'srv "shard_node2"' ENGINE = SPIDER, PARTITION shard3 COMMENT = 'srv "shard_node3"' ENGINE = SPIDER, PARTITION shard4 COMMENT = 'srv "shard_node4"' ENGINE = SPIDER) */ ; select name, sum(cnt) from v_shardtest_group group by name; select `name`,`cnt` from `log_db`.`v_shardtest_group` order by `name` Limitation of a Spider Engine 5. SELECT (Group By) Spider Engine Node 2 Node 3 Node 4Node 1
  • 50. select * from shardtest order by id; select * from shardtest order by name; select id from shardtest order by id; select name from shardtest order by id; select id from shardtest order by name; select name from shardtest order by name; Limitation of a Spider Engine 5. SELECT (Order By) Spider Engine Node 2 Node 3 Node 4Node 1 select `id`,`name` from `log_db`.`shardTest` select `id`,`name` from `log_db`.`shardTest` select count(*) from `log_db`.`shardTest` select `id` from `log_db`.`shardTest` order by `id` select `id`,`name` from `log_db`.`shardTest` select `id`,`name` from `log_db`.`shardTest` select count(*) from `log_db`.`shardTest` select `name` from `log_db`.`shardTest` order by `name` Shard DB DataSpider DB Sorting
  • 51. create table join_tb( jt_no int auto_increment , ct_code char(4) , ct_cnt int , primary key(jt_no) ); create table common_tb( ct_no int auto_increment , ct_code char(4) , ct_name varchar(30) , primary key (ct_no) , key (ct_code) ) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "common_tb" ' /*!50100 PARTITION BY KEY (ct_no) (PARTITION shard1 COMMENT = 'srv "shard_node1"' ENGINE = SPIDER) */ create table join_tb( jt_no int auto_increment , ct_ code char(4) , ct_ cnt int , primary key(jt_no) ) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "join_tb" ' /*!50100 PARTITION BY KEY (`jt_no`) (PARTITION shard1 COMMENT = 'srv "shard_node1"' ENGINE = SPIDER, PARTITION shard2 COMMENT = 'srv "shard_node2"' ENGINE = SPIDER, PARTITION shard3 COMMENT = 'srv "shard_node3"' ENGINE = SPIDER, PARTITION shard4 COMMENT = 'srv "shard_node4"' ENGINE = SPIDER) */ create table common_tb( ct_no int auto_increment , ct_code char(4) , ct_name varchar(30) , primary key (ct_no) ); Limitation of a Spider Engine 5. SELECT (Join) Spider Engine Node 1 Node 2 Node 3 Node 4Node 1
  • 52. insert into join_tb(ct_code, ct_cnt) values ('A001',1); insert into join_tb(ct_code, ct_cnt) values ('A002',2); insert into join_tb(ct_code, ct_cnt) values ('A003',3); … insert into join_tb(ct_code, ct_cnt) values ('A009',49); insert into join_tb(ct_code, ct_cnt) values ('A010',50); insert into common_tb(ct_code, ct_name) values ('A001','TEST1'); insert into common_tb(ct_code, ct_name) values ('A002','TEST2'); insert into common_tb(ct_code, ct_name) values ('A003','TEST3'); … insert into common_tb(ct_code, ct_name) values ('A011','TEST11'); insert into common_tb(ct_code, ct_name) values ('A012','TEST12'); insert into common_tb(ct_code, ct_name) values ('A013','TEST13'); select a.ct_cnt, a.ct_code, b.ct_name from join_tb a , common_tb b where a.ct_code = b.ct_code; select `ct_code`,`ct_cnt` from `log_db`.`join_tb` select `ct_code`,`ct_name` from `log_db`.`common_tb` where `ct_code` = 'A010' select `ct_code`,`ct_name` from `log_db`.`common_tb` where `ct_code` = 'A006' select `ct_code`,`ct_name` from `log_db`.`common_tb` where `ct_code` = 'A012' … select `ct_code`,`ct_name` from `log_db`.`common_tb` where `ct_code` = 'A007' select `ct_code`,`ct_name` from `log_db`.`common_tb` where `ct_code` = 'A013' select `ct_code`,`ct_name` from `log_db`.`common_tb` where `ct_code` = 'A009' … Limitation of a Spider Engine 5. SELECT (Join) Spider Engine Node 2 Node 3 Node 4Node 1 join_tb common_tb join_tb join_tb join_tb 1단계 : join_tb 데이터 스캔 2단계 : 1단계에서 읽은 데이터를 대상 으로 common_tb 데이터 확인
  • 53. Spider Engine Node 1 join Node 2 join Node 3 join Node 4 join Spider Engine join Node 1 Node 2 Node 3 Node 4 Limitation of a Spider Engine 5. SELECT (Join)
  • 54. Insert common_tb common_tb DATA common_tb DATA common_tb DATA common_tb DATA ? Global table Join View View ? Limitation of a Spider Engine 5. SELECT (Join) Node 2 Node 3 Node 4Node 1 Spider Engine Node 2 Node 3 Node 4Node 1
  • 55. alter table common_tb COMMENT='wrapper "mysql", table "common_tb" ' /*!50100 PARTITION BY KEY (ct_no) (PARTITION shard1 COMMENT = 'srv "shard_node2 shard_node3 shard_node4 shard_node1"' ENGINE = SPIDER) */ TRUNCATE TABLE common_tb; insert into common_tb(ct_code, ct_name) values ('A001','TEST1'); insert into common_tb(ct_code, ct_name) values ('A002','TEST2'); insert into common_tb(ct_code, ct_name) values ('A003','TEST3'); … insert into common_tb(ct_code, ct_name) values ('A011','TEST11'); insert into common_tb(ct_code, ct_name) values ('A012','TEST12'); insert into common_tb(ct_code, ct_name) values ('A013','TEST13'); insert into `common_tb`(`ct_no`,`ct_code`,`ct_name`)values(1,'A001','TEST01') insert into `common_tb`(`ct_no`,`ct_code`,`ct_name`)values(2,'A002','TEST02') insert into `common_tb`(`ct_no`,`ct_code`,`ct_name`)values(3,'A003','TEST03') … insert into `common_tb`(`ct_no`,`ct_code`,`ct_name`)values(11,'A011','TEST11') insert into `common_tb`(`ct_no`,`ct_code`,`ct_name`)values(12,'A012','TEST12') insert into `common_tb`(`ct_no`,`ct_code`,`ct_name`)values(13,'A013','TEST13') Limitation of a Spider Engine 5. SELECT (Join) Spider Engine Node 2 Node 3 Node 4Node 1
  • 56. CREATE ALGORITHM = MERGE VIEW v_join_tb as select a.jt_no, a.ct_cnt, a.ct_code a_ct_code, b.ct_code b_ct_code, b.ct_name from join_tb a , common_tb b where a.ct_code = b.ct_code; CREATE TABLE v_join_tb( jt_no int , ct_cnt int , a_ct_code char(4) , b_ct_code char(4) , ct_name varchar(30) , primary key (jt_no) , key (a_ct_code, b_ct_code) ) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "v_join_tb" ' /*!50100 PARTITION BY KEY (`jt_no`) (PARTITION shard1 COMMENT = 'srv "shard_node1"' ENGINE = SPIDER, .. PARTITION shard4 COMMENT = 'srv "shard_node4"' ENGINE = SPIDER) */; select * from v_join_tb where a_ct_code = 'A001' and b_ct_code = 'A001'; select `jt_no`,`ct_cnt`,`a_ct_code`,`b_ct_code`,`ct_name` from `log_db`.`v_join_tb` where `a_ct_code` = 'A001' and `b_ct_code` = 'A001' Key Point !! Limitation of a Spider Engine 5. SELECT (Join) Spider Engine Node 2 Node 3 Node 4Node 1 CREATE VIEW ALGORITHM 1) MERGE 2) TEMPTABLE
  • 57. select * from v_join_tb where a_ct_code = 'A001’and b_ct_code = 'A001'; select `jt_no`,`ct_cnt`,`a_ct_code`,`b_ct_code`,`ct_name` from `log_db`.`v_join_tb` where `a_ct_code` = 'A001' and `b_ct_code` = 'A001' Limitation of a Spider Engine 5. SELECT (Join) Spider Engine Node 2 Node 3 Node 4Node 1 INDEX Access OK !
  • 58. SELECT * FROM shardtest WHERE name IN ('key1','SPIDER_01'); +----+-----------+ | id | name | +----+-----------+ | 1 | SPIDER_01 | | 5 | key1 | | 4 | SPIDER_01 | | 8 | SPIDER_01 | | 3 | SPIDER_01 | | 7 | SPIDER_01 | | 2 | SPIDER_01 | | 6 | key1 | +----+-----------+ Temporary Table ← IN KEY ? Spider Engine Node 2 Node 3 Node 4Node 1 Limitation of a Spider Engine 5. SELECT ( IN( ) ) drop temporary table if exists log_db.tmp_spider_bka_0x7f5ba7f23420_shardTest; create temporary table log_db.tmp_spider_bka_0x7f5ba7f23420_shardTest( id bigint , c0 char(120) collate utf8_general_ci ) engine=memory default charset=utf8 collate utf8_general_ci; insert into log_db.tmp_spider_bka_0x7f5ba7f23420_shardTest(id,c0)values(0,'key1'),(1,'SPIDER_01'); select a.id,b.`id`,b.`name` from log_db.tmp_spider_bka_0x7f5ba7f23420_shardTest a,`log_db`.`shardTest` b where a.c0 <=> b.`name`; drop temporary table if exists log_db.tmp_spider_bka_0x7f5ba7f23420_shardTest; OR equal
  • 59. Spider Engine Node 2 Node 3 Node 4Node 1 Limitation of a Spider Engine 5. SELECT ( IN( ) ) SELECT * FROM shardtest WHERE name = 'key1' UNION ALL SELECT * FROM shardtest WHERE name = 'SPIDER_01'; +----+-----------+ | id | name | +----+-----------+ | 5 | key1 | | 6 | key1 | | 1 | SPIDER_01 | | 4 | SPIDER_01 | | 8 | SPIDER_01 | | 3 | SPIDER_01 | | 7 | SPIDER_01 | | 2 | SPIDER_01 | +----+-----------+ select `id`,`name` from `log_db`.`shardTest` where `name` = 'SPIDER_01' select `id`,`name` from `log_db`.`shardTest` where `name` = 'key1'
  • 60. create table shardtest_key ( shard_key int , shard_no int NOT NULL AUTO_INCREMENT , val varchar(100) , PRIMARY KEY (shard_no, shard_key) ) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "shardtest_key" ' /*!50100 PARTITION BY LIST (`shard_key`) (PARTITION shard1 VALUES IN (1) COMMENT = 'srv "shard_node1"' ENGINE = SPIDER, PARTITION shard3 VALUES IN (3) COMMENT = 'srv "shard_node3"' ENGINE = SPIDER, PARTITION shard4 VALUES IN (4) COMMENT = 'srv "shard_node4"' ENGINE = SPIDER, PARTITION shard2 VALUES IN (2) COMMENT = 'srv "shard_node2"' ENGINE = SPIDER) */ create table shardtest_key ( shard_key int , shard_no int NOT NULL AUTO_INCREMENT , val varchar(100) , PRIMARY KEY (shard_no) ); insert into shardtest_key(shard_key, val) values (1,'node1'); insert into shardtest_key(shard_key, val) values (2,'node2'); insert into shardtest_key(shard_key, val) values (3,'node3'); insert into shardtest_key(shard_key, val) values (4,'node4'); … insert into shardtest_key(shard_key, val) values (2,'node2'); insert into shardtest_key(shard_key, val) values (3,'node3'); insert into shardtest_key(shard_key, val) values (4,'node4'); Spider Engine Node 2 Node 3 Node 4Node 1 Limitation of a Spider Engine 5. SELECT ( IN( ) + shardkey)
  • 61. SELECT * FROM shardtest_key WHERE shard_key in (1,2) AND shard_no in (1,5,9,2,26); +-----------+----------+-------+ | shard_key | shard_no | val | +-----------+----------+-------+ | 1 | 1 | node1 | | 1 | 5 | node1 | | 1 | 9 | node1 | | 2 | 2 | node2 | | 2 | 26 | node2 | +-----------+----------+-------+ Spider Engine Node 2 Node 3 Node 4 Node 1 Limitation of a Spider Engine 5. SELECT ( IN( ) + shardkey ) drop temporary table if exists log_db.tmp_spider_bka_0x7f0c403d1820_shardtest_key; create temporary table log_db.tmp_spider_bka_0x7f0c403d1820_shardtest_key( id bigint , c0 int(11) , c1 int(11) ) engine=memory default charset=utf8 collate utf8_general_ci; insert into log_db.tmp_spider_bka_0x7f0c403d1820_shardtest_key(id,c0,c1) values(0,1,1),(1,2,1),(2,5,1),(3,9,1),(4,26,1) select a.id,b.`shard_key`,b.`shard_no`,b.`val` from log_db.tmp_spider_bka_0x7f0c403d1820_shardtest_key a ,`log_db`.`shardtest_key` b where a.c0 <=> b.`shard_no` and a.c1 <=> b.`shard_key` drop temporary table if exists log_db.tmp_spider_bka_0x7f0c403d1820_shardtest_key values(0,1,2),(1,2,2),(2,5,2),(3,9,2),(4,26,2)
  • 62. id >= 1 and id <= 6 equal Spider Engine Node 2 Node 3 Node 4Node 1 Limitation of a Spider Engine 5. SELECT ( BETWEEN ) SELECT * FROM shardtest where id between 1 and 6; +----+-----------+ | id | name | +----+-----------+ | 1 | SPIDER_01 | | 5 | key1 | | 4 | SPIDER_01 | | 3 | SPIDER_01 | | 2 | SPIDER_01 | | 6 | key1 | +----+-----------+ (select 0,`id`,`name` from `log_db`.`shardTest` where `id` >= 1 and `id` <= 6 order by `id`) order by `id`
  • 63. explain SELECT * FROM shardtest where name = 'key1' and id >= 1 and id <= 6; +------+-------------+-----------+-------+--------------------------+---------+---------+------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+-----------+-------+--------------------------+---------+---------+------+------+-------------+ | 1 | SIMPLE | shardtest | range | PRIMARY,idx_shardtest_01 | PRIMARY | 4 | NULL | 8 | Using where | +------+-------------+-----------+-------+--------------------------+---------+---------+------+------+-------------+ Spider Engine Node 2 Node 3 Node 4Node 1 Limitation of a Spider Engine 5. SELECT ( BETWEEN ) SELECT * FROM shardtest WHERE name = 'key1‘ AND id >= 1 and id <= 6; +----+------+ | id | name | +----+------+ | 5 | key1 | | 6 | key1 | +----+------+ (select 0,`id`,`name` from `log_db`.`shardTest` where `id` >= 1 and `id` <= 6 order by `id`) order by `id` Spider Engine “name” filter Shard DB Data Index PRIMARY KEY
  • 64. explain SELECT * FROM shardtest use index(idx_shardtest_01) where name = 'key1' and id >= 1 and id <= 6; +------+-------------+-----------+------+------------------+------------------+---------+-------+------+-------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+-----------+------+------------------+------------------+---------+-------+------+-------------+ | 1 | SIMPLE | shardtest | ref | idx_shardtest_01 | idx_shardtest_01 | 360 | const | 9687 | Using where | +------+-------------+-----------+------+------------------+------------------+---------+-------+------+-------------+ idx_shardtest_01 : name Spider Engine Node 2 Node 3 Node 4Node 1 Limitation of a Spider Engine 5. SELECT ( BETWEEN ) SELECT * FROM shardtest use index(idx_shardtest_01) WHERE name = 'key1‘ AND id >= 1 and id <= 6; +----+------+ | id | name | +----+------+ | 5 | key1 | | 6 | key1 | +----+------+ select `id`,`name` from `log_db`.`shardTest` where `name` = 'key1' Spider Engine “id” filter Shard DB Data
  • 65. Spider Engine Node 2 Node 3 Node 4Node 1 Limitation of a Spider Engine 5. SELECT ( BETWEEN ) create index idx_shardtest_03 on shardtest(name, id); explain SELECT * FROM shardtest use index(idx_shardtest_03) where name = 'key1' and id between 1 and 6; +------+-------------+-----------+-------+------------------+------------------+---------+------+------+--------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +------+-------------+-----------+-------+------------------+------------------+---------+------+------+--------------------------+ | 1 | SIMPLE | shardtest | range | idx_shardtest_03 | idx_shardtest_03 | 364 | NULL | 8 | Using where; Using index | +------+-------------+-----------+-------+------------------+------------------+---------+------+------+--------------------------+ SELECT * FROM shardtest use index(idx_shardtest_03) WHERE name = 'key1‘ AND id between 1 and 6; +----+------+ | id | name | +----+------+ | 5 | key1 | | 6 | key1 | +----+------+ (select 0,`id`,`name` from `log_db`.`shardTest` where `id` >= 1 and `id` <= 6 and `name` = 'key1' order by `id`,`name` ) order by `id`,`name`
  • 66.  What is Spider Engine?  Architecture  How to Create Spider Engine  Limitation of a Spider Engine  Guideline  Q&A Agenda
  • 67. Schema • Shard 별로 스키마 구성 (물리적으로 같은 위치에) • 자동 증가값은 Spider Engine 에서 처리하도록 구성 • Global 스카마의 경우 HA 기능을 사용하여 각 서버에 복제본 구성 • Index 는, Data node 에는 전통적으로 필요한 index 생성 Spider node 에는 필요한 모든 컬럼 index 생성 Performance • 각 Node에서 가장 성능이 나쁜 서버의 속도가 전체 성능을 결정한다. (아쉽게도 각 Node에 Query를 parallel 하게 전달하지는 않는다.) Query • IN절과 ORDER BY 절은 최소화 • 조건절에 Filter 위치를 확실히 확인 • 설계 및 개발단계에 선반영 검토 (ex. 모든 쿼리에 Shard Key 조건을 추가하여 개발) Guideline
  • 68.  What is Spider Engine?  Architecture  How to Create Spider Engine  Limitation of a Spider Engine  Guideline  Q&A Agenda
  • 69. Q & A ■ Spider_internal_limit shard node에 레코드 LIMIT 제한을 준다. ■ Spider_internal_limit = 100 Query : SELECT * FROM shardtest limit 101 Node 2 Node 3 Node 4 Node 1
  • 70. Q & A ■ Spider_internal_limit = 100 Query : SELECT * FROM shardtest order by id limit 101 Node 2 Node 3 Node 4Node 1 ■ Spider_internal_limit = -1 Query : SELECT * FROM shardtest order by id limit 100 Node 2 Node 3 Node 4Node 1
  • 71. Q & A ■ Spider_internal_limit = 100 Query : SELECT * FROM shardtest limit 1000 Node 2 Node 3 Node 4Node 1 ■ 결과
  • 72. Q & A ■ 스키마 변경은 각 노트에 상태와 무관한가? Node 4 Shutdown Spider Engine
  • 73. Q & A ■ 스키마 변경은 각 노트에 상태와 무관한가? Node4에 접속 불가
  • 74. Q & A ■ 스키마 변경은 각 노트에 상태와 무관한가? ALL Node Shutdown
  • 75. Q & A ■ Spider node에 shard_key Partition + 각 노드 Partition 구조 및 인덱스 설계 고려 사항이 있는가? Node 2 Node 3 Node 4Node 1 CREATE TABLE `shardtest_key` ( `shard_key` int(11) DEFAULT NULL, `shard_no` int(11) NOT NULL AUTO_INCREMENT, Partkey_week INT, `val` varchar(100) DEFAULT NULL, PRIMARY KEY (`shard_no`,Partkey_week) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 /*!50100 PARTITION BY LIST (Partkey_week) (PARTITION character_crud_log_P00 VALUES IN (0) ENGINE = InnoDB, PARTITION character_crud_log_P01 VALUES IN (1) ENGINE = InnoDB, PARTITION character_crud_log_P02 VALUES IN (2) ENGINE = InnoDB, PARTITION character_crud_log_P03 VALUES IN (3) ENGINE = InnoDB, PARTITION character_crud_log_P04 VALUES IN (4) ENGINE = InnoDB, PARTITION character_crud_log_P05 VALUES IN (5) ENGINE = InnoDB) */; Spider Engine CREATE TABLE `shardtest_key` ( `shard_key` int(11) NOT NULL DEFAULT '0', `shard_no` int(11) NOT NULL AUTO_INCREMENT, Partkey_week int, `val` varchar(100) DEFAULT NULL, PRIMARY KEY (`shard_no`,shard_key, Partkey_week), key (shard_key, Partkey_week) ) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "shardtest_key" ' /*!50100 PARTITION BY LIST (`shard_key`) (PARTITION shard1 VALUES IN (1) COMMENT = 'srv "shard_node1"' ENGINE = SPIDER, PARTITION shard3 VALUES IN (3) COMMENT = 'srv "shard_node3"' ENGINE = SPIDER, PARTITION shard4 VALUES IN (4) COMMENT = 'srv "shard_node4"' ENGINE = SPIDER, PARTITION shard2 VALUES IN (2) COMMENT = 'srv "shard_node2"' ENGINE = SPIDER) */ ■ 결론 위에서 이야기 했던 것 처럼 각 노드에 필요한 조건이 모두 전달되려면 Spider에 인덱스가 존재해야 한다. 결국 partition을 제대로 사용하려면 spider 쪽에 (shard_key + Partition_key + 필요한 인덱스) 구조로 인덱스를 만들어야 한다.
  • 76. Q & A Spider Engine Node 2 Node 3 Node 4Node 1 실행 계획 1,2,3 1,2,3 ■ Spider node에 shard_key Partition + 각 노드 Partition 구조 및 인덱스 설계 고려 사항이 있는가?
  • 77. Q & A ■ Spider 복제 구성에서 SELECT 되는 기준 노드는? Spider Engine Node 2 Node 3 Node 4 Node 1 Client insert insert Client select select Insert 부하 Insert & Select 부하
  • 78. Q & A ■ Spider 복제 구성에서 SELECT 되는 기준 노드는? Spider Engine CREATE TABLE `common_tb` ( `ct_no` int(11) NOT NULL AUTO_INCREMENT, `ct_code` char(4) DEFAULT NULL, `ct_name` varchar(30) DEFAULT NULL, `node_name` varchar(6), PRIMARY KEY (`ct_no`), KEY `ct_code` (`ct_code`) ) ENGINE=SPIDER DEFAULT CHARSET=utf8 COMMENT='wrapper "mysql", table "common_tb" ' /*!50100 PARTITION BY KEY (ct_no) (PARTITION shard1 COMMENT = 'srv "shard_node1 shard_node2 shard_node3 shard_node4"' ENGINE = SPIDER) */ CREATE TABLE `common_tb` ( `ct_no` int(11) NOT NULL AUTO_INCREMENT, `ct_code` char(4) DEFAULT NULL, `ct_name` varchar(30) DEFAULT NULL, `node_name` varchar(6) DEFAULT 'node4', PRIMARY KEY (`ct_no`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 Node 1 Node 2 Node 3 Node 4 Node1, Node2, Node3, Node4
  • 79. Q & A ■ Spider 복제 구성에서 SELECT 되는 기준 노드는? Spider Engine Node 1 Node 2 Node 3 Node 4 General_log