본문 바로가기

CS 과목(CS科目)/데이터 베이스(データベース)

26.partitioning ,sharding, replication

partitioning(vertical partitioning , horizontal partitioning)

database table을 더 작은 table들로 나누는 것.

vertical partion

vertical partion의 사용예시

1. 정규화

2. 민감한 정보에는 제한을 더 걸어서 보호하기 위하여 vertical partion을 할 수가 있다. 

3. 자주 사용되는 attribute들만 모아서 partion을 만들 수가 있고, 자주 사용되지 않는 attribute만 모아서 partion을 만들 수 있다.

-> vertical partion은 꼭 정규화에만 사용되는 것이 아니라 또 1,2,3 때에만 사용되는 것이 아니라 여러 상황에서 사용된다.

정규화 과정은 결국에는 vertical partitioning의 한 종류이다. 

vertical paritioning을 사용하는 또 다른 예제를 아래에서 살펴 보자.

예제를 살펴 보기에 앞서, HDD or SDD에 저장돼 있는 DB에서 어떻게 데이터를 읽어 들여 오는지에 대해 간략하게 살펴 

보자. 

위 페이지를 렌더링해주기 위해서는 ARTICLE 테이블에서 content column을 제외한 attribute가 필요하다.

해당 attribute를 읽기 위하여 위 그림에도 나와 있듯이 select문을 실행을 한다.

구체적인 과정

1. DBMS가 "FROM article WHERE..."을 보고, 이 조건(condition)에 해당하는 tuple들을 모두 읽어서 메모리에 로드시킨다.

2. "SELECT id..."를 보고 로드된 tuple들 중에서 column : id ~ comment_cnt까지(content column은 제외)를 추출한다.

-> 만약 content(게시글) attribute의 크기가 굉장히 크면 어떻게 될까???

페이지의 렌더링을 위해서는 content attribute가 필요하지 않음에도 불구하고, 굉장히 큰 사이즈의 content도 같이 불러 들이므로 매우 비효율적이다.  

Solution : vertical partitioning을 통해 contentcolumn을 아래와 같이 분할. 

 

게시글(content)을 렌더링하기 위해서는 더이상 article이 아니라, article_content table에서 read를 한다.

vertical partitioning을 통해 content를 분할을 해줌으로써, content값이 필요할 때에만 그 큰 사이즈의 데이터를 읽어 들이

므로 매우 효율적이다.  

# of users N : 총 user의 수

# of channels M : 총 channel의 수

-> SUBSCRIPTION(구독자 정보) 테이블은 최대 N*M개의 tuple을 가질 수가 있다. 

참고로, DB에서의 읽기란 SELECT!

DB에서의 쓰기란 {INSERT,UPDATE,DELETE}!( 테이블에 변화를 주는 작업 )

horizontal partitioning은 분할 후에도, schema에는 변화가 없다는 특징이 있다. 

horizontal partitioing을 하기 위해서 사용된 key값을 partion key라고 부른다. 

기존의 subscription 테이블은 이제 사라지고, 2개의 partition이 생성이 된다. 

dingyo가 구독한 채널들 정보를 모두 조회하고 싶을 떄에는 dingyo의 user_id( partiton key )를 이용하여 해당 테이블만 탐색을 하면된다.

그러나 channel_id가 1인 채널을 구독한 user_id를 조회하고 싶다면 어떻게 해야 할까??

위의 partition은 user_id를 기준으로 하여 테이블을 분할을 하였다.

고로, channel_id가 1인 tuple은 명확히 분할되지 않았기에, 위 2개의 테이블을 모두 full scan을 하여야 한다.

이러한 이유로 partition key는 가장 많이 사용될 패턴에 따라 정하는 것이 중요!

(hash function이 데이터를 균등하게 분배하도록 설계하는 것도 중요!)

참고로, hash_based horizontal partition은 한 번 partition으로 분할시키고 나면, 그 이후에 또 한번 parition을 나누는

것이 매우 어렵다. 

예를 들어서 기존에는 2개의 partition이 존재를 하였는데, hash function의 결과값을 {0,1}에서 {0,1,2,3}으로 늘려서, 2개

의 partition을 더 만들고 싶다고 하자.

이렇게 되면, 기존의 2개의 partition에 있던 데이터들도 다시 새로운 partition으로 데이터를 옮기는 작업이 필요하다.

그러나 만약 서비스 중이라면, 이러한 작업들을 하기가 매우 조심스럽다. 

고로, 처음 partitioning을 할 때 신중하게 해야 한다는 것을 기억하자

horizontal partitioning 같은 경우에는, 만약 클라이언트의 요청이 폭주하였을 때, 모두 같은 DB 서버에 요청을 보내기 때문

에 DB 서버의 CPU와 메모리에 부하가 심하게 걸리므로, 퍼포먼스가 좋지 않다. 

Solution : Sharding

sharding을 하게 되면 각 partition을 이제는 shard라고 부르게 되며, partition key(user_id)를 shard key라고 부르게 된다. 

주 서버(master server)는 항상 부 서버(slave server)로 실시간으로 데이터를 copy를 해준다.

그 목적은 master server에서 만약 에러가 발생을 했을 때, 그 에러를 대처하기 위해서이다.(이러한 방법을 failover이라고 한다.)

만약 master server에 에러가 감지가 되면, Spring 서버와 같은 logic tier는 slave server로 read/write 요청을 보내어서 서비

스를 지속시킨다.

그리고 DB 서버는 주로 write 작업보다는 read작업을 많이 하므로, read에 대한 트래픽이 많다.

replication을 사용하면, 위 그림과 같이 read에 대한 트래픽을 분산시켜 서버의 부하를 줄일 수가 있다. 

(참고로, 위 그림에서는 slave server가 1대이지만, 2대 이상이여도 전혀 문제가 되지 않는다. 오히려 그게 더 안전하다)

sharding vs replication

sharding은 다른 테이블들을 다른 DB 서버에 저장.

replication은 같은 테이블들을 다른 DB 서버에 저장.