• 카산드라 -1부 : 설치와 인스턴스 실행해보기

    2018. 9. 13. 11:48

    by. 위지원

    오늘 할 건 아파치 카산드라이다.카산드라 따라잡기를 보고 따라 해보았다. 책에선 버전이 0.7.2지만 나는 3.11.3을 사용했다.




    여담이지만 왜 카산드라라는 이름을 썼는지 궁금해하는 사람이 있다. https://www.quora.com/Where-does-Apache-Cassandras-name-come-from

    관련 이미지


    카산드라프리아모스 왕과 헤카베의 딸을 말한다. - 위키



    저 링크에 따르면, 카산드라는 너무나 아름다운 여자라 아폴로 신이 그 미모에 반해서 미래를 볼 수 있는 능력을 주었다고 한다. 단 이 능력을 주면 나의 사랑을 받아주어라..라고 조건을 걸고 말이다. 그러나 그녀는 능력만 받고 사랑은 받아주지 않았다. 그래서 아폴로는 그녀의 말을 아무도 믿지 않도록 저주를 내렸다고 한다. 좀 재밌어서 더 이야기 하자면 아폴로가 " 내사랑을 받지 않을거면 작별 키스라도.. " 라고 하고 작별키스를 하는 사이 혀에 담긴 설득력을 빼갔다고 하는 썰도 있다.


    링크에서는 이 여인의 신뢰감이 없는 부분을 착안하여 이름을 지었다고는 하는 것 같다. 확장성이나 가용성이 좋은 대신 RDBMS에 비해 신뢰도가 좀 떨어진다고는 하는데....(데이터에 대한 입력/변경이 비동기식이고 또 중앙관리 서버가 없어서 분산 된 데이터 사이의 정합성이 맞지 않는 경우가 발생한다고 한다.*) 그래서 카산드라의 마크도 눈인 것인가? 아무튼 그것은 중요치 않고, 오늘은 간단히 살펴보고 설치하는 것 까지만 해볼 것이다.


    *이를 보안하기 위해 복제 된 여러 데이터들중 timestamp가 가장 최신인 데이터를 반환하는 로직을 제공하기도 한다고... 오래된 timestamp면 데이터 갱신을 최신으로 한다. 근데 생각해보면 이렇게 일일히 다 비교하면 성능적으로 문제가 생기기때문에 성능과 신뢰도 수준을 조절하여 모든 데이터를 스캔 비교할지 하나의 서버에 있는 데이터만 읽어서 return할지를 정할 수 있다.


    책에서는 바로 설치로 들어가기때문에 이론을 아주 간단히 알아보자.

    아파치 카산드라는 facebook에서 개발하였으며 현재는 아파치 프로젝트로 진행 되는 오픈 소스이며 key-value 형태의 NoSQL 데이터 베이스 관리 시스템의 하나이다.  JAVA기반이며 Google BigTable을 바탕으로 개발되었다. 컬럼 중심 데이터 모델의 특성을 지니고 있다.

    현재 3.11 버전까지 나와있으며 2011년 4월 18일에 0.6버전이 처음 출시되었다. 데이터를 여러 노드에 분산하고 또 복제하는 방식으로 r/w 모두 훌륭하다.

    https://docs.datastax.com/en/cassandra/3.0/cassandra/architecture/archIntro.html 를 참고하면 아키텍쳐 요약본에 대해 알 수 있다.

    카산드라는  클러스터의 모든 노드에 분산되어 있는 노드의 피어 투 피어 분산 시스템을 사용하여 장애 문제를 해결한다. 그리고 이 방식으로 상태 정보를 자주 교환한다. (이때 Gossip 프로토콜이라는 클러스터 내의 노드간 정보 공유용 프로토콜을 사용한다.)

    • RowKey가 index로 RowKey는 여러개의 column(value,timestamp)들을 가지고 있다. 
    • 각 컬럼은 컬럼 패밀리에 속한다.(super 컬럼패밀리는 다른 컬럼패밀리와 부모/자식 관계도 가능하다. 검색의 효율성을 높이기 위해 super column을 사용한다고 한다.) 
    • 컬럼 패밀리는 keyspace에 포함된다. 
    • keyspace는 RDBMS의 스키마같은 것으로 keyspace 단위로 복제 및 관련 정책을 관리하기때문에 application당 한개의 keyspace를 가지고 있게 된다.
    • 저장될때는 Map<RowKey,SortedMap<ColumnKey,ColmnValue>> 형태로 저장된다.
    • SQL과 비슷한 CQL을 제공한다(Cassandra Query Language)
    • 컬럼이나 슈퍼컬럼은 이름순으로 정렬되어 저장된다.

    위에 그림에서 볼 수 있듯이 각 row key마다 스키마가 다르다.이를 schemeless라고 한다.

    장점
    - 데이터는 먼저 메모리에 쓰여진 후 일정크기가 되면 디스크로 옮겨진다.
    - Consistent Hashing 기법을 사용하기때문에 서버가 추가적으로 생기거나 삭제가 되도 용이하다. 여기에 추가로 로드 밸런싱을 위한 알고리즘까- 지 추가해서 한 서버에 요청이 과해지지 않도록 한다.

    단점
    - Row key랑 Column으로만 index가 가능하기때문에 검색조건이 단순해서 복잡한 조건의 검색은 불가능 하다.
    - join이나 트랜잭션을 지원하지 않는다.
    - 자식 컬럼 패밀리의 인덱싱은 불가능하다.
    - 데이터에 대한 Lock을 걸려면 zookeeper를 추가해서 설정해야한다.    

    우리가 흔히 아는 RDBMS와의 차이점은 다음과 같다.

    '





    노드가 하나인 카산드라를 설치해보기



    *시작 전에 java 8이상이 설치되어있어야 한다.(cassandra 3.11.3기준)


    시간이 없으니 이론은 이쯤만 보고 설치를 해보자.


    http://cassandra.apache.org/  에 접속하면 카산드라를 다운로드 할 수 있다.


    [weejw@com ~]$ curl -O http://apache.mirror.cdnetworks.com/cassandra/3.11.3/apache-cassandra-3.11.3-bin.tar.gz
      % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                     Dload  Upload   Total   Spent    Left  Speed
    100 35.5M  100 35.5M    0     0  3957k      0  0:00:09  0:00:09 --:--:-- 5625k


    그다음에 압축을 풀어준다.  그러면 노란색과 같이 폴더가 생긴다.


    [weejw@com ~]$ tar -zxvf apache-cassandra-3.11.3-bin.tar.gz

    ....

    apache-cassandra-3.11.3  apache-cassandra-3.11.3-bin.tar.gz


    그리고 나서 압축 해제가 된 폴더 내의 conf폴더로 이동하면 cassandra.yaml 파일이 있다.  해당 파일을 편집한다.

    *YAML은 XML, C, 파이썬, 펄, RFC2822에서 정의된 e-mail 양식에서 개념을 얻어 만들어진 '사람이 쉽게 읽을 수 있는' 데이터 직렬화 양식 -위키

    *YAML은 예멀이라고 읽으며 친인간적이고 여러 언어에서 쓰일 수 있으며 유니코드 기반인 언어이다. -책


    [weejw@com ~]$ cd apache-cassandra-3.11.3/conf/
    [weejw@com conf]$ ls
    README.txt                      cqlshrc.sample
    cassandra-env.ps1               hotspot_compiler
    cassandra-env.sh                jvm.options
    cassandra-jaas.config           logback-tools.xml
    cassandra-rackdc.properties     logback.xml
    cassandra-topology.properties   metrics-reporter-config-sample.yaml
    cassandra.yaml                  triggers
    commitlog_archiving.properties


    *혹여나 앞에 띄어쓰기하면 에러뜹니다..~(너무 당연한가..핳)


    # data_file_directories:
    #     - /var/lib/cassandra/data

    를 아래와 같이 수정


    data_file_directories:

    - /home/weejw/apache-cassandra-3.11.3/data


    # commitlog_directory: /var/lib/cassandra/commitlog

    를 아래와 같이 수정


    commitlog_directory: /home/weejw/apache-cassandra-3.11.3/commit


    # saved_caches_directory: /var/lib/cassandra/saved_caches

    를 아래와 같이 수정


    saved_caches_directory: /home/weejw/apache-cassandra-3.11.3/saved_caches



    그리고나서 해당 경로에 실제로 파일을 생성해줘야합니다!


    [weejw@com apache-cassandra-3.11.3]$ mkdir data
    [weejw@com apache-cassandra-3.11.3]$ mkdir commit
    [weejw@com apache-cassandra-3.11.3]$ mkdir saved_caches


    bin 폴더에 가면 다음과 같은 파일들이 있습니다.이중에서 cassandra를 입력하여 실행시킨 뒤 실행중인지 확인해봅니다.


    [weejw@com bin]$ ls
    cassandra         debug-cql.bat      sstableupgrade.bat
    cassandra.bat     nodetool           sstableutil
    cassandra.in.bat  nodetool.bat       sstableutil.bat
    cassandra.in.sh   source-conf.ps1    sstableverify
    cassandra.ps1     sstableloader      sstableverify.bat
    cqlsh             sstableloader.bat  stop-server
    cqlsh.bat         sstablescrub       stop-server.bat
    cqlsh.py          sstablescrub.bat   stop-server.ps1
    debug-cql         sstableupgrade


    그러면 아래와 같이 로그가 화면에 출력됩니다.

    *원래 카산드라는 콘솔과 분리되어 시스템 데몬처럼 동작하게 되지만 -f 옵션을 같이 전달해 실행하면 포어그라운드로 실행이 가능해진다.


    <...생략..>

    INFO  [MigrationStage:1] 2018-09-12 21:54:04,699 ViewManager.java:137 - Not submitting build tasks for views in keyspace system_auth as storage service is not initialized
    INFO  [MigrationStage:1] 2018-09-12 21:54:04,702 ColumnFamilyStore.java:411 - Initializing system_auth.resource_role_permissons_index
    INFO  [MigrationStage:1] 2018-09-12 21:54:04,739 ColumnFamilyStore.java:411 - Initializing system_auth.role_members
    INFO  [MigrationStage:1] 2018-09-12 21:54:04,768 ColumnFamilyStore.java:411 - Initializing system_auth.role_permissions
    INFO  [MigrationStage:1] 2018-09-12 21:54:04,796 ColumnFamilyStore.java:411 - Initializing system_auth.roles


    그다음에 다음과 같은 명령어를 입력하면 노드툴과 연결하여 상태를 확인할 수 있습니다.

    *노드 툴은 JMX포트를 이용해 서버가 살아있는지를 확인한다.


    [weejw@com bin]$ ./nodetool --host 127.0.0.1 ring

    Datacenter: datacenter1
    ==========
    Address    Rack        Status State   Load            Owns                Token                                      
                                                                              9190797917222882005                        
    127.0.0.1  rack1       Up     Normal  103.65 KiB      100.00%             -9189612010720093071                       
    127.0.0.1  rack1       Up     Normal  103.65 KiB      100.00%             -9179985222429901813                       
    127.0.0.1  rack1       Up     Normal  103.65 KiB      100.00%             -9102634396224859180

    <...생략...>


    이렇게 보는게 더 낫다.(위에 명령어를 실행하면 이렇게 하라고 나온다.)


     [weejw@com bin]$ ./nodetool status
    Datacenter: datacenter1
    =======================
    Status=Up/Down
    |/ State=Normal/Leaving/Joining/Moving
    --  Address    Load       Tokens       Owns (effective)  Host ID                               Rack
    UN  127.0.0.1  257.12 KiB  256          100.0%            85d707a5-7034-4211-8a77-5d988c5a32c2  rack1


    하나의 머신에서 여러 개의 인스턴스 실행하기

    카산드라를 여러 노드에서 동작 시키고 싶을 때는 카산드라 인스턴스를 여러 개 띄워서 시뮬레이션 해보자.
    앞의 하나의 노드에서 실행하는 것과의 차이점은 인스턴스마다 다른 디렉토리를 생성하고 각 노드의 설정파일을 만들어줘야한다.

    아래 명령어는 현재 시스템에서 적절한 loopback address가 지원되는지를 확인한다.
    * 루프백 주소란? http://codedragon.tistory.com/3937

    127.0.0.1~127.255.255.255의 범위 전체가 루프백을 위해 localhost로 설정되어있어야한다. 아래의 명령어로 ping을 날려서 확인해보자. * -c는 count

    [weejw@com bin]$ ping -c 1 127.0.0.1
    PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
    64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.247 ms

    --- 127.0.0.1 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.247/0.247/0.247/0.000 ms
    [weejw@com bin]$ ping -c 1 127.0.0.2
    PING 127.0.0.2 (127.0.0.2) 56(84) bytes of data.
    64 bytes from 127.0.0.2: icmp_seq=1 ttl=64 time=0.045 ms

    --- 127.0.0.2 ping statistics ---
    1 packets transmitted, 1 received, 0% packet loss, time 0ms
    rtt min/avg/max/mdev = 0.045/0.045/0.045/0.000 ms


    홈 디렉토리에 새로운 폴더를 만들고 commitlog,data,saved_caches라는 폴더를 만든다(*위와 같은 과정)

    그 다음에 카산드라 폴더를 새로 만들 폴더로 복사한다.


    [weejw@com ~]$ mkdir hpcas
    [weejw@com ~]$ mkdir hpcas/{commitlog,data,saved_caches}
    [weejw@com ~]$ cp -r apache-cassandra-3.11.3 hpcas/ apache-cassandra-3.11.3-1
    [weejw@com ~]$ cd hpcas/
    [weejw@com hpcas]$ ls
    apache-cassandra-3.11.3  commitlog  data  saved_caches


    각각의 인스턴스를 위한 폴더를 만들어주고 (1,2,3,4) cassandra 폴더도 복사해준다.


    [weejw@com ~]$ mkdir commitlog/{1,2,3,4}

    [weejw@com ~]$ mkdir data/{1,2,3,4}

    [weejw@com ~]$ mkdir saved_caches/{1,2,3,4}

    [weejw@com ~]$ cp -r apache-cassandra-3.11.3-1/ apache-cassandra-3.11.3-2

    [weejw@com ~]$ cp -r apache-cassandra-3.11.3-1/ apache-cassandra-3.11.3-3
    [weejw@com ~]$ cp -r apache-cassandra-3.11.3-1/ apache-cassandra-3.11.3-4


    새로 복사한곳의 conf/casandra.yaml파일을 인스턴스가 서로 충돌하지 않도록 기본 경로와 IP주소를 수정한다. 이런 과정을 4번 반복한다.

    ex. 127.0.0.1 127.0.0.2 127.0.0.3 127.0.0.4


    data_file_directories:

    - /home/weejw/hpcas/apache-cassandra-3.11.3/data/1

    commitlog_directory: /home/weejw/hpcas/apache-cassandra-3.11.3/commitlog/1

    saved_caches_directory: /home/weejw/hpcas/apache-cassandra-3.11.3/saved_caches/1


    listen_address: 127.0.0.1
    rpc_address: 127.0.0.1

    카산드라는 JMX(Java Management Extensios)를 이용한다. 시스템 인스턴스와 별도로 외부 포트에도 연결을 해야하기때문에 별도의 관리 포트를 부여해주어야한다. conf/cassandra-env.sh도 수정해주자. 이것또한 8002,8003,8004 이렇게 반복해서 모든 폴더의 설정파일을 수정해준다.


    JMX_PORT="8001"


    수정이 모두 완료되었으면 /bin/cassandra 를 이용해서 실행시켜준다. 난 노드 4개까지 설정했지만 총 3개만 실행시켰다.

    https://github.com/docker-library/cassandra/issues/144 를 참조하면 각 인스턴스가 가질 heap size를 수정해주면 원하는 인스턴스 개수만큼 실행이 가능해질 것 같다.(귀찮아서 안...)


    Datacenter: datacenter1
    =======================
    Status=Up/Down
    |/ State=Normal/Leaving/Joining/Moving
    --  Address    Load       Tokens       Owns (effective)  Host ID                               Rack
    DN  127.0.0.1  119.47 KiB  256          65.1%             d24771d4-0472-4a20-9f59-d74f54f3effa  rack1
    UN  127.0.0.2  75 KiB     256          65.5%             6979e4a9-ff14-46ca-9ebd-f9229848adba  rack1
    UN  127.0.0.3  112.95 KiB  256          69.4%             c1232d20-2fdd-4314-98cc-9767c018cf50  rack1


    이렇게 일일히 귀찮게 설정하는 부분을 셸 스크립트를 이용해서 하면 좀 더 간편하고 쉽고 빠르게 할 수 있겠습니다..


    대화의 장 💬