용량 계획
용량 계획 (capacity-planning)
Qdrant 클러스터를 규모 조정(sizing)한다는 것은 커렉션이 필요로 하는 **저장 공간(disk)과 메모리(RAM)**를 추정하고, 그 부하를 노드들에 어떻게 분산할지 결정하는 일이에요. 어떤 구성이 좋은지는 몇 가지 요소에 달려 있어요.
- 벡터가 몇 개나 있고, 차원(dimension)이 얼마나 되는지
- 사용 중인 payload 데이터의 양과 그 인덱스
- 어떤 데이터를 메모리에 저장하고 어떤 것을 디스크에 저장할지
- 클러스터의 복제(replication) 설정
- 양자화(quantization)를 쓰는지, 쓴다면 어떻게 설정했는지
배포 규모를 인터랙티브하게 계산해 보려면 Qdrant Sizing Calculator를 사용해 보세요.
RAM과 디스크 크기 계산하기
각 컬렉션이 필요로 하는 RAM과 디스크를 추정해요. 클러스터의 모든 컬렉션에 대해 이 작업을 반복한 뒤 결과를 합산하면 클러스터 전체 용량이 나와요.
컬렉션의 용량 계획은 **기본 단위(base unit)**에서 시작해요. 기본 단위는 컬렉션의 포인트 수에 **복제 계수(replication factor)**를 곱한 값이에요. 즉 모든 레플리카에 걸쳐 저장될 총 포인트 수예요.
base = number_of_points * replication_factor
Dense 벡터
원본 벡터 (Original Vectors)
Dense 벡터는 검색 대상이 되는 임베딩의 원래 표현이에요. 이들이 소비하는 RAM과 디스크는 기본 수, 벡터 차원수, 그리고 데이터 타입(datatype)에 따라 달라져요.
dense_size = base * dimensions * bytes_per_dim
여기서 bytes_per_dim은 데이터 타입에 따라 달라져요: float32 = 4바이트(기본), float16 = 2바이트, uint8 = 1바이트, turbo4 = 0.5바이트. Dense 벡터가 기본 cached 티어에 있으면 이 크기가 RAM에 반영돼요.
포인트에 여러 이름이 붙은 벡터(multiple named vectors)가 실려 있다면, 각 이름 벡터에 이 공식을 적용한 뒤 결과를 합산하면 돼요.
양자화된 벡터 (Quantized Vectors)
양자화는 결과 검색 품질이 받아들일 만할 때만 사용해야 해요. 일부 임베딩 모델은 효율적으로 양자화되지 않기 때문에, 양자화하지 않은 결과와 비교해 recall(재현율)을 검증해 보는 게 좋아요.
HNSW 벡터 인덱스
예를 들어 100만 개 포인트, 복제 계수 2, 기본값 m = 16인 경우를 보면:
hnsw_size = 2,000,000 * 16 * 2 * 4 bytes * 1.2 ≈ 0.29 GB
Sparse 벡터
Sparse 벡터는 키워드 스타일의 전문 검색(full-text search)을 뒷받침해요. 이 벡터도 인덱스가 있는데, 역인덱스(inverted-index) 스타일 구조예요.
Payload
Payload 저장
Payload의 크기는 데이터의 구조와 내용에 전적으로 달려 있어요. 텍스트 필드는 길이와 인코딩에 따라 커지고, 숫자는 8바이트로 고정되며, 불리언(boolean)은 1바이트예요. payload 크기를 추정할 때는 JSON 크기 계산기를 쓰면 돼요.
포인트당 평균 payload 크기를 알면, 총 크기는 메모리 티어에 따라 달라져요.
disk_size = base * avg_payload_size * 1.5
ram_size = base * avg_payload_size * 1.5 * 3 # cached 인 경우
Payload 인덱스
대략적으로, 인덱싱하는 필드 크기의 약 2배를 예산으로 잡아요.
payload_index_size ≈ indexed_payload_size * 2
필터링에 쓰는 필드만 인덱싱해야 해요. 전부 인덱싱하면 RAM을 낭비하게 돼요.
ID 트래커 (ID Tracker)
포인트 ID와 내부 벡터 번호 간의 매핑을 유지하는 트래커도 작은 메모리를 차지해요. 총 포인트 수에 비례하므로 위 예시 기준으로 대략 0.10GB 수준이에요. (정확한 계산식은 확인 필요 — 원문에서 구체적인 공식은 명시되지 않았어요.)
종합해 보기 (Putting It Together)
최종 RAM·디스크 합계에 **약 20%의 여유분(headroom)**을 더해요. RAM 쪽에서는 OS 페이지 캐시, Qdrant의 런타임 오버헤드, 최적화 중 임시 작업을 커버해요. 디스크 쪽에서는 WAL, 스냅샷, 옵티마이저가 만드는 임시 세그먼트를 커버해요.
RAM = dense_size + hnsw_size + id_tracker_size
= 5.72 + 0.29 + 0.10 ≈ 6.11 GB
* 1.2 headroom ≈ 7.33 GB to plan for
Disk = dense_size + hnsw_size + disk_size (payload) + id_tracker_size
= 5.72 + 0.29 + 2.86 + 0.10 ≈ 8.97 GB
* 1.2 headroom ≈ 10.76 GB to plan for
이것들은 여전히 추정치예요. 정확한 수치가 필요하면 Qdrant Sizing Calculator를 쓰거나, 대표 샘플로 직접 테스트해 보세요. 이 계산을 모든 컬렉션에 반복한 뒤, RAM과 디스크 합계를 전체로 합산해서 클러스터를 규모 조정해요.
클러스터 토폴로지 (Cluster Topology)
샤드 수 (Shard Count)
샤드 수는 컬렉션 생성 시점에 노드 수로 기본 설정돼요. 컬렉션을 다시 만들지 않고는 나중에 바꿀 수 없어요. 다만 Qdrant Cloud에서는 resharding이 가능해요. 그래서 샤드 수는 처음부터 정하는 게 좋아요.
노드 수 (Node Count)
클러스터의 노드 수는 총 RAM/디스크 요구량과 복제 요구 사항에서 나와요. 복제 계수가 클러스터의 레플리카 수를 결정하므로, 실제 벡터 저장 밀도에 영향을 줘요. 각 노드는 base_node(노드당 포인트 수)를 담당한다고 보면 돼요.
디스크를 RAM보다 우선하는 구성 (Choosing Disk over RAM)
서브그룹 지향 구성 (Subgroup-Oriented Configuration)
base_ram = active_number_of_points * replication_factor
활성(active) 벡터의 서브셋만 메모리에 캐시되어 최근·활발한 사용자에게 빠른 검색을 제공하는 시나리오예요. Qdrant에서 데이터를 파티셔닝하는 더 자세한 내용은 multitenancy 문서를 참고하세요.
Qdrant Cloud에서 디스크 공간 확장 (Scaling Disk Space in Qdrant Cloud)
벡터 검색을 지원하는 클러스터는 다른 검색 시스템에 비해 상당한 디스크 공간이 필요해요. 디스크 공간이 부족하면, cloud.qdrant.io의 UI로 클러스터를 확장할 수 있어요.
참고: Qdrant UI로 디스크 공간을 늘리면 나중에 줄일 수 없어요.
위의 Putting It Together 안내에 따라 WAL, 스냅샷, 옵티마이저가 만드는 임시 세그먼트를 포함한 ~20% 여유분까지 포함해 전체 RAM·디스크 요구량을 추정하세요.
주의사항 (Disclaimers)
- 이 계산들은 어디까지나 근사치예요. 더 정확한 수치가 필요하면 실제 데이터의 샘플로 항상 테스트해 봐야 해요.
- 마이그레이션 시나리오는 일반 운영보다 더 많은 여유분을 요구해요.