일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- ddd
- 성능
- kafka
- 카프카 트랜잭션
- graphql
- JPA
- APNS
- nginx설정
- gcm 푸시 번역
- nginx
- 페이스북 번역
- 푸시
- 웹사이트최적화기법
- nginx설치
- 푸시 번역
- 웹사이트 성능
- 도메인 주도 개발
- notification
- 웹사이트성능
- 자바스크립트
- Java
- Design Pattern
- 디자인패턴
- 카프카
- php
- GCM
- Push
- GCM 번역
- git
Archives
- Today
- Total
간단한 개발관련 내용
카산드라(Apache Cassandra)의 파티션키와 토큰생성 본문
반응형
파티션 키(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
- 노드 A: 토큰 범위
2.2. 데이터 삽입 과정
- 데이터 삽입 요청:
- 예:
user_id = 'user123'
,name = 'John Doe'
,email = 'john@example.com'
- 예:
- 파티션 키 추출:
- 파티션 키가
user_id
인 경우,user_id = 'user123'
이 파티션 키로 사용됩니다.
- 파티션 키가
- 파티셔너에 의한 해싱:
user_id = 'user123'
이 Murmur3Partitioner에 의해 해싱되어 토큰 값1500
이 생성됩니다.
- 토큰 매핑:
- 생성된 토큰
1500
은 노드 B의 토큰 범위(1001
~2000
)에 속하므로, 데이터는 노드 B에 저장됩니다.
- 생성된 토큰
- 데이터 복제(Replication):
- 복제 인자(Replication Factor)가 2인 경우, 데이터는 노드 B와 다음 노드인 노드 C에 복제됩니다.
- 따라서,
user123
의 데이터는 노드 B와 노드 C에 저장됩니다.
2.3. 데이터 조회 과정
- 쿼리 요청:
- 예:
SELECT * FROM users WHERE user_id = 'user123';
- 예:
- 파티션 키 추출 및 해싱:
user_id = 'user123'
이 해싱되어 토큰1500
이 생성됩니다.
- 토큰 매핑:
- 토큰
1500
이 노드 B에 매핑되므로, 노드 B와 복제된 노드 C에서 데이터를 조회합니다.
- 토큰
- 데이터 반환:
- 클라이언트는 노드 B 또는 노드 C 중 하나에서 데이터를 받아옵니다.
3. 토큰 생성과 노드에의 할당 상세 설명
3.1. 토큰 생성 과정
- 파티션 키 선택:
- 테이블 생성 시 지정한 파티션 키를 사용합니다. 예를 들어,
user_id
.
- 테이블 생성 시 지정한 파티션 키를 사용합니다. 예를 들어,
- 파티셔너에 의한 해싱:
- 파티셔너는 파티션 키를 해싱하여 고유한 토큰을 생성합니다.
- Murmur3Partitioner는 64비트 해시 값을 생성하며, 이 값을 토큰으로 사용합니다.
CREATE TABLE users ( user_id UUID PRIMARY KEY, name TEXT, email TEXT, age INT );
- 토큰 값:
- 파티션 키가 해싱되어 생성된 토큰은 정수 범위 내의 값입니다. 예:
0
~2^64-1
- 파티션 키가 해싱되어 생성된 토큰은 정수 범위 내의 값입니다. 예:
3.2. 노드의 토큰 범위 할당
- 클러스터 초기화:
- 클러스터가 처음 설정될 때, 각 노드는 자신에게 할당된 토큰 범위를 가집니다.
- 자동 토큰 할당: 새로운 노드가 클러스터에 추가되면, 기존 노드의 토큰 범위를 분할하여 새로운 노드에 할당합니다.
- 수동 토큰 할당:
- 고급 설정에서 각 노드에 특정 토큰 범위를 수동으로 할당할 수 있습니다.
- 반복적 과정:
- 클러스터 확장 시, 새로운 노드가 추가되고 기존 토큰 범위가 조정되어 데이터가 재분배됩니다.
3.3. 데이터 저장과 복제
- 토큰 범위에 따른 데이터 저장:
- 생성된 토큰을 기준으로 데이터를 특정 노드에 저장합니다.
- Primary Replica: 토큰 범위를 담당하는 첫 번째 노드가 데이터의 기본 복제본을 저장합니다.
- 복제 인자(Replication Factor):
- 클러스터 내의 다른 노드에 데이터를 복제합니다.
- 예: 복제 인자가 3인 경우, Primary Replica 외에 두 개의 추가 노드에 복제됩니다.
- 복제 전략(Replication Strategy):
- SimpleStrategy: 단일 데이터 센터 환경에서 사용되며, Primary Replica 다음으로 나오는 노드에 데이터를 복제합니다.
- NetworkTopologyStrategy: 다중 데이터 센터 환경에서 사용되며, 각 데이터 센터마다 복제 인자를 설정할 수 있습니다.
CREATE KEYSPACE my_keyspace WITH replication = { 'class': 'SimpleStrategy', 'replication_factor': 3 };
- 데이터 저장 예시:
user_id = 'user123'
의 데이터는 Primary Replica인 노드 B에 저장되고, 추가로 노드 C와 노드 A에 복제됩니다.
4. 토큰과 노드 할당의 실제 예시
4.1. 가상 클러스터 예시
- 클러스터 노드 및 토큰 범위:
- 노드 A: 토큰 범위
0
~1000
- 노드 B: 토큰 범위
1001
~2000
- 노드 C: 토큰 범위
2001
~3000
- 노드 A: 토큰 범위
4.2. 데이터 삽입 예시
- 데이터:
user_id = 'user123'
- 해싱:
user123
을 해싱하여 토큰1500
생성.
- 토큰 매핑:
- 토큰
1500
은 노드 B의 범위1001
~2000
에 속하므로, 노드 B에 저장.
- 토큰
- 복제:
- 복제 인자 2인 경우, 노드 B와 노드 C에 복제.
4.3. 데이터 조회 예시
- 쿼리:
SELECT * FROM users WHERE user_id = 'user123';
- 파티션 키 해싱 및 토큰 매핑:
user123
해싱 → 토큰1500
→ 노드 B
- 데이터 반환:
- 노드 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. 요약
- 파티션 키는 데이터 분산의 기준: 파티션 키는 데이터를 클러스터 내의 특정 노드에 분산시키기 위한 기준점으로 사용됩니다. 이는 데이터를 균등하게 분산하고, 조회 성능을 최적화하는 데 중요한 역할을 합니다.
- 토큰 생성과 할당 과정:
- 파티션 키 해싱: 파티션 키를 파티셔너가 해싱하여 토큰을 생성합니다.
- 토큰 매핑: 생성된 토큰은 클러스터 내의 노드 토큰 범위에 매핑됩니다.
- 데이터 저장 및 복제: 해당 노드에 데이터가 저장되고, 복제 인자에 따라 다른 노드에도 복제됩니다.
- 효과적인 설계:
- 균등한 데이터 분포: 파티션 키가 고유하고 균등하게 분포되도록 설계합니다.
- 파티션 크기 관리: 파티션 크기가 너무 크거나 작지 않도록 파티션 키를 적절히 조정합니다.
- 쿼리 패턴 반영: 주로 사용하는 쿼리에 맞춰 파티션 키와 클러스터링 키를 설계합니다.
- 복제와 일관성: 복제 전략과 일관성 수준을 적절히 설정하여 데이터의 가용성과 일관성을 보장합니다.
파티션 키와 토큰의 개념을 정확히 이해하고, 이를 기반으로 데이터 모델링을 설계하면 Cassandra의 뛰어난 확장성과 성능을 최대한 활용할 수 있습니다. 추가적인 질문이나 더 깊은 설명이 필요하시면 언제든지 말씀해 주세요!
반응형