데이터베이스 샤딩(Sharding)이란 동일한 스키마의 데이터베이스를 여러 인스턴스에 나누어 저장하는 것을 말한다. 이중화와는 다른 개념이다. 이중화는 하나의 데이터를 여러 곳에 저장하지만 샤딩은 하나의 데이터를 하나의 인스턴스에 골라서 저장을 한다. 보통은 잘 사용하지 않고 데이터가 억수로 많은 경우에 사용한다.
샤딩을 사용하면 데이터가 많은 경우에 단일 인스턴스보다 성능이 빨라지고 단일 인스턴스에 저장할 수 없는 만큼의 데이터를 가지고 있다면 샤딩을 사용해야만 할 것이다.
샤딩에는 여러 종류가 있지만 여기에서는 Range Sharding이란 것을 사용해 볼 예정이다.
Range Sharding
유저테이블을 샤딩한다고 생각하자. 인스턴스를 4개(개발자가 정하면 된다.) 두고 1~3월 생일은 1번, 4~6월 생일은 2번, 7~9월 생일은 3번, 10~12월 생일은 4번 인스턴스에 저장한다. 또한 이름을 기준으로 ㄱ~ㅁ 성씨는 1번, ㅂ~ㅈ 성씨는 2번... 이렇게 나눌 수도 있고, 거주지기준, 성별기준같이 임의의 기준으로 나누어 저장하는 방법을 Range Sharding이라고 한다.
여기에서 각 데이터베이스 인스턴스를 샤드라고 부른다.
Router
새로운 유저를 추가할 때 몇 번 인스턴스에 저장할건지, 유저를 찾을 때 몇 번 인스턴스에서 찾아야하는지, 유저를 업데이트나 삭제할 때 해당하는 유저가 몇 번 인스턴스에 있는지를 찾아야 할 것이다. 그럴때 Router를 두고 어디에 저장할건지, 어디서 찾을건지 정해주면 된다.
유저의 이름을 기준으로 Range Sharding을 해보자.
준비
DB가 4개 필요하다. 하지만 실제로 인스턴스를 4개 만들 수 없으니 도커컴포즈를 사용한다. MySQL을 사용할 예정이다.
데이터베이스 준비
# docker-compose.yml
version: '3.8'
services:
db1:
image: 'mysql'
ports:
- "9000:3306"
environment:
- MYSQL_ROOT_PASSWORD=123
db2:
image: 'mysql'
ports:
- "9001:3306"
environment:
- MYSQL_ROOT_PASSWORD=123
db3:
image: 'mysql'
ports:
- "9002:3306"
environment:
- MYSQL_ROOT_PASSWORD=123
db4:
image: 'mysql'
ports:
- "9003:3306"
environment:
- MYSQL_ROOT_PASSWORD=123
데이터베이스를 4개 만들 도커 컴포즈를 작성한다. 실전에서는 절대 비밀번호를 저렇게 노출하면 안된다. 접속할 때 구분해야되니 포트로 구분하자.
그 후 각 컨테이너에 접근해서 데이터베이스와 테이블을 만들어야 한다.
docker-compose up -d
docker exec sharding-db1-1
mysql -uroot -p
create database sharding;
use sharding;
create table user (id int not null auto_increment, name varchar(100), age int, primary key(id)) charset=utf8;
sharding-db1-1 ~ sharding-db4-1까지 반복한다. (분명 한번에 하는 방법이 있을텐데 몰라서 노가다했다..;;)
파이썬과 데이터베이스 연동
# datasource.py
import pymysql
class DataSource:
def __init__(self):
self.conn1 = pymysql.connect(
host="localhost", user="root", password="123", database="sharding", port=9000, charset="utf8")
self.conn2 = pymysql.connect(
host="localhost", user="root", password="123", database="sharding", port=9001, charset="utf8")
self.conn3 = pymysql.connect(
host="localhost", user="root", password="123", database="sharding", port=9002, charset="utf8")
self.conn4 = pymysql.connect(
host="localhost", user="root", password="123", database="sharding", port=9003, charset="utf8")
self.cur1 = self.conn1.cursor()
self.cur2 = self.conn2.cursor()
self.cur3 = self.conn3.cursor()
self.cur4 = self.conn4.cursor()
self.cursors = [self.cur1, self.cur2, self.cur3, self.cur4]
self.connections = [self.conn1, self.conn2, self.conn3, self.conn4]
if __name__ == "__main__":
src = DataSource()
에러가 안난다면 성공한 것이다!
다음시간에 라우터를 만들고 본격적으로 샤딩을 해보자!
'프로그래밍 > 개발' 카테고리의 다른 글
[개발] 샤딩이란 것을 해보자! (3) (2) | 2023.04.21 |
---|---|
[개발] 샤딩이란 것을 해보자! (2) (0) | 2023.04.21 |
[개발] nginx에서 https 적용하기 (0) | 2023.02.23 |
[개발] Nginx에서 여러 도메인 적용하기 (3) | 2023.02.20 |
우분투 22.04 업그레이드 오류 (0) | 2022.08.27 |