1 - ring 이란
2 - swift는 어떻게 안전하게 데이터를 보관하는가?
3 - swift는 어떻게 확장하는가?
balance
만약 책장이 가득차려고 해서 책장마다 칸막이를 한개씩 더 추가해 본더고 가정하자.
만약 그렇다면 다음과 같이 책장이 변할 것이다. 아래의 그림과 같이 총 20개의 칸막이(device)를 사용하게 될 것이다.
이 때 장부를 업데이트 하려고 하니 각 책장의 1,2 번 칸막이가 3,4 번 칸막이보다 장부에 많이 기입이 됐다.
어떤 일이 일어날지 생각을 해본다면 각 책장의 1,2번 칸막이는 3,4번 칸막이 보다 2배로 많은 카드를 저장 하게 될 것이다.
왜냐하면 장부에 2배로 더 많이 기입이 되었기 때문이다. (1,2번 칸막이는 2번 기록 / 3,4번 칸막이는 1번 기록) 그렇기 때문에 1,2번 칸막이가 3,4번 칸막이 보다 많은 카드를 저장하게 되어 분배가 적절히 일어 나지 못할것이다. 여기서 우선 중요한 것은 장부에 2배로 더 많이 기입되면 카드가 들어 올때 저장될 확률이 2배로 더 높다는 점이다.
그렇다면 현재 장부가 얼마나 잘못 분배되었는지 알아보자.
우선 기본적으로 생각할 수 있는 수치이다.
이 수치를 결정하는 이유는 사실 가장 심플하게 공간을 할당하는 방법은 공간 / 칸막이가 나누어 떨어질 때 이다. 만약 이렇다면 남거나 모자라지 않고 모든 칸막이들이 동일한 비율로 공간에 기입이 가능하다.
하지만 실제 클러스터에는 공간 / 칸막이가 정확하게 나누어 떨어지기는 힘들다.
(공간은 replica 개수 * partition 총 개수이며 칸막이는 zone 개수 * zone 당 device 개수이다.) 그렇기 때문에 어떤 칸막이는 공간을 더 받고 어떤 칸막이는 공간을 덜 받게 되는 상태가 나타나며
그렇기 때문에 어떤 칸막이는 카드를 더 저장하게 되고 어떤 칸막이는 카드를 덜 저장하게 되는 문제가 발생한다. 그리 고 이런 더 받거나 덜 받는 정도는 공식을 통해서 미리 유추해 볼 수 있다.
위의 예제로 이 값을 계산해 보면
30/20 으로 칸막이 한개는 장부에 1.5번씩 기록되어야 한다.
이 값이 현재 이상적으로 공간을 할당할 횟수이다.
그렇다면 이제 어떤 칸막이가 공간을 할당한 횟수를 보자.
장부를 살펴보면 1,2번 칸막이들은 (뒤에서 -1, -2로 끝나는) 3,4번 칸막이들에 (뒤에서 -3, -4로 끝나는) 비해서 2 배 더 많이 기입이 되어 있다.
즉 1,2번 칸막이는 2개씩 공간이 할당 되어져 있고 3,4번 칸막이는 1개씩 공간이 할당 되어져 있다.
그렇다면 1개 공간이 할당된 칸막이(3,4번 칸막이들)가 얼마나 적은 비율로 공간이 할당 된것인지 계산해 보자.
비율적으로 계산해 보면
swift에서는 이런 균등히 저장 될 수 있는 지에 대한 척도를 balance라고 표현한다.
우선 현재는 후에 나올 weight라는 값을 제하고 생각을 한다면 아래와 같이 계산 할 수 있다. (현재 모든 칸막이의 크기가 동일해서 동일한 weight를 갖는다고 가정)
총 공간 / 총 칸막이의 개수는 1.5 이다.
즉 1 - 현재 칸막이에 할당된 공간 / ( 총 공간 / 총 칸막이 개수 ) 는 1/3 이고 결과 balance는 33% 이다.
비슷하게 그렇다면 2개 공간이 할당된 칸막이 (1,2번 칸막이들)이 얼마나 남는 비율로 공간이 할당 된것인지 계산해 보자.
만약 20개의 칸막이가 있고 장부의 공간이 20개라고 가정해 보자 그렇다면 이상적으로 기록할 개수가 1인 자연수가 나옴으로 현재 기록될 공간의 수도 1로 생각할 수 있다.
이 때 장부를 업데이트 하려고 하니 각 책장의 1,2 번 칸막이가 3,4 번 칸막이보다 장부에 많이 기입이 됐다.
어떤 일이 일어날지 생각을 해본다면 각 책장의 1,2번 칸막이는 3,4번 칸막이 보다 2배로 많은 카드를 저장 하게 될 것이다.
왜냐하면 장부에 2배로 더 많이 기입이 되었기 때문이다. (1,2번 칸막이는 2번 기록 / 3,4번 칸막이는 1번 기록) 그렇기 때문에 1,2번 칸막이가 3,4번 칸막이 보다 많은 카드를 저장하게 되어 분배가 적절히 일어 나지 못할것이다. 여기서 우선 중요한 것은 장부에 2배로 더 많이 기입되면 카드가 들어 올때 저장될 확률이 2배로 더 높다는 점이다.
그렇다면 현재 장부가 얼마나 잘못 분배되었는지 알아보자.
우선 기본적으로 생각할 수 있는 수치이다.
총 집어 넣을 수 있는 물리적인 칸막이의 수 = 20 = 책장 5개 * 칸막이 4개기본적으로 이하의 공식 및 내용에는 횟수를 공간 / 칸막이 로 설명하겠다.
총 장부에 적을 수 있는 공간 = 30 = 카드 3장 * 카드 고유번호 마지막자리의 수 10
횟수 = 공간 / 칸막이또한 칸막이당 이상적으로 공간을 할당할 횟수(유리수 가능)를 정하자.
이 수치를 결정하는 이유는 사실 가장 심플하게 공간을 할당하는 방법은 공간 / 칸막이가 나누어 떨어질 때 이다. 만약 이렇다면 남거나 모자라지 않고 모든 칸막이들이 동일한 비율로 공간에 기입이 가능하다.
하지만 실제 클러스터에는 공간 / 칸막이가 정확하게 나누어 떨어지기는 힘들다.
(공간은 replica 개수 * partition 총 개수이며 칸막이는 zone 개수 * zone 당 device 개수이다.) 그렇기 때문에 어떤 칸막이는 공간을 더 받고 어떤 칸막이는 공간을 덜 받게 되는 상태가 나타나며
그렇기 때문에 어떤 칸막이는 카드를 더 저장하게 되고 어떤 칸막이는 카드를 덜 저장하게 되는 문제가 발생한다. 그리 고 이런 더 받거나 덜 받는 정도는 공식을 통해서 미리 유추해 볼 수 있다.
칸막이당 이상적으로 공간을 할당할 횟수이하 이상적으로 공간을 할당할 횟수 라고 표현 하겠다.
= 총 장부에 적을 수 있는 공간 / 총 집어 넣을 수 있는 물리적인 칸막이 수
위의 예제로 이 값을 계산해 보면
30/20 으로 칸막이 한개는 장부에 1.5번씩 기록되어야 한다.
이 값이 현재 이상적으로 공간을 할당할 횟수이다.
그렇다면 이제 어떤 칸막이가 공간을 할당한 횟수를 보자.
장부를 살펴보면 1,2번 칸막이들은 (뒤에서 -1, -2로 끝나는) 3,4번 칸막이들에 (뒤에서 -3, -4로 끝나는) 비해서 2 배 더 많이 기입이 되어 있다.
즉 1,2번 칸막이는 2개씩 공간이 할당 되어져 있고 3,4번 칸막이는 1개씩 공간이 할당 되어져 있다.
그렇다면 1개 공간이 할당된 칸막이(3,4번 칸막이들)가 얼마나 적은 비율로 공간이 할당 된것인지 계산해 보자.
비율적으로 계산해 보면
남거나 부족하게 기록된 현재 기록된 공간의 개수 : 이상적으로 기록되야할 공간 개수위의 예제로 보면 총 1.5번 기록되는 중에 횟수와의 차이는 1.5 - 1 = 0.5번 만큼 차이가 난다. 즉 0.5 : 1.5 만큼 더 부족하게 분배 된 것이다. 수치상으로 표현하기 위해 이 값을 0.5/1.5= 1/3 이라고 표현하고 백분율로 33% 라고 표현한다. (a를 이용해서 생각한 방식)
= ( 이상적으로 기록되야할 공간 개수 - 현재 기록된 공간의 개수) : 이상적으로 기록되야할 공간 개수 ... (a)
=1 - ( 현재 기록된 공간의 개수 / 이상적으로 기록되야할 공간 개수) : 1 ... (b)
swift에서는 이런 균등히 저장 될 수 있는 지에 대한 척도를 balance라고 표현한다.
우선 현재는 후에 나올 weight라는 값을 제하고 생각을 한다면 아래와 같이 계산 할 수 있다. (현재 모든 칸막이의 크기가 동일해서 동일한 weight를 갖는다고 가정)
balance = 절대값( 1 - 현재 칸막이에 할당된 공간 / ( 총 공간 / 총 칸막이 개수 ) ) * 100% (b를 이용해서 생각한 방식)위의 예제로 다시 생각해 보면 현재 칸막이에 할당된 공간은 1 이다.
총 공간 / 총 칸막이의 개수는 1.5 이다.
즉 1 - 현재 칸막이에 할당된 공간 / ( 총 공간 / 총 칸막이 개수 ) 는 1/3 이고 결과 balance는 33% 이다.
비슷하게 그렇다면 2개 공간이 할당된 칸막이 (1,2번 칸막이들)이 얼마나 남는 비율로 공간이 할당 된것인지 계산해 보자.
balance = 33% = abs( 1 - 2 / 1.5 ) * 100%이렇게 현재 모든 칸막이(1,2,3,4번)들은 모두 33% 정도의 남거나 부족한 비율로 balance가 형성된다. 보통 swift에 서 밸런스는 이러한 각 칸막이들의 balance중에서 최고로 큰 값이 설정 된다.
만약 20개의 칸막이가 있고 장부의 공간이 20개라고 가정해 보자 그렇다면 이상적으로 기록할 개수가 1인 자연수가 나옴으로 현재 기록될 공간의 수도 1로 생각할 수 있다.
balance = 0% = abs( 1 - 1 / 1 ) * 100%와 같이 0이 계산 될 것이다.
- 즉, balance가 0에 가까우면 가까울 수록 데이터가 골고루 분산된다.
- 반대로, balance가 높으면 높을 수록 데이터 몰림 현상이 일어난다.(ring 안에 다른 device에 비해 많이 기록되는 device가 존재한다는 의미)
partition의 개수의 중요성
그렇다면 어떻게 하면 이 문제를 해결 할 수 있을까?
가장 간단한 방법은 처음 장부를 만들때 카드 고유번호의 마지막 자리만 쓰는게 아니라 마지막 2자리를 쓰면 된다. 만 약 그렇다면 공간이 300개(카드3장 * 카드 고유번호 마지막 2자리(100))가 될 것이다.
그렇다면 이상적으로 공간을 할당할 횟수 = 15 = 300 / 20 로 모든 칸막이들을 15번씩만 기입하면 문제가 해결 가능할 것이다.
그렇다면 고유번호 마지막 자리만 쓰는게 아닌 고유번호 마지막 2자리를 쓰는 의미는 무엇인가?이는 partition의 개수를 높게 설정한 것이다.
하지만 실제 상황에서 partition 개수를 증가 시키는 것은 매우 힘들다. (예를 들어 swift에서 제공하는 툴은 이런 기능을 생각하지 않았다.)
그렇기 때문에 초반에 ring을 제작할때 어느정도 이상의 partition 개수를 생각해야 한다.
swift에서는 그렇기 때문에 partition 개수 = 2 ^ partition_power 로 2의 배수개로 partition의 개수를 생성한다.
그렇다면 다음은 예제는 쉽게 나누어 떨어지는 상태가 되었지만 그에 반해 실제 수치와 같이 쉽게 나누어 떨어지지 않
는 상황을 생각해 보자.
만약 300개의 공간이 있는데 칸막이가 23개 있는 경우 이 때는 13.04 개 만큼씩 할당 되고
대략 13개가 할당되는 칸막이와 14개가 할당되는 칸막이가 생길 것이다. 이때 balance는 아래와 같다.
대략 13개가 할당되는 칸막이와 14개가 할당되는 칸막이가 생길 것이다. 이때 balance는 아래와 같다.
13개가 할당되는 칸막이
balance = 0.3% = abs( 1 - 13 / 13.04 ) * 100%
= abs( (13.04 - 13) / 13.04 ) * 100%
= abs( 0.04 / 13.04 ) * 100%
14개가 할당되는 칸막이
balance = 7.4% = abs( 1 - 14 / 13.04 ) * 100%
= abs( (13.04 - 14) / 13.04 ) * 100%
= abs( -0.96 / 13.04 ) * 100%
그렇기 때문에 balance는 7.4% 이다.
그렇다면 3000개의 공간이 있을때 칸막이가 23개 있다면 이 때는 130.43 개 만큼씩 할당 되고
대략 130개가 할당되는 칸막이와 131개가 할당되는 칸막이가 생길 것이다. 이때 balance는 아래와 같다.
그렇다면 3000개의 공간이 있을때 칸막이가 23개 있다면 이 때는 130.43 개 만큼씩 할당 되고
대략 130개가 할당되는 칸막이와 131개가 할당되는 칸막이가 생길 것이다. 이때 balance는 아래와 같다.
130개가 할당되는 칸막이
balance = 0.3% = abs( 1 - 130 / 130.43 ) * 100%
= abs( (130.43 - 130) / 130.43 ) * 100%
= abs( 0.43 / 130.43 ) * 100%
131개가 할당되는 칸막이
balance = 0.4% = abs( 1 - 131 / 130.43 ) * 100%
= abs( (130.43 - 131) / 130.43 ) * 100%
= abs( 0.57 / 130.43 ) * 100%
그렇기 때문에 balance는 0.4% 이다.
위 식들에 차이점을 보면 알겠지만 공간의 개수(partition의 개수 * replica)의 크기가 커지면 커질 수록 분모의 크기가 커진다 13.04 -> 130.43
이를 위해 아래 식으로 설명 하겠다.
물론 두 식은 같은 식이지만 표현을 편하게 하기 위해서 위와 같이 표현하고 a를 이용해서 설명한다면 balance = 절대 값( 1 - 현재 칸막이에 할당된 공간 / ( 총 공간 / 총 칸막이 개수 ) ) * 100% (b를 이용한 표현 방식) = 절대값( ( 이 상적으로 할당된 공간 - 현재 칸막이에 할당된 공간 ) / 이상적으로 할당된 공간 ) * 100% (a를 이용한 표현 방식)
이상적으로 할당된 공간과 현재 칸막이에 할당된 공간의 차이는 공간의 수가 극도로 작지 않는한 대부분 0~1 사이의 유리수 이다. 그렇기 때문에 분모인 이상적으로 할당된 공간에 크게 좌우 되는데 이 값은 공간의 개수(partition의 개수 * replica)의 크기가 커지면 커질 수록 커질 수 있는 것이다.
그렇기 때문에 ring을 설계할때 partition 수는 어느 정도 이상 크기를 생각해야 된다.
즉 partition 수가 크면 클 수록 분배는 더욱 고르게 된다고 생각할 수 있다.
만약 partition 수를 hash data 개수 만큼 만든 다면 정말 가장 정확하게 분배 가능할 것이다.
하지만 그렇게 되면 ring의 크기가 커지므로(partition * replica 가 ring의 크기이기 때문에) 엄청난 크기의 ring을 메모 리에 놓고 관리하기 힘들 것이다. 또한 이전에 설명한 것과 같이 만약에 partition 수가 hash data 개수 만큼 커지면 카 드를 복사할때 바구니 채가 아닌 일일히 복사 해야 되서 replication에 대한 비용이 증가 할 것이다.
그렇기 때문에 partition 수는 적정 수준을 유지해야 한다.
weight
그렇다면 이번엔 만약 2배 크기의 칸막이를 추가 했다고 가정해 보자.
2배 크기의 칸막이는 보통의 칸막이에 비해 2배로 많은 양을 저장할 수 있어야 골고루 분배가 된다고 생각할 수 있다. 그렇기 때문에 장부안에서 2배 크기의 칸막이는 보통의 칸막이에 비해 2배로 많이 기입되어야 한다.
고유번호 뒤의 2자리를 써서 바구니의 개수가 100인 상태이다. 이때 그렇다면 각 칸막이가 장부에서 차지할 공간을 계산해 보자.
우선 weight 1당 몇개의 공간이 할당 될지 계산을 한 이 후 그 값에 weight 값을 곱하면 몇개의 공간이 할당 되야 할지 계산 할 수 있다.
위 식들에 차이점을 보면 알겠지만 공간의 개수(partition의 개수 * replica)의 크기가 커지면 커질 수록 분모의 크기가 커진다 13.04 -> 130.43
이를 위해 아래 식으로 설명 하겠다.
물론 두 식은 같은 식이지만 표현을 편하게 하기 위해서 위와 같이 표현하고 a를 이용해서 설명한다면 balance = 절대 값( 1 - 현재 칸막이에 할당된 공간 / ( 총 공간 / 총 칸막이 개수 ) ) * 100% (b를 이용한 표현 방식) = 절대값( ( 이 상적으로 할당된 공간 - 현재 칸막이에 할당된 공간 ) / 이상적으로 할당된 공간 ) * 100% (a를 이용한 표현 방식)
이상적으로 할당된 공간과 현재 칸막이에 할당된 공간의 차이는 공간의 수가 극도로 작지 않는한 대부분 0~1 사이의 유리수 이다. 그렇기 때문에 분모인 이상적으로 할당된 공간에 크게 좌우 되는데 이 값은 공간의 개수(partition의 개수 * replica)의 크기가 커지면 커질 수록 커질 수 있는 것이다.
그렇기 때문에 ring을 설계할때 partition 수는 어느 정도 이상 크기를 생각해야 된다.
즉 partition 수가 크면 클 수록 분배는 더욱 고르게 된다고 생각할 수 있다.
만약 partition 수를 hash data 개수 만큼 만든 다면 정말 가장 정확하게 분배 가능할 것이다.
하지만 그렇게 되면 ring의 크기가 커지므로(partition * replica 가 ring의 크기이기 때문에) 엄청난 크기의 ring을 메모 리에 놓고 관리하기 힘들 것이다. 또한 이전에 설명한 것과 같이 만약에 partition 수가 hash data 개수 만큼 커지면 카 드를 복사할때 바구니 채가 아닌 일일히 복사 해야 되서 replication에 대한 비용이 증가 할 것이다.
그렇기 때문에 partition 수는 적정 수준을 유지해야 한다.
weight
그렇다면 이번엔 만약 2배 크기의 칸막이를 추가 했다고 가정해 보자.
2배 크기의 칸막이는 보통의 칸막이에 비해 2배로 많은 양을 저장할 수 있어야 골고루 분배가 된다고 생각할 수 있다. 그렇기 때문에 장부안에서 2배 크기의 칸막이는 보통의 칸막이에 비해 2배로 많이 기입되어야 한다.
고유번호 뒤의 2자리를 써서 바구니의 개수가 100인 상태이다. 이때 그렇다면 각 칸막이가 장부에서 차지할 공간을 계산해 보자.
x는 크기가 1인 칸막이가 장부에서 차지할 공간의 개수 (1,2,3 칸막이)즉 15개의 보통 크기의 칸막이(1,2,3 칸막이)는 12번 기입(칸막이당 12개의 공간)되어야 하고 5개의 2배 크기의 칸막이(4번 칸막이)는 24번 기입(칸막이당 24개의 공간)되면 올바르게 기입된다.
x * 2는 크기가 2인 칸막이가 2배 기입되어야 한다는 의미 (4 칸막이)
(카드3장 * 카드 고유번호 마지막 2자리(100)) = (보통 크기 칸막이 개수) * x + (2배 크기의 칸막이 개수) * (x * 2)
300 = 15 * x + 5 * (x * 2) 이기 때문에
x = 12
이런 칸막이의 크기를 swift에서는 weight라고 표현한다.다시 weight를 적용해서 balance를 계산하는 방법을 생각해 보자.
weight는 일반적으로 비율로 계산해서 생각한다. 예를 들면 보통 크기의 칸막이 를 1 2배 크기의 칸막이를 2로 생각할 수 있다.
우선 weight 1당 몇개의 공간이 할당 될지 계산을 한 이 후 그 값에 weight 값을 곱하면 몇개의 공간이 할당 되야 할지 계산 할 수 있다.
weight 1당 몇개의 공간이 할당 될지의 값 = ( 총 공간 / 모든 칸막이의 weight값의 합)이를 위해 balance를 계산하는 식을 다시 정리해 본다면 아래와 같이 정리 가능하다.
이상적으로 공간을 할당할 횟수 = weight 1당 몇개의 공간이 할당 될지의 값 * 현재 칸막이의 weight
balance = 절대값( 1 - 현재 칸막이에 할당된 공간 / 이상적으로 공간을 할당할 횟수 ) * 100%위의 예를 이용해서 다시 한번 계산해 보자.
= 절대값( 1 - 현재 칸막이에 할당된 공간 / ( weight 1당 몇개의 공간이 할당 될지의 값 * 현재 칸막이의 weight ) ) * 100%
= 절대값( 1 - 현재 칸막이에 할당된 공간 / ( ( 총 공간 / 모든 칸막이의 weight값의 합) * 현재 칸막이의 weight ) ) * 100%
모든 칸막이의 weight값의 합 = 15 * 1 + 5 * 2 = 25
총 공간 = 300
보통 크기의 칸막이의 balance (1,2,3 칸막이)
현재 칸막이의 weight = 1
현재 칸막이가 할당된 공간 = 12
balance = 절대값( 1 - 12 / ( ( 300 / 25 ) * 1 ) ) * 100%
= 절대값( 1 - 1 ) * 100%
= 0%
2배 크기의 칸막이의 balance (4 칸막이)
현재 칸막이의 weight = 2
현재 칸막이가 할당된 공간 = 24
balance = 절대값( 1 - 24 / ( ( 300 / 25 ) * 2 ) ) * 100%
= 절대값( 1 - 1 ) * 100%
= 0%
여기 까지 partition 크기의 중요성과 balance 그리고 weight에 대해서 알아 보았다.
현재까지 가이드를 읽었으면 다음 개념에 대해서 정리하자.
* balance
* weight
현재까지 가이드를 읽었으면 다음 개념에 대해서 정리하자.
* balance
* weight
댓글 없음:
댓글 쓰기