RYE
샤딩을 지원하는 오픈소스 관계형 DBMS
강철규
PaaS
CONTENTS
1. 응용에서 샤딩할 때 고려할 점
2. RYE에 적용된 기술
3. RYE open source project
1.
응용에서 샤딩할 때 고려할 점
1.0 예제 데이터베이스
login_history
userid
login_time
ip_address
country_code
VARCHAR(50)
DATETIME
VARCHAR(20)
VARCHAR(2)
PRIMARY KEY(userid, login_time)
country
code
name
VARCHAR(2)
VARCHAR(50)
PRIMARY KEY(code)
SELECT h.login_time, h.ip_address, c.name
FROM login_history h
LEFT OUTER JOIN country c
ON c.code = h.country_code
WHERE userid = ?
AND login_time between ? and ?
SELECT COUNT(*)
FROM login_history
WHERE login_time between ? and ?
조회 쿼리
통계 쿼리
1.0 예제 데이터베이스
‘user1’ …
‘user1’
‘user1’
‘user2’ …
‘user2’
… …
login_history
‘JP’ ‘Japan’
‘KR’ ‘Korea’
‘US’ ‘USA’
country
‘user1’ …
‘user1’
‘user1’
… …
login_history
‘JP’ ‘Japan’
‘KR’ ‘Korea’
‘US’ ‘USA’
country
‘user2’ …
‘user2’
… …
login_history
‘JP’ ‘Japan’
‘KR’ ‘Korea’
‘US’ ‘USA’
country
sharding
1.1 SQL Routing
void loginHistory(String userid) {
sql = “SELECT h.login_time, … ”;
pstmt = conn.prepareStatement(sql)
pstmt.setString(1, userid);
…
ResultSet rs = pstmt.executeQuery();
…
}
shard node
Data Source
Connection
userid
hash, modular
conn = getConnection(userid);
1.1 SQL Routing
void loginStatistics() {
sql = “SELECT COUNT(*) … “;
pstmt = conn.prepareStatement(sql)
…
ResultSet rs = pstmt.executeQuery();
…
}
모든 샤드에 대한
DB 커넥션 배열 반환
void loginStatistics() {
Connection[] conn = getAllShardConns();
for (int i=0 ; i < conn.length ; i++ ) {
sql = “SELECT COUNT(*) … “;
pstmt = conn[i].prepareStatement(sql)
…
ResultSet rs = pstmt.executeQuery();
…
}
}
1.2 샤드 확장
shard1
shard2
shard2
shard1
shard3
shard4
데이터 마이그레이션 필요
• 같은 userid 에 대한 데이터는 같이 이동
되어야 함
• 한 userid의 데이터가 많은 경우 이동되는
시간이 길어질 수 있음 à 마이그레이션 시
간 동안 변경되는 데이터에 대한 관리
• 서비스 정지 상태에서 마이그레이션
• 서비스 운영 중 마이그레이션
1.3 샤드 데이터 정합성
1. 모든 응용은 동일한 샤딩 룰을 유지해야 함
• 다른 샤딩 룰 à 잘못된 샤드로 쿼리 전송
application
application
shard2
shard1
shard3
shard4
2. 통계 쿼리 결과 정합성
• shard1 à shard3 데이터 복사된 경우
• shard1에서 복사된 데이터를 삭제하기
전에는 COUNT(*) 쿼리가 부정확함
2.
RYE에 적용된 기술
2.1 SQL routing
응용에서 샤드 키 정보를 인식하는 방법
ü 샤드를 결정하기 위한 별도의 API
ü SQL에서 추출
void loginHistory(String userid) {
sql = “SELECT h.login_time, … ”;
pstmt = conn.prepareStatement(sql)
pstmt.setString(1, userid);
pstmt.setTimestamp(2, startTime);
pstmt.setTimestamp(3, endTime);
ResultSet rs = pstmt.executeQuery();
…
}
2.1 SQL routing
테이블 정의
CREATE TABLE
login_history
(
userid VARCHAR(50),
login_time DATETIME,
ip_address VARCHAR(20),
country_code VARCHAR(2),
PRIMARY KEY(userid, login_time)
)
CREATE TABLE
country
(
code VARCHAR(2),
name VARCHAR(50),
PRIMARY KEY (code)
);
테이블 타입과 샤드키 컬럼 정보를
DB 카탈로그에 저장
GLOBALSHARD
SHARD BY userid;
2.1 SQL routing
SELECT h.login_time, c.name
FROM login_history h
LEFT OUTER JOIN country c
ON c.code = h.country_code
WHERE userid = ?
AND login_time between ? and ?
쿼리 파싱
SELECT COUNT(*)
FROM login_history
WHERE
login_time between ? and ?
2.1 SQL routing
SELECT h.login_time, c.name
FROM login_history h
LEFT OUTER JOIN country c
ON c.code = h.country_code
WHERE userid = ?
AND login_time between ? and ?
쿼리 파싱
shard table
shard-key column
shard-value
SELECT COUNT(*)
FROM login_history
WHERE
login_time between ? and ?
2.1 SQL routing
쿼리 타입과 샤드 커넥션
SQL Type shard table shard-value shard connection
SELECT
Yes 1 1 shard
Yes n n shards
Yes 0 all shards
No - any shard
INSERT, UPDATE, DELETE,
SELECT FOR UPDATE
Yes 1 1 shard
Yes 0,n ERROR
No - all shards
DDL - - all shards
* prepare, DatabaseMetadata : any shard
2.1 SQL routing
하나의 트랜잭션에서 커넥션 호환
current connection
none 1 shard all shards
connection
request
1 shard O O, X (*)
X
any shard
O
(auto commit)
O O
n shards
O
(auto commit)
X O
all shards O X O
(*) 같은 shard-value에 대한 트랜잭션만 허용
2.1 SQL routing
prepare
prepare
sharding metadata
prepareStatement()
setString()
setObject()
…
execute() execute
shard-value
↓
shard 선택
prepare/execute
shardx
Application JDBC Driver DB Server
shardy
쿼리 실행 흐름
2.1 SQL routing
샤딩 그룹
• shard-value는 개수가 많기 때문에 관리를 위한 데이터 단위가 필요
• 같은 샤드에 저장되는 shard-value의 그룹
• GROUPID = Hash(shard-value) % N + 1 (N = 샤딩 그룹의 개수)
• 샤드 리밸런스시 마이그레이션 단위. 데이터 정합성 판단에 활용.
Sharding catalog
• (GROUPID, SHARDID) mapping table
• shard node table - DB 접속을 위한 정보. ip, port, …
shard-value à shard 선택
2.1 SQL routing
GROUPID SHARDID
1 1
2 1
… …
10000 2
SHARDID ip port …
1 1.1.1.1 … …
1 1.1.1.2 … …
2 1.1.2.1 … …
… … … …
shard-value à shard 선택 예
‘user1’
GROUPID
527
hash
2.1 SQL routing
성능을 위한 고려사항
• 커넥션 풀링
• 샤드 커넥션 재사용
• Statement pooling
• Sharding metadata 재사용 ­ 샤딩
정보를 얻기 위한 서버 요청 횟수 줄임
• 쿼리 실행 정보 재사용 ­ 쿼리 실행을
위한 prepare 횟수 줄임
• JDBC 드라이버 내에 커넥션 풀 유지
DBCP
Connection
Pool
JDBC
Application
2.1 SQL routing
성능을 위한 고려사항
• 커넥션 풀링
• 샤드 커넥션 재사용
• Statement pooling
• Sharding metadata 재사용 ­ 샤딩
정보를 얻기 위한 서버 요청 횟수 줄임
• 쿼리 실행 정보 재사용 ­ 쿼리 실행을
위한 prepare 횟수 줄임
• JDBC 드라이버 내에 커넥션 풀 유지
DBCP
Connection
Pool
JDBC
shard
Connection
Pool
Application
2.1 SQL routing
성능을 위한 고려사항
• sharding catalog
• DB에 저장
• JDBC 드라이버에 sharding catalog 캐시 유지
• sharding catalog version 관리
• sharding catalog 변경 시 version 증가
• 주기적으로 최신 버전인지 검사
• 서버 통신 할 때 최신 버전인지 검사
SHARDID ip …
… … …
GROUPID SHARDID
… …
GROUPID SHARDID
… …
shard
Connection
Pool
JDBC
2.2 샤드 확장
shard1
shard2
shard2
shard1
shard3
shard4
서비스 운영 중 마이그레이션
• 마이그레이션 대상 선정
• 저장된 데이터 복사
• 변경된 데이터 반영
2.2 샤드 확장
마이그레이션 대상 선정
• (GROUPID, SHARDID) mapping table에서 GROUPID선정
GROUPID SHARDID
1 1
… 1
5000 1
5001 2
… 2
10000 2
3
3
# shards : 2 à 3
2.2 샤드 확장
저장된 데이터 복사
• 가능한 방안: 모든 GROUPID를 한번에 처리
• Table full-scan.
• 부하 조절이 어려움
• GROUPID가 이전되는 시점에 발생할 수 있는 에러 급증 가능
table
record
record
page
table full-scan
index
index scan
• 해결 방안: GROUPID단위로 처리
• GROUPID 단위 조회.
• 부하 조절이 용이함
• GROUPID 가 이전되는 시점에 발생하는 에러가 분산됨
• 서비스에 주는 영향이 작음
2.2 샤드 확장
GROUPID를 이용한 데이터 접근방법 필요함
• (GROUPID, shard-value) 시스템 테이블 유지
• SHARD 테이블에 대한 INSERT 시
(GROUPID, shard-value)값이 없는 경우 추가
저장된 데이터 복사
• GROUPID에 대한 모든 shard-value값을 추출
• 각각의 shard-value값으로 데이터 조회
• shard-key 컬럼으로 시작하는 인덱스 필요
à Primary key 활용
‘user1’
GROUPID
527
hash
2.2 샤드 확장
변경된 데이터 반영
• 데이터를 복사하는 동안 발생되는 데이터 변경에 대해 적용
• Transaction log에서 변경된 값을 읽어서 반영.
• 데이터 복사와 변경된 데이터 반영 병렬 진행
Transaction log
• 데이터 변경에 대한 physical logging
• 예: UPDATE … SET count = count + 1 WHERE …
변경된 모든 레코드에 대해 변경되기 전/후의 값을 모두 추
출 가능
‘a’ … …
‘a’
‘a’ … …
‘a’
… … …
Trx
log
SHARDn
select
insert
migrator
analyze
insert/update/delete
User
transaction
2.2 샤드 확장
Transaction log 반영을 종료하는 절차
1) 데이터 복사 완료 확인
2) 해당 GROUPID에 대한 쿼리 유입을 막도록 설정
3) ‘disable GROUPID’ log 기록
4) ‘disable GROUPID’ log를 읽으면 로그 반영 종료
5) 타겟 DB가 해당 GROUPID 를 처리하도록 변경
6) shard catalog 변경
• 2) 시점부터 변경된 (GROUPID, SHARDID) 정보가
driver로 전달되는 시점까지 해당 GROUPID 에 대한
쿼리는 오류 발생
migrator
db_server
Trx
log
disable
GROUPID=n
write log
disable GROUPID=n
db_server
enable
GROUPID=n
shardx shardy
2.3 데이터 정합성 관리
GROUPID기반 정합성 검사
• DB 서버에서 GROUPID bitmap 관리
• DB 서버는 관리하는 GROUPID인지 검사
• 모든 레코드, 인덱스에 GROUPID를 저장함
shardx
1 2 … N-1 N
1 1 … 0 0
GROUPID bitmap
DB server
2.3 데이터 정합성 관리
INSERT INTO login_history VALUES
(‘user1’, now(), ‘1.1.1.1’, ‘KR’);
shardx
JDBC
1 … 527 … N
1 … 1 … 0
groupid bitmap
INSERT INTO login_history VALUES
(‘user1’, now(), ‘1.1.1.1’, ‘KR’)
GROUPID= 527
정합성 검사
execute
DB server
‘user1’
GROUPID
527
hash
2.3 데이터 정합성 관리
INSERT INTO login_history VALUES
(‘user1’, now(), ‘1.1.1.1’, ‘KR’)
GROUPID = 527
record header userid login_time ip_address country_code
GROUPID=527
…
uesr1 2017-10-17
12:00:00.000
1.1.1.1 KR
레코드 저장
2.3 데이터 정합성 관리
저장된 GROUPID 용도
• 마이그레이션
• transaction log 반영 시 마이그레이션 대상 GROUPID인지 판단
• shard key가 지정되지 않은 쿼리의 데이터 정합성
• secondary index scan
• table full-scan
2.3 데이터 정합성 관리
shard key가 지정되지 않은 쿼리의 데이터 정합성
SELECT COUNT(*)
FROM login_history
WHERE
login_time
between ? and ?
shardx
527 user1 … … …
527 user1 … … …
1 … 527 … N
1 … 0 … 0
GROUPID bitmap
login_history
shardy
527 user1 … … …
527 user1 … … …
1 … 527 … N
0 … 1 … 0
GROUPID bitmap
login_history
groupid 527
migration
관리 대상 GROUPID 아님
결과에서 제외
2.4 프로세스 아키텍쳐
sharding catalog
shard1
hostA
shard
mgmt
server
shard1
hostB
shard
mgmt
server
shard2
hostC
shard2
hostD
GROUPID bitmap
HA
HA
JDBC
SQL
2.5 샤드 구성
hostA
① install RYE
② rye service start
hostB
① install RYE
② rye service start
hostC
① install RYE
② rye service start
hostD
① install RYE
② rye service start
$ java rye.jdbc.admin.Shard init demodb hostA,hostB 40000 
--num-groups=10000 
--add-node=2:hostC,2:hostD
jdbc:rye://hostA:40000,hostB:40000/demodb/rw?
초기화
명령어
connection
URL
shard1 host shard mgmt port
③ DB 생성 및 샤드 정보 초기화
shard1 shard1 shard2 shard2
H
A
H
A
3.
RYE open source project
https://github.com/naver/rye
CUBRID 프로젝트에서 포크
3.1 Rye Open Source Project
3.1 Rye Open Source Project
DB Server
Storage Manager
Lock
Manager
Log
Manager
Brokers
Connection
Pooling
Monitoring/
Logging
Job Queuing
Transaction
Manager
Object
Manager
Query
Manager
Interfaces
ODBC OLEDB JDBC PHP
DB Server
replication
HA
CUBRID Architecture
3.1 Rye Open Source Project
DB Server
Storage Manager
Lock
Manager
Log
Manager
Brokers
Connection
Pooling
Monitoring/
Logging
Job Queuing
Transaction
Manager
Object
Manager
Query
Manager
Interfaces
JDBC
DB Server
replication
HA
RYE Architecture
Sharding
Shard Mgmt
Server
migrator
Q & A
dl_oss_rye@navercorp.com
Thank you

[223]rye, 샤딩을 지원하는 오픈소스 관계형 dbms

  • 1.
    RYE 샤딩을 지원하는 오픈소스관계형 DBMS 강철규 PaaS
  • 2.
    CONTENTS 1. 응용에서 샤딩할때 고려할 점 2. RYE에 적용된 기술 3. RYE open source project
  • 3.
  • 4.
    1.0 예제 데이터베이스 login_history userid login_time ip_address country_code VARCHAR(50) DATETIME VARCHAR(20) VARCHAR(2) PRIMARYKEY(userid, login_time) country code name VARCHAR(2) VARCHAR(50) PRIMARY KEY(code) SELECT h.login_time, h.ip_address, c.name FROM login_history h LEFT OUTER JOIN country c ON c.code = h.country_code WHERE userid = ? AND login_time between ? and ? SELECT COUNT(*) FROM login_history WHERE login_time between ? and ? 조회 쿼리 통계 쿼리
  • 5.
    1.0 예제 데이터베이스 ‘user1’… ‘user1’ ‘user1’ ‘user2’ … ‘user2’ … … login_history ‘JP’ ‘Japan’ ‘KR’ ‘Korea’ ‘US’ ‘USA’ country ‘user1’ … ‘user1’ ‘user1’ … … login_history ‘JP’ ‘Japan’ ‘KR’ ‘Korea’ ‘US’ ‘USA’ country ‘user2’ … ‘user2’ … … login_history ‘JP’ ‘Japan’ ‘KR’ ‘Korea’ ‘US’ ‘USA’ country sharding
  • 6.
    1.1 SQL Routing voidloginHistory(String userid) { sql = “SELECT h.login_time, … ”; pstmt = conn.prepareStatement(sql) pstmt.setString(1, userid); … ResultSet rs = pstmt.executeQuery(); … } shard node Data Source Connection userid hash, modular conn = getConnection(userid);
  • 7.
    1.1 SQL Routing voidloginStatistics() { sql = “SELECT COUNT(*) … “; pstmt = conn.prepareStatement(sql) … ResultSet rs = pstmt.executeQuery(); … } 모든 샤드에 대한 DB 커넥션 배열 반환 void loginStatistics() { Connection[] conn = getAllShardConns(); for (int i=0 ; i < conn.length ; i++ ) { sql = “SELECT COUNT(*) … “; pstmt = conn[i].prepareStatement(sql) … ResultSet rs = pstmt.executeQuery(); … } }
  • 8.
    1.2 샤드 확장 shard1 shard2 shard2 shard1 shard3 shard4 데이터마이그레이션 필요 • 같은 userid 에 대한 데이터는 같이 이동 되어야 함 • 한 userid의 데이터가 많은 경우 이동되는 시간이 길어질 수 있음 à 마이그레이션 시 간 동안 변경되는 데이터에 대한 관리 • 서비스 정지 상태에서 마이그레이션 • 서비스 운영 중 마이그레이션
  • 9.
    1.3 샤드 데이터정합성 1. 모든 응용은 동일한 샤딩 룰을 유지해야 함 • 다른 샤딩 룰 à 잘못된 샤드로 쿼리 전송 application application shard2 shard1 shard3 shard4 2. 통계 쿼리 결과 정합성 • shard1 à shard3 데이터 복사된 경우 • shard1에서 복사된 데이터를 삭제하기 전에는 COUNT(*) 쿼리가 부정확함
  • 10.
  • 11.
    2.1 SQL routing 응용에서샤드 키 정보를 인식하는 방법 ü 샤드를 결정하기 위한 별도의 API ü SQL에서 추출 void loginHistory(String userid) { sql = “SELECT h.login_time, … ”; pstmt = conn.prepareStatement(sql) pstmt.setString(1, userid); pstmt.setTimestamp(2, startTime); pstmt.setTimestamp(3, endTime); ResultSet rs = pstmt.executeQuery(); … }
  • 12.
    2.1 SQL routing 테이블정의 CREATE TABLE login_history ( userid VARCHAR(50), login_time DATETIME, ip_address VARCHAR(20), country_code VARCHAR(2), PRIMARY KEY(userid, login_time) ) CREATE TABLE country ( code VARCHAR(2), name VARCHAR(50), PRIMARY KEY (code) ); 테이블 타입과 샤드키 컬럼 정보를 DB 카탈로그에 저장 GLOBALSHARD SHARD BY userid;
  • 13.
    2.1 SQL routing SELECTh.login_time, c.name FROM login_history h LEFT OUTER JOIN country c ON c.code = h.country_code WHERE userid = ? AND login_time between ? and ? 쿼리 파싱 SELECT COUNT(*) FROM login_history WHERE login_time between ? and ?
  • 14.
    2.1 SQL routing SELECTh.login_time, c.name FROM login_history h LEFT OUTER JOIN country c ON c.code = h.country_code WHERE userid = ? AND login_time between ? and ? 쿼리 파싱 shard table shard-key column shard-value SELECT COUNT(*) FROM login_history WHERE login_time between ? and ?
  • 15.
    2.1 SQL routing 쿼리타입과 샤드 커넥션 SQL Type shard table shard-value shard connection SELECT Yes 1 1 shard Yes n n shards Yes 0 all shards No - any shard INSERT, UPDATE, DELETE, SELECT FOR UPDATE Yes 1 1 shard Yes 0,n ERROR No - all shards DDL - - all shards * prepare, DatabaseMetadata : any shard
  • 16.
    2.1 SQL routing 하나의트랜잭션에서 커넥션 호환 current connection none 1 shard all shards connection request 1 shard O O, X (*) X any shard O (auto commit) O O n shards O (auto commit) X O all shards O X O (*) 같은 shard-value에 대한 트랜잭션만 허용
  • 17.
    2.1 SQL routing prepare prepare shardingmetadata prepareStatement() setString() setObject() … execute() execute shard-value ↓ shard 선택 prepare/execute shardx Application JDBC Driver DB Server shardy 쿼리 실행 흐름
  • 18.
    2.1 SQL routing 샤딩그룹 • shard-value는 개수가 많기 때문에 관리를 위한 데이터 단위가 필요 • 같은 샤드에 저장되는 shard-value의 그룹 • GROUPID = Hash(shard-value) % N + 1 (N = 샤딩 그룹의 개수) • 샤드 리밸런스시 마이그레이션 단위. 데이터 정합성 판단에 활용. Sharding catalog • (GROUPID, SHARDID) mapping table • shard node table - DB 접속을 위한 정보. ip, port, … shard-value à shard 선택
  • 19.
    2.1 SQL routing GROUPIDSHARDID 1 1 2 1 … … 10000 2 SHARDID ip port … 1 1.1.1.1 … … 1 1.1.1.2 … … 2 1.1.2.1 … … … … … … shard-value à shard 선택 예 ‘user1’ GROUPID 527 hash
  • 20.
    2.1 SQL routing 성능을위한 고려사항 • 커넥션 풀링 • 샤드 커넥션 재사용 • Statement pooling • Sharding metadata 재사용 ­ 샤딩 정보를 얻기 위한 서버 요청 횟수 줄임 • 쿼리 실행 정보 재사용 ­ 쿼리 실행을 위한 prepare 횟수 줄임 • JDBC 드라이버 내에 커넥션 풀 유지 DBCP Connection Pool JDBC Application
  • 21.
    2.1 SQL routing 성능을위한 고려사항 • 커넥션 풀링 • 샤드 커넥션 재사용 • Statement pooling • Sharding metadata 재사용 ­ 샤딩 정보를 얻기 위한 서버 요청 횟수 줄임 • 쿼리 실행 정보 재사용 ­ 쿼리 실행을 위한 prepare 횟수 줄임 • JDBC 드라이버 내에 커넥션 풀 유지 DBCP Connection Pool JDBC shard Connection Pool Application
  • 22.
    2.1 SQL routing 성능을위한 고려사항 • sharding catalog • DB에 저장 • JDBC 드라이버에 sharding catalog 캐시 유지 • sharding catalog version 관리 • sharding catalog 변경 시 version 증가 • 주기적으로 최신 버전인지 검사 • 서버 통신 할 때 최신 버전인지 검사 SHARDID ip … … … … GROUPID SHARDID … … GROUPID SHARDID … … shard Connection Pool JDBC
  • 23.
    2.2 샤드 확장 shard1 shard2 shard2 shard1 shard3 shard4 서비스운영 중 마이그레이션 • 마이그레이션 대상 선정 • 저장된 데이터 복사 • 변경된 데이터 반영
  • 24.
    2.2 샤드 확장 마이그레이션대상 선정 • (GROUPID, SHARDID) mapping table에서 GROUPID선정 GROUPID SHARDID 1 1 … 1 5000 1 5001 2 … 2 10000 2 3 3 # shards : 2 à 3
  • 25.
    2.2 샤드 확장 저장된데이터 복사 • 가능한 방안: 모든 GROUPID를 한번에 처리 • Table full-scan. • 부하 조절이 어려움 • GROUPID가 이전되는 시점에 발생할 수 있는 에러 급증 가능 table record record page table full-scan index index scan • 해결 방안: GROUPID단위로 처리 • GROUPID 단위 조회. • 부하 조절이 용이함 • GROUPID 가 이전되는 시점에 발생하는 에러가 분산됨 • 서비스에 주는 영향이 작음
  • 26.
    2.2 샤드 확장 GROUPID를이용한 데이터 접근방법 필요함 • (GROUPID, shard-value) 시스템 테이블 유지 • SHARD 테이블에 대한 INSERT 시 (GROUPID, shard-value)값이 없는 경우 추가 저장된 데이터 복사 • GROUPID에 대한 모든 shard-value값을 추출 • 각각의 shard-value값으로 데이터 조회 • shard-key 컬럼으로 시작하는 인덱스 필요 à Primary key 활용 ‘user1’ GROUPID 527 hash
  • 27.
    2.2 샤드 확장 변경된데이터 반영 • 데이터를 복사하는 동안 발생되는 데이터 변경에 대해 적용 • Transaction log에서 변경된 값을 읽어서 반영. • 데이터 복사와 변경된 데이터 반영 병렬 진행 Transaction log • 데이터 변경에 대한 physical logging • 예: UPDATE … SET count = count + 1 WHERE … 변경된 모든 레코드에 대해 변경되기 전/후의 값을 모두 추 출 가능 ‘a’ … … ‘a’ ‘a’ … … ‘a’ … … … Trx log SHARDn select insert migrator analyze insert/update/delete User transaction
  • 28.
    2.2 샤드 확장 Transactionlog 반영을 종료하는 절차 1) 데이터 복사 완료 확인 2) 해당 GROUPID에 대한 쿼리 유입을 막도록 설정 3) ‘disable GROUPID’ log 기록 4) ‘disable GROUPID’ log를 읽으면 로그 반영 종료 5) 타겟 DB가 해당 GROUPID 를 처리하도록 변경 6) shard catalog 변경 • 2) 시점부터 변경된 (GROUPID, SHARDID) 정보가 driver로 전달되는 시점까지 해당 GROUPID 에 대한 쿼리는 오류 발생 migrator db_server Trx log disable GROUPID=n write log disable GROUPID=n db_server enable GROUPID=n shardx shardy
  • 29.
    2.3 데이터 정합성관리 GROUPID기반 정합성 검사 • DB 서버에서 GROUPID bitmap 관리 • DB 서버는 관리하는 GROUPID인지 검사 • 모든 레코드, 인덱스에 GROUPID를 저장함 shardx 1 2 … N-1 N 1 1 … 0 0 GROUPID bitmap DB server
  • 30.
    2.3 데이터 정합성관리 INSERT INTO login_history VALUES (‘user1’, now(), ‘1.1.1.1’, ‘KR’); shardx JDBC 1 … 527 … N 1 … 1 … 0 groupid bitmap INSERT INTO login_history VALUES (‘user1’, now(), ‘1.1.1.1’, ‘KR’) GROUPID= 527 정합성 검사 execute DB server ‘user1’ GROUPID 527 hash
  • 31.
    2.3 데이터 정합성관리 INSERT INTO login_history VALUES (‘user1’, now(), ‘1.1.1.1’, ‘KR’) GROUPID = 527 record header userid login_time ip_address country_code GROUPID=527 … uesr1 2017-10-17 12:00:00.000 1.1.1.1 KR 레코드 저장
  • 32.
    2.3 데이터 정합성관리 저장된 GROUPID 용도 • 마이그레이션 • transaction log 반영 시 마이그레이션 대상 GROUPID인지 판단 • shard key가 지정되지 않은 쿼리의 데이터 정합성 • secondary index scan • table full-scan
  • 33.
    2.3 데이터 정합성관리 shard key가 지정되지 않은 쿼리의 데이터 정합성 SELECT COUNT(*) FROM login_history WHERE login_time between ? and ? shardx 527 user1 … … … 527 user1 … … … 1 … 527 … N 1 … 0 … 0 GROUPID bitmap login_history shardy 527 user1 … … … 527 user1 … … … 1 … 527 … N 0 … 1 … 0 GROUPID bitmap login_history groupid 527 migration 관리 대상 GROUPID 아님 결과에서 제외
  • 34.
    2.4 프로세스 아키텍쳐 shardingcatalog shard1 hostA shard mgmt server shard1 hostB shard mgmt server shard2 hostC shard2 hostD GROUPID bitmap HA HA JDBC SQL
  • 35.
    2.5 샤드 구성 hostA ①install RYE ② rye service start hostB ① install RYE ② rye service start hostC ① install RYE ② rye service start hostD ① install RYE ② rye service start $ java rye.jdbc.admin.Shard init demodb hostA,hostB 40000 --num-groups=10000 --add-node=2:hostC,2:hostD jdbc:rye://hostA:40000,hostB:40000/demodb/rw? 초기화 명령어 connection URL shard1 host shard mgmt port ③ DB 생성 및 샤드 정보 초기화 shard1 shard1 shard2 shard2 H A H A
  • 36.
  • 37.
  • 38.
    3.1 Rye OpenSource Project DB Server Storage Manager Lock Manager Log Manager Brokers Connection Pooling Monitoring/ Logging Job Queuing Transaction Manager Object Manager Query Manager Interfaces ODBC OLEDB JDBC PHP DB Server replication HA CUBRID Architecture
  • 39.
    3.1 Rye OpenSource Project DB Server Storage Manager Lock Manager Log Manager Brokers Connection Pooling Monitoring/ Logging Job Queuing Transaction Manager Object Manager Query Manager Interfaces JDBC DB Server replication HA RYE Architecture Sharding Shard Mgmt Server migrator
  • 40.
  • 41.