간단한 개발관련 내용

카산드라(Apache Cassandra)의 파티션키와 토큰생성 본문

NoSql/Casandra

카산드라(Apache Cassandra)의 파티션키와 토큰생성

vincenzo.dev.82 2024. 10. 3. 00:27
반응형

파티션 키(Partition Key)는 Cassandra에서 데이터를 어떤 노드에 저장할지를 결정하는 토큰(Token)을 생성하는 데 사용됩니다. 이 과정은 Cassandra의 분산 아키텍처에서 데이터의 균등한 분산과 높은 가용성을 보장하는 핵심 메커니즘입니다. 아래에서는 파티션 키가 토큰을 생성하고, 이 토큰이 노드에 할당되며 데이터를 저장하는 과정을 단계별로 자세히 설명하겠습니다.


1. 파티션 키와 토큰의 관계 이해하기

1.1. 파티션 키(Partition Key)란?

  • 정의: 파티션 키는 테이블 내의 각 행(row)을 고유하게 식별하며, 데이터를 클러스터 내의 특정 노드에 분산시키는 기준이 되는 키입니다.
  • 역할:
    • 데이터 분산: 파티션 키를 기반으로 데이터가 클러스터 내의 다양한 노드에 고르게 분산됩니다.
    • 데이터 조회 효율성: 특정 파티션 키를 사용한 쿼리는 해당 파티션이 저장된 노드에서만 데이터를 조회하므로 조회 속도가 향상됩니다.

1.2. 토큰(Token)이란?

  • 정의: 토큰은 파티션 키가 파티셔너(Partitioner)에 의해 해싱된 값으로, 클러스터 내의 데이터 분포를 결정하는 데 사용됩니다.
  • 역할:
    • 데이터 분배: 토큰을 기반으로 데이터가 클러스터의 특정 노드에 저장됩니다.
    • 토큰 범위: 각 노드는 특정 토큰 범위를 담당하며, 이 범위 내의 데이터를 저장합니다.

1.3. 파티셔너(Partitioner)란?

  • 정의: 파티셔너는 파티션 키를 해싱하여 토큰을 생성하는 알고리즘입니다. 기본적으로 Cassandra는 Murmur3Partitioner를 사용합니다.
  • 역할:
    • 해싱: 파티션 키를 해싱하여 고정 길이의 토큰을 생성합니다.
    • 토큰 분배: 생성된 토큰을 클러스터 내의 노드에 균등하게 분배합니다.

2. 파티션 키를 사용한 데이터 분산 과정

데이터가 Cassandra 클러스터에 저장되는 과정을 단계별로 살펴보겠습니다.

2.1. 클러스터 구성

가상의 Cassandra 클러스터를 예로 들어 설명하겠습니다.

  • 노드(Node): 클러스터를 구성하는 각 서버입니다.
  • 토큰 범위(Token Range): 각 노드는 특정 토큰 범위를 담당합니다. 예를 들어:
    • 노드 A: 토큰 범위 0 ~ 1000
    • 노드 B: 토큰 범위 1001 ~ 2000
    • 노드 C: 토큰 범위 2001 ~ 3000

2.2. 데이터 삽입 과정

  1. 데이터 삽입 요청:
    • 예: user_id = 'user123', name = 'John Doe', email = 'john@example.com'
  2. 파티션 키 추출:
    • 파티션 키가 user_id인 경우, user_id = 'user123'이 파티션 키로 사용됩니다.
  3. 파티셔너에 의한 해싱:
    • user_id = 'user123'Murmur3Partitioner에 의해 해싱되어 토큰 값 1500이 생성됩니다.
  4. 토큰 매핑:
    • 생성된 토큰 1500은 노드 B의 토큰 범위(1001 ~ 2000)에 속하므로, 데이터는 노드 B에 저장됩니다.
  5. 데이터 복제(Replication):
    • 복제 인자(Replication Factor)가 2인 경우, 데이터는 노드 B와 다음 노드인 노드 C에 복제됩니다.
    • 따라서, user123의 데이터는 노드 B와 노드 C에 저장됩니다.

2.3. 데이터 조회 과정

  1. 쿼리 요청:
    • 예: SELECT * FROM users WHERE user_id = 'user123';
  2. 파티션 키 추출 및 해싱:
    • user_id = 'user123'이 해싱되어 토큰 1500이 생성됩니다.
  3. 토큰 매핑:
    • 토큰 1500이 노드 B에 매핑되므로, 노드 B와 복제된 노드 C에서 데이터를 조회합니다.
  4. 데이터 반환:
    • 클라이언트는 노드 B 또는 노드 C 중 하나에서 데이터를 받아옵니다.

3. 토큰 생성과 노드에의 할당 상세 설명

3.1. 토큰 생성 과정

  1. 파티션 키 선택:
    • 테이블 생성 시 지정한 파티션 키를 사용합니다. 예를 들어, user_id.
  2. 파티셔너에 의한 해싱:
    • 파티셔너는 파티션 키를 해싱하여 고유한 토큰을 생성합니다.
    • Murmur3Partitioner는 64비트 해시 값을 생성하며, 이 값을 토큰으로 사용합니다.
    CREATE TABLE users (
      user_id UUID PRIMARY KEY,
      name TEXT,
      email TEXT,
      age INT
    );
  3. 토큰 값:
    • 파티션 키가 해싱되어 생성된 토큰은 정수 범위 내의 값입니다. 예: 0 ~ 2^64-1

3.2. 노드의 토큰 범위 할당

  1. 클러스터 초기화:
    • 클러스터가 처음 설정될 때, 각 노드는 자신에게 할당된 토큰 범위를 가집니다.
    • 자동 토큰 할당: 새로운 노드가 클러스터에 추가되면, 기존 노드의 토큰 범위를 분할하여 새로운 노드에 할당합니다.
  2. 수동 토큰 할당:
    • 고급 설정에서 각 노드에 특정 토큰 범위를 수동으로 할당할 수 있습니다.
  3. 반복적 과정:
    • 클러스터 확장 시, 새로운 노드가 추가되고 기존 토큰 범위가 조정되어 데이터가 재분배됩니다.

3.3. 데이터 저장과 복제

  1. 토큰 범위에 따른 데이터 저장:
    • 생성된 토큰을 기준으로 데이터를 특정 노드에 저장합니다.
    • Primary Replica: 토큰 범위를 담당하는 첫 번째 노드가 데이터의 기본 복제본을 저장합니다.
  2. 복제 인자(Replication Factor):
    • 클러스터 내의 다른 노드에 데이터를 복제합니다.
    • 예: 복제 인자가 3인 경우, Primary Replica 외에 두 개의 추가 노드에 복제됩니다.
  3. 복제 전략(Replication Strategy):
    • SimpleStrategy: 단일 데이터 센터 환경에서 사용되며, Primary Replica 다음으로 나오는 노드에 데이터를 복제합니다.
    • NetworkTopologyStrategy: 다중 데이터 센터 환경에서 사용되며, 각 데이터 센터마다 복제 인자를 설정할 수 있습니다.
    CREATE KEYSPACE my_keyspace WITH replication = {
      'class': 'SimpleStrategy',
      'replication_factor': 3
    };
  4. 데이터 저장 예시:
    • user_id = 'user123'의 데이터는 Primary Replica인 노드 B에 저장되고, 추가로 노드 C와 노드 A에 복제됩니다.

4. 토큰과 노드 할당의 실제 예시

4.1. 가상 클러스터 예시

  • 클러스터 노드 및 토큰 범위:
    • 노드 A: 토큰 범위 0 ~ 1000
    • 노드 B: 토큰 범위 1001 ~ 2000
    • 노드 C: 토큰 범위 2001 ~ 3000

4.2. 데이터 삽입 예시

  1. 데이터:
    • user_id = 'user123'
  2. 해싱:
    • user123을 해싱하여 토큰 1500 생성.
  3. 토큰 매핑:
    • 토큰 1500은 노드 B의 범위 1001 ~ 2000에 속하므로, 노드 B에 저장.
  4. 복제:
    • 복제 인자 2인 경우, 노드 B와 노드 C에 복제.

4.3. 데이터 조회 예시

  1. 쿼리:
    • SELECT * FROM users WHERE user_id = 'user123';
  2. 파티션 키 해싱 및 토큰 매핑:
    • user123 해싱 → 토큰 1500 → 노드 B
  3. 데이터 반환:
    • 노드 B 또는 복제된 노드 C에서 데이터 반환.

5. 파티션 키와 토큰 할당 설계 시 고려 사항

5.1. 균등한 데이터 분포

  • 목표: 데이터가 클러스터 전체에 고르게 분포되도록 파티션 키를 선택합니다.
  • 방법:
    • 고유성: 파티션 키는 고유하거나 고르게 분포된 값을 가져야 합니다. 예: UUID, 해시된 값 등.
    • 균등한 해싱: 파티션 키가 파티셔너에 의해 균등하게 해싱되도록 설계합니다.

5.2. 파티션 크기 관리

  • 파티션 크기: 각 파티션에 저장되는 데이터 양을 적절히 유지합니다.
  • 과도한 데이터 축적 방지:
    • 너무 많은 데이터를 하나의 파티션에 저장하면 성능 저하 및 "hot spot" 문제가 발생할 수 있습니다.
    • 예: 시간 기반 파티션 키를 추가하여 파티션 크기를 분산시킵니다.
    PRIMARY KEY ((user_id, year, month), timestamp)

5.3. 쿼리 패턴 최적화

  • 쿼리 우선 설계(Query-First Design): 주로 사용하는 쿼리를 먼저 정의하고, 그에 맞춰 파티션 키와 클러스터링 키를 설계합니다.
  • 효율적인 조회: 자주 조회되는 데이터에 접근할 때 필요한 노드 수를 최소화합니다.

5.4. 복제와 일관성 고려

  • 복제 인자 설정: 데이터의 가용성과 내구성을 고려하여 적절한 복제 인자를 설정합니다.
  • 일관성 수준: 클라이언트의 일관성 요구 사항에 따라 읽기 및 쓰기 일관성 수준을 설정합니다.

6. 실무 적용 예시

6.1. 사용자 활동 로그 테이블

사용자의 활동 로그를 저장하는 테이블을 설계한다고 가정해보겠습니다.

CREATE TABLE user_activity_logs (
  user_id UUID,
  log_id TIMEUUID,
  activity TEXT,
  timestamp TIMESTAMP,
  PRIMARY KEY (user_id, log_id)
) WITH CLUSTERING ORDER BY (log_id DESC);
  • 파티션 키: user_id
    • 각 사용자의 모든 로그가 동일한 파티션에 저장됩니다.
  • 클러스터링 키: log_id
    • 로그가 log_id의 내림차순으로 정렬됩니다.
  • 토큰 할당:
    • user_id가 해싱되어 생성된 토큰에 따라 데이터를 저장할 노드가 결정됩니다.
    • 복제 인자 3인 경우, Primary Replica와 두 개의 보조 노드에 데이터가 복제됩니다.

6.2. 시간 기반 파티션 키 활용

대규모 로그 데이터를 시간별로 분산 저장하여 파티션 크기를 관리합니다.

CREATE TABLE daily_user_activity_logs (
  user_id UUID,
  year INT,
  month INT,
  log_id TIMEUUID,
  activity TEXT,
  timestamp TIMESTAMP,
  PRIMARY KEY ((user_id, year, month), log_id)
) WITH CLUSTERING ORDER BY (log_id DESC);
  • 파티션 키: (user_id, year, month)
    • 특정 사용자의 특정 월별 로그가 동일한 파티션에 저장됩니다.
  • 클러스터링 키: log_id
    • 로그가 log_id의 내림차순으로 정렬됩니다.
  • 장점:
    • 파티션 크기를 시간 단위로 제한하여 관리할 수 있습니다.
    • 특정 월의 로그만 조회할 때 효율적입니다.

7. 파티션 키와 토큰 할당의 최적화 전략

7.1. 균등한 데이터 분포 유지

  • 파티션 키 선택: 고유하고 균등하게 분포된 값을 선택합니다. 예: UUID, 해시된 사용자 ID 등.
  • 해싱 알고리즘 이해: 파티셔너가 사용하는 해싱 알고리즘(Murmur3Partitioner)의 특성을 이해하고, 파티션 키가 균등하게 분포되도록 설계합니다.

7.2. 파티션 크기 관리

  • 시간 기반 파티션 키: 로그나 센서 데이터처럼 시간에 따라 축적되는 데이터를 저장할 때, 시간 기반의 파티션 키를 사용하여 파티션 크기를 관리합니다.
  • 데이터 분할: 필요에 따라 추가적인 파티션 키 컬럼을 도입하여 데이터를 더 세분화합니다.

7.3. 쿼리 패턴 최적화

  • 쿼리 분석: 애플리케이션에서 자주 사용하는 쿼리를 분석하여, 해당 쿼리에 최적화된 파티션 키와 클러스터링 키를 설계합니다.
  • 인덱스 활용: 클러스터링 키를 통해 인덱스를 활용하여 빠른 조회를 지원합니다.

7.4. 복제와 일관성 관리

  • 복제 전략 선택: 클러스터의 네트워크 토폴로지와 일관성 요구 사항에 맞는 복제 전략을 선택합니다.
    • 단일 데이터 센터: SimpleStrategy 사용.
    • 다중 데이터 센터: NetworkTopologyStrategy 사용.
  • 일관성 수준 조정: 애플리케이션의 일관성 요구 사항에 따라 적절한 읽기 및 쓰기 일관성 수준을 설정합니다.
  • SELECT * FROM users WHERE user_id = 'user123' CONSISTENCY QUORUM;

8. 요약

  • 파티션 키는 데이터 분산의 기준: 파티션 키는 데이터를 클러스터 내의 특정 노드에 분산시키기 위한 기준점으로 사용됩니다. 이는 데이터를 균등하게 분산하고, 조회 성능을 최적화하는 데 중요한 역할을 합니다.
  • 토큰 생성과 할당 과정:
    1. 파티션 키 해싱: 파티션 키를 파티셔너가 해싱하여 토큰을 생성합니다.
    2. 토큰 매핑: 생성된 토큰은 클러스터 내의 노드 토큰 범위에 매핑됩니다.
    3. 데이터 저장 및 복제: 해당 노드에 데이터가 저장되고, 복제 인자에 따라 다른 노드에도 복제됩니다.
  • 효과적인 설계:
    • 균등한 데이터 분포: 파티션 키가 고유하고 균등하게 분포되도록 설계합니다.
    • 파티션 크기 관리: 파티션 크기가 너무 크거나 작지 않도록 파티션 키를 적절히 조정합니다.
    • 쿼리 패턴 반영: 주로 사용하는 쿼리에 맞춰 파티션 키와 클러스터링 키를 설계합니다.
    • 복제와 일관성: 복제 전략과 일관성 수준을 적절히 설정하여 데이터의 가용성과 일관성을 보장합니다.

파티션 키와 토큰의 개념을 정확히 이해하고, 이를 기반으로 데이터 모델링을 설계하면 Cassandra의 뛰어난 확장성과 성능을 최대한 활용할 수 있습니다. 추가적인 질문이나 더 깊은 설명이 필요하시면 언제든지 말씀해 주세요!

반응형