Database

[DATABASE] Partitioning, Sharding, Replication

ju_young 2023. 12. 23. 13:31
728x90

Partitioning

partitioning은 다음과 같이 vertical partitioninghorizontal partitioning으로 나눌 수 있다.

 

vertical partitioning horizontal partitioning
column을 기준으로 table을 나누는 방식 row를 기준으로 table을 나누는 방식

Vertical Partitioning

예를 들어 Article이라는 게시글관련 테이블이 있다고 해보자.

 

id title writer_id created_at read_cnt comment_cnt content
... ... ... ... ... ... ...

만약 게시글들을 조회해야할 경우 content attribute는 필요가 없고 id, title, writer_id, created_at, read_cnt, comment_cnt만 필요로 할 것이다. 이때 SELECT 문으로 조회를 실행하면 content를 포함하여 전체 데이터를 보조기억장치에서 불러온다. 이렇게 사용하지 않는데 사이즈가 큰 content까지 불러오게 되면서 성능에 영향을 줄 수 있다.

 

이런 문제를 해결하기위해 vertical partitioning을 할 수 있다. 즉, 다음과 같이 content부분만 분리함으로써 게시글들을 조회할때는 id, title, writer_id, created_at, read_cnt, comment_cnt만 불러올 수 있도록하고 특정 게시글을 조회할때 content를 불러올 수 있도록 할 수 있다.

 

id title writer_id created_at read_cnt comment_cnt
... ... ... ... ... ...
id content
... ...

Horizontal Partitioning

유튜브처럼 채널에 대한 사용자의 구독 정보 테이블을 다음과 같다고 해보자.

 

user_id channel_id alarm membership
aaa 1 ... ...
hey 401 ... ...
dingo 395 ... ...
mara 717 ... ...
lol 1 ... ...
son 22 ... ...
aaa 28 ... ...
mara 101 ... ...
aaa 42 ... ...
dingo 42 ... ...

사용자 수가 N이고 채널의 수가 M이라고 한다면 해당 테이블이 가질 수 있는 최대 N * M만큼 가질 수 있다. 그리고 테이블의 크기가 커질 수록 인덱스의 크기도 커진다. 이로 인해 테이블의 read/write 마다 인덱스에서 처리되는 시간이 늘어날 수 있다. 왜냐하면 B-tree를 사용하는 인덱스를 기준으로 삽입/삭제시 마다 B-tree가 조정이 되기 때문이다.

 

이런 문제를 해결하기 위해서 horizontal partitioning을 할 수 있다. horizontal partitioning은 여러 방법(hash-based, range-based 등)이 있으며 hash-based 방법을 많이 사용한다고 한다.

 

hash-based로 horizontal partitioning을 수행한다고 했을 때 두 개의 테이블로 나누기위해 user_id를 hash function에 넣어서 0 또는 1을 출력한다고 해보자. 예를 들어 user_id가 aaa일 경우 0을 출력하고 hey일 경우 1을 출력하도록 만드는 것이다. 그러면 다음과 같이 partitioning을 수행한 결과를 확인할 수 있다.

 

user_id channel_id alarm membership
aaa 1 ... ...
dingo 395 ... ...
aaa 28 ... ...
aaa 42 ... ...
dingo 42 ... ...
user_id channel_id alarm membership
hey 401 ... ...
mara 717 ... ...
lol 1 ... ...
son 22 ... ...
mara 101 ... ...

이 과정에서 hash function에 넣은 user_id를 partition key라 한다.

 

그런데 channel_id로 조회해야할 경우는 어떻게 해야할까? user_id로 조회할 때는 hash function을 통해 출력된 값으로 인해 조회해야할 테이블을 찾을 수 있지만 channel_id는 두 테이블 모두 조회해야한다. 따라서 partition key를 정할 때는 가장 많이 사용될 패턴에 따라 정하는 것이 중요하다. 또한 데이터가 균등하게 분배될 수 있도록 hash function을 정의하는 것도 중요하다.

Sharding

horizontal partitioning처럼 동작한다. 하지만 sharing은 각 partition이 독립된 DB 서버에 저장되는 것이다. 이렇게 독립된 DB 서버에 저장함으로써 백엔드 서버로부터의 요청들을 분산시켜 부하를 줄일 수 있다.

NOTE
sharding에서는 partition key를 shard key라 부르고 각 partition을 shard라 부른다.

Replication

Replication은 하나의 DB 서버에 문제가 발생했을 경우에도 서비스가 중단되지 않도록 할 수 있다. 예를 들어 실제 서비스에서 사용하는 DB 서버와 Copy된 DB 서버를 두며 운영 DB 서버에 write가 일어나면 Copy DB 서버도 똑같이 copy가 되는 것이다. 그리고 운영 DB 서버에 문제가 발생하면 Copy DB 서버를 사용할 수 있는 것이다. (이를 fail over라 부름) 또한 조회 요청이 많을 경우 두 DB 서버에 분산시켜 부하를 줄일 수 있다. 이때 운영 DB 서버를 master/primary/leader라 부르고 copy DB 서버를 slave/secondary/replica라 부른다.

 

[reference]
https://www.youtube.com/watch?v=P7LqaEO-nGU&list=PLcXyemr8ZeoREWGhhZi5FZs6cvymjIBVe&index=29

728x90

'Database' 카테고리의 다른 글

[DATABASE] INDEX(인덱스)  (0) 2023.12.16
[DATABASE] 정규화(Normalization)  (0) 2023.12.15
[DATABASE] Functional Dependency(FD)  (0) 2023.12.13
[DATABASE] MVCC (MultiVersion Concurrency Control)  (0) 2023.12.10
[DATABASE] LOCK (2PL Protocol)  (0) 2023.12.07