Tag Archives: 클러스터

[NoSQL] Cassandra 스키마 불일치 문제 해결 하기

사용자 삽입 이미지
간혹 시스템을 운영하다 보면 클러스터의 특정 노드가 폭주한다거나 문제가 발생하는 경우가 자주 있습니다. 이때에 스키마를 변경하는 명령을 수행하게 되면 문제 있는 노드들이 스키마를 변경하지 못하고 다음과 같은 장애를 내뱉는 경우가 있습니다.
[code]SchemaDisagreementException()
java.lang.RuntimeException: SchemaDisagreementException()
        at org.apache.cassandra.cli.CliClient.executeCLIStatement(CliClient.java:308)
        at org.apache.cassandra.cli.CliMain.processStatement(CliMain.java:217)
        at org.apache.cassandra.cli.CliMain.main(CliMain.java:345)
Caused by: java.lang.RuntimeException: SchemaDisagreementException()
        at org.apache.cassandra.cli.CliClient.executeAddColumnFamily(CliClient.java:1039)
        at org.apache.cassandra.cli.CliClient.executeCLIStatement(CliClient.java:226)
        … 2 more
Caused by: SchemaDisagreementException()
        at org.apache.cassandra.thrift.Cassandra$system_add_column_family_result.read(Cassandra.java:26905)
        at org.apache.cassandra.thrift.Cassandra$Client.recv_system_add_column_family(Cassandra.java:1455)
        at org.apache.cassandra.thrift.Cassandra$Client.system_add_column_family(Cassandra.java:1430)
        at org.apache.cassandra.cli.CliClient.executeAddColumnFamily(CliClient.java:1028)
        … 3 more[/code]
Cassandra라는 기본적으로 스키마 설정에 대하여 임의의 버전값을 부여하여 노드들간에 통일성을 유지하도록 동작하고 있습니다. 하지만 저런 에러를 한번만 만나게 되면 클러스터간의 스키마 통일성이 깨지게 됩니다.

cassandra-cli를 실행한 후 다음과 같은 방법으로 스키마의 동기화 상태를 확인할 수 있습니다.
[code][default@unknown] describe cluster;
Cluster Information:
   Snitch: org.apache.cassandra.locator.SimpleSnitch
   Partitioner: org.apache.cassandra.dht.RandomPartitioner
   Schema versions:
75eece10-bf48-11e0-0000-4d205df954a7: [192.168.1.9, 192.168.1.25]
5a54ebd0-bd90-11e0-0000-9510c23fceff: [192.168.1.27][/code]
위와 같이 describe cluster명령을 치게 되면 Schema versions가 나오게 되는데 여기서 192.168.1.27 노드가 어긋나 버린것을 확인할 수 있습니다. 이것을 복구하여 스키마를 일치시켜주기 위해서는 다음과 같은 방법을 사용합니다.

1. 192.168.1.27 서버에 접속
2. cassandra 데몬을 죽임(sudo service cassandra stop / kill <pid>)
3. 카산드라 데이터 디렉토리 안의 system 디렉토리안에 있는 schema*, migration*을 모두 삭제
   (기본 설정일 경우 /var/lib/cassandra/data/system 에 위치)
4. 카산드라 재시작, 필요한 정보들이 없다며 에러들이 주르륵 뜬 후에 스키마 정보를 다른 클러스터들로부터 다시 가져와 동기화를 합니다.
[code][default@unknown] describe cluster;
Cluster Information:
   Snitch: org.apache.cassandra.locator.SimpleSnitch
   Partitioner: org.apache.cassandra.dht.RandomPartitioner
   Schema versions:
75eece10-bf48-11e0-0000-4d205df954a7: [192.168.1.9, 192.168.1.25, 192.168.1.27][/code]
이제 위와 같이 하나의 스키마로 통일이 되었습니다.

참고 : http://wiki.apache.org/cassandra/FAQ#schema_disagreement

[NoSQL] Cassandra에서 데이터가 노드에 저장되는 방식에 대해 (Consistent Hashing)

사용자 삽입 이미지

Consistent Hashing이란 다수의 노드로 이루어진 클러스터안에 데이터를 저장할때 데이터의 키를 기반으로 하여 어떤 노드에 저장할 것인가 계산하는 로직을 말합니다. Gossip Protocol과 더블어 아마존의 Dynamo의 영향을 받은 부분입니다.

사용자 삽입 이미지
간단하게 표현하여 보자면 위와 같습니다. alice라는 키에 값을 넣을때에는 3대의 노드가 있다면 단순히 이름을 해싱하여 3으로 나누면 됩니다. 위의 그림에서는 두번째 노드에 저장하는것으로 결정 되었네요.

사용자 삽입 이미지
시스템이 확장됨에 따라 노드가 하나 더 추가되었습니다. 단순하게 위의 그림만을 놓고 보자면 alice는 더이상 2에 저장되지 않습니다. 3에 저장되는 군요. 반대로 이미 2에 저장된 데이터는 3으로 옮겨와야 합니다. 데이터의 개편이 필요합니다.

사용자 삽입 이미지
실제로 데이터는 단순하게 나머지연산(%)을 하지는 않습니다. 각각의 노드가  응답가능한 데이터의 범위를 가지고 있고 거기에 맞는 범위안에 데이터가 저장됩니다. 위의 경우에는 키 alice를 해싱한 결과가 23이라면 0과 42사이에 저장하면 되는것이겠죠.

사용자 삽입 이미지
새로운 노드가 추가(또는 삭제)되었습니다. 대부분의 데이터는 여전히 그 자리에 있습니다.

사용자 삽입 이미지
4대의 노드간의 밸런스를 조정한 상태(rebalanced)입니다. 이경우 약간의 데이터가 자기 자리를 찾기위해 옮겨다녀야 합니다. 위의 alice는 23으로 변화가 없지만 35인 데이터가 있다면 노드 위치를 옮겨야 합니다.