티스토리 뷰

DataBase

Sharding 방법.

RyanGomdoriPooh 2016. 6. 21. 14:05

샤딩이라는 것은 데이터를 파티셔닝하는 방법이다.


파티셔닝을 하는 방식에는 1) 수직적 파티셔닝 2) 수평적 파티셔닝 으로 나뉩니다.


사진 data, 동영상 data 로 두가지 종류의 data가 있고, 저장할 DB가 1번, 2번이 있다고 하면,


수직적인 방식으로는 1번 DB에 사진 data를 저장하고, 2번 DB에 동영상 data를 저장하는 방식.


수평적인 방식으로는 1번과 2번 DB에 사진 data의 일부분을 분할 저장, 마찬가지로 동영상 data도 1,2번 DB에 분할 저장하는 방식이다.




본격적으로 샤딩의 방법에 대해서 이야기 합니다.


데이터 베이스에 관해서 샤딩을 고려할 때 먼저 고려되어야 하는 부분은 데이터 베이스의 퍼포먼스를 Scale-Up 하는 것이다.

 

샤딩은 데이터를 다른 공간에 나누는 작업이다. 한 대의 데이터 베이스에서 합리적인 속도가 필요하거나 스토리지 용량을 초과하는 경우, 샤딩을 하면서 용량을 늘리는 형식으로 진행이 된다.

 

몽고DB에서는 하나의 replica set(primary, secondary로 구성된 set)Shard라고 명명한다.

 

보통 샤드는 논리적인 샤드들로 처음 고려하게 된다.

 

샤드는 대부분 2의 배수로 정의 되어있다. 실제로 대부분의 서비스는 샤드를 1024로 나눈다.

Instagram의 경우에는 4096으로 나누었다. 둘 다 실제로 사용되기 적절한 값이다.

 

간단하게 하기 위해서 예제에서는 4개의 논리적 샤드로 시작하겠습니다. 먼저 사용자들의 집합에 대한 예를 보겠습니다.

 

id | email | name

----+---------------------------+-----------------

1 | craig.kerstiens@gmail.com | Craig Kerstiens

2 | john.doe@gmail.com | John Doe

3 | jane.doe@gmail.com | Jane Doe

4 | user4@gmail.com | User 4

5 | user5@gmail.com | User 5

6 | user6@gmail.com | User 6

7 | user7@gmail.com | User 7

8 | user8@gmail.com | User 8

 

이것들을 논리적 샤드로 나누면, 다음과 같은 결과를 볼 수 있습니다.

----------------------------------------------------------

1 | craig.kerstiens@gmail.com | Craig Kerstiens

5 | user5@gmail.com | User 5

----------------------------------------------------------

2 | john.doe@gmail.com | John Doe

6 | user6@gmail.com | User 6

----------------------------------------------------------

3 | jane.doe@gmail.com | Jane Doe

7 | user7@gmail.com | User 7

----------------------------------------------------------

4 | user4@gmail.com | User 4

8 | user8@gmail.com | User 8

----------------------------------------------------------

 

샤딩할 때, 중요한 것은 특정 데이터베이스에 집중되어서 저장되지 않는 것입니다.

그래서 그런 로직을 만들어야합니다.

 

샤딩할 때, 요청시 특정 데이터베이스에 집중되지 않는 매커니즘을 발견하는 것은 중요합니다. 위의 예에서는 데이터베이스 안의 rowID 값을 이용했지만,

logical_shard = hash(User.id) % 4

 

email과 같은 고유값을 가지고 sharding도 가능하다.

logical_shard = hash(User.email) % 4

 

Physical Shards

 

Logical Sharding이 고려가 되어서 끝나면 이제는 Physical Sharding만 남아 있습니다.

 

물리적으로 하나의 샤드를 가지고 있다고 해서 물리적인 형식의 샤딩을 못하는 게 아니고 어플리케이션 단계에서는 가능합니다.

 

접근 가능한 물리적 샤드는 존재하는 논리적 샤드와 존재하는 물리적 샤드의 모듈러 연산을 통해서 쉽게 찾을 수 있습니다.

total_physical_shards = 2

total_logical_shards = 4

logical_shard = hash(User.email) % total_logical_shards

physical_shard = logical_shard % total_physical_shards

 

위 공식은 즉,



 

| 1 5 |

 

| 2 6 |

 

| 3 7 |

 

| 4 8 |

 

4가지의 Logical Sharding으로 나누었을 때, 예를 들어, 한 덩이 1 5 Logical Shard 1개라고 하면, 이것을 다시 물리적인 공간으로 다음과 같이 두 부분으로 나누어집니다.



 

| 1 5 || 3 7 |

 

| 2 6 || 4 8 |

 

, 물리적으로 logical shard①③ , ②④ 로 두 부분으로 나누었습니다.




Primary Key를 만드는 방법에 대해서는

 

여러 부분으로 분배한 샤드의 primary key를 정수형을 이용해서 사용한다면 중복이 될 경우가 생길 수 있습니다.

 

중복이 된다면 큰 문제를 발생할 수 있기 때문에 유일한 키가 될 수 있는 User ID를 만들어야 합니다.

 


초기 용량을 넘어서서 용량을 늘려가는 방법

 

처음으로 존재하는 각 물리적 샤드에 follower 를 추가합니다.

follower는 처음 서비스의 데이터베이스의 복제본을 만들어서 샤드 과정에 쓰이는 것입니다.

 

follower 추가


 

 

 

2. follower Write가 가능한 독립적인 데이터베이스로 권한을 부여해줍니다.

아래 데이터베이스는 데이터베이스 입력 시, 동시에 권한을 부여한 follower와 같이 데이터가 쓰이는 상태입니다.


 

3. 이 시점에서 리플리케이션으로 자동으로 데이터베이스를 복제하는 것을 끊고, 서로 다른 데이터베이스를 가지고 있기 위해서

예를 들면 DB 0, 2가 서로 구분되기 위해서 중복되지 않게 삭제를 해줍니다.

DB 1, 3도 마찬가지입니다.

 

결론은 처음 DB 0, 1로 나누어서 두 DB를 번갈아가면서 저장했었는데 결론은 네 부분 DB로 용량이 두 배로 증가하였고, 데이터는 0,1,2,3 이렇게 4개의 DB에 나누어 담겨지게 되었습니다.


 

샤딩을 하려면 고유한 UUID(universally unique identifier)를 사용해야합니다.

결국 UUID를 사용해서 고유한 값을 이용해 샤드를 구분해서 저장하기 위함입니다.


이런 형식으로 샤드를 추가하면서 용량을 추가할 수 있습니다.


Reference : 

인스타그램 블로그 - http://instagram-engineering.tumblr.com/

댓글
댓글쓰기 폼
공지사항
Total
494,172
Today
228
Yesterday
138
링크
TAG
more
«   2022/01   »
            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          
글 보관함