Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

3,943 views

Published on

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

Published in: Technology
  • Hello! Get Your Professional Job-Winning Resume Here - Check our website! https://vk.cc/818RFv
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here

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

  1. 1. RYE 샤딩을 지원하는 오픈소스 관계형 DBMS 강철규 PaaS
  2. 2. CONTENTS 1. 응용에서 샤딩할 때 고려할 점 2. RYE에 적용된 기술 3. RYE open source project
  3. 3. 1. 응용에서 샤딩할 때 고려할 점
  4. 4. 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 ? 조회 쿼리 통계 쿼리
  5. 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. 6. 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);
  7. 7. 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(); … } }
  8. 8. 1.2 샤드 확장 shard1 shard2 shard2 shard1 shard3 shard4 데이터 마이그레이션 필요 • 같은 userid 에 대한 데이터는 같이 이동 되어야 함 • 한 userid의 데이터가 많은 경우 이동되는 시간이 길어질 수 있음 à 마이그레이션 시 간 동안 변경되는 데이터에 대한 관리 • 서비스 정지 상태에서 마이그레이션 • 서비스 운영 중 마이그레이션
  9. 9. 1.3 샤드 데이터 정합성 1. 모든 응용은 동일한 샤딩 룰을 유지해야 함 • 다른 샤딩 룰 à 잘못된 샤드로 쿼리 전송 application application shard2 shard1 shard3 shard4 2. 통계 쿼리 결과 정합성 • shard1 à shard3 데이터 복사된 경우 • shard1에서 복사된 데이터를 삭제하기 전에는 COUNT(*) 쿼리가 부정확함
  10. 10. 2. RYE에 적용된 기술
  11. 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. 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. 13. 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 ?
  14. 14. 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 ?
  15. 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. 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. 17. 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 쿼리 실행 흐름
  18. 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. 19. 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
  20. 20. 2.1 SQL routing 성능을 위한 고려사항 • 커넥션 풀링 • 샤드 커넥션 재사용 • Statement pooling • Sharding metadata 재사용 ­ 샤딩 정보를 얻기 위한 서버 요청 횟수 줄임 • 쿼리 실행 정보 재사용 ­ 쿼리 실행을 위한 prepare 횟수 줄임 • JDBC 드라이버 내에 커넥션 풀 유지 DBCP Connection Pool JDBC Application
  21. 21. 2.1 SQL routing 성능을 위한 고려사항 • 커넥션 풀링 • 샤드 커넥션 재사용 • Statement pooling • Sharding metadata 재사용 ­ 샤딩 정보를 얻기 위한 서버 요청 횟수 줄임 • 쿼리 실행 정보 재사용 ­ 쿼리 실행을 위한 prepare 횟수 줄임 • JDBC 드라이버 내에 커넥션 풀 유지 DBCP Connection Pool JDBC shard Connection Pool Application
  22. 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. 23. 2.2 샤드 확장 shard1 shard2 shard2 shard1 shard3 shard4 서비스 운영 중 마이그레이션 • 마이그레이션 대상 선정 • 저장된 데이터 복사 • 변경된 데이터 반영
  24. 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. 25. 2.2 샤드 확장 저장된 데이터 복사 • 가능한 방안: 모든 GROUPID를 한번에 처리 • Table full-scan. • 부하 조절이 어려움 • GROUPID가 이전되는 시점에 발생할 수 있는 에러 급증 가능 table record record page table full-scan index index scan • 해결 방안: GROUPID단위로 처리 • GROUPID 단위 조회. • 부하 조절이 용이함 • GROUPID 가 이전되는 시점에 발생하는 에러가 분산됨 • 서비스에 주는 영향이 작음
  26. 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. 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. 28. 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
  29. 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. 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. 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. 32. 2.3 데이터 정합성 관리 저장된 GROUPID 용도 • 마이그레이션 • transaction log 반영 시 마이그레이션 대상 GROUPID인지 판단 • shard key가 지정되지 않은 쿼리의 데이터 정합성 • secondary index scan • table full-scan
  33. 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. 34. 2.4 프로세스 아키텍쳐 sharding catalog shard1 hostA shard mgmt server shard1 hostB shard mgmt server shard2 hostC shard2 hostD GROUPID bitmap HA HA JDBC SQL
  35. 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. 36. 3. RYE open source project
  37. 37. https://github.com/naver/rye CUBRID 프로젝트에서 포크 3.1 Rye Open Source Project
  38. 38. 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
  39. 39. 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
  40. 40. Q & A dl_oss_rye@navercorp.com
  41. 41. Thank you

×