• 카산드라-3부 : 파티셔닝

    2018. 9. 16. 19:22

    by. 위지원

    랜덤 파티셔너에 사용할 이상적인 초기 토큰 구하기


    카산드라는 일관적 해싱을 이용한다. 일관된 해싱은 분산 캐싱을 위해 나타난 것으로 링 형태의 Hasing을 해서 각 노드 사이에는 일종의 구간이 있어 데이터의 해싱값은 해당 구간에 배치되게 된다. 이러한 해싱을 이용하게 되면 노드가 삭제되거나 추가 되는 경우에 해당 구간을 나누거나 넘기는 식으로만 진행하면 된다는 이점이 있다. 추가적으로 더 말하자면 이때 데이터가 어느 한 노드에만 집중적으로 몰리는 상황을 방지하고자 가상 노드를 추가하여 밸런스를 맞춰준다. 



    각 노드들은 초기 토큰(링 위에서 위치를 나타내는용도)을 가지게 되고 초기 토큰들은 keyspace를 균등하게 분할한다. 파티셔너는 데이터의 row key를 이용해서 token을 계산하게 되는데, data의 token보다 크지 않으면서 가장 가까운 초기 토큰을 가진 노드의 데이터는 다른 복제본과 함께 저장된다. 초기 토큰은 아래와 같이 구할 수 있다.


    초기 토큰 = Zero_Indexed_Node_Number * ((2^127) / Number_Of_Nodes)


    예를 들어서 5개의 노드가 있는 클러스터에서 3번째 노드의 초기 토큰을 구하고자 하면 2*((2^127)/5)를 이용해서 초기토큰을 구할 수 있다.


    위의 식으로 예제를 하나 작성해서 결과를 살펴보자.


    [weejw@com hpcbuild]$ cat src/java/hpcas/c01/InitialToken.java
    package hpcas.c01;

    import java.math.*;

    public class InitialToken{
        public static void main(String[] args){
            if(System.getenv("tokens") == null){
                System.err.println("Usage: tokens=5 ant -DclassToRun=InitialTokens run");
                System.exit(0);
            }
           
            int nodes = Integer.parseInt(System.getenv("tokens"));
            for(int i=0; i<nodes;i++){
                BigInteger hs  = new BigInteger("2");
                BigInteger res = hs.pow(127);
                BigInteger div = res.divide( new BigInteger(nodes+""));
                BigInteger fin = div.multiply( new BigInteger(i+""));
                System.out.println(fin);
            }
        }
    }


    그리고나서 아래와 같이 명령어를 실행하면 다음과 같이 결과를 알 수 있다.


    [weejw@com hpcbuild]$ tokens=5 ant -DclassToRun=hpcas.c01.InitialToken run
    Buildfile: /home/weejw/hpcbuild/build.xml

    init:

    compile:
        [javac] Compiling 1 source file to /home/weejw/hpcbuild/build/classes

    dist:
          [jar] Building jar: /home/weejw/hpcbuild/dist/lib/hpcas.jar

    run:
         [java] 0
         [java] 34028236692093846346337460743176821145
         [java] 68056473384187692692674921486353642290
         [java] 102084710076281539039012382229530463435
         [java] 136112946768375385385349842972707284580

    BUILD SUCCESSFUL
    Total time: 2 seconds



    위 결과에 있는대로 각 노드에 대해 등거리 숫자를 생성해 저장되는 데이터가 균형을 이룰 수 있도록 하고 노드에 대한 요청도 균형을 이루게 한다. 

    처음으로 카산드라 서버를 구동할때는 cassandra.yaml 파일에 initial_tokens필드에 숫자를 이용하면 된다고 한다.


    순서 보존 파티셔너에 사용할 초기 토큰 선택하기


    위에는 제목에 나와있는 것 처럼 파티셔너를 랜덤하게 할때는 좋지만 key의 순서가 필요할때는 불균형하게 key를 가지는 경우가 생길 수도 있다.


    cassandra.yaml 파일을 보면 아래와 같은 속성이 있다. 여기에서 속성을 변경하면 파티셔닝의 방법을 변경할 수 있다.

    org.apache.cassandra.dht.(OrderPresevingPartitioner 또는 ByteOrderedPartitioner) 를 이용하면 정렬된 방법으로 파티셔닝을 할 수 있다.



    이렇게 순서를 유지하면 키의 범위로 검색하고 데이터를 순서대로 리턴받는데에 좋은점이 있지만, 개발자와 관리자가 데이터 분배를 추적하고 계획해야한다는 단점이 있다고 한다.



    대화의 장 💬