Qdrant 저장소
Qdrant 저장소 (Storage)
Qdrant는 컬렉션 안의 모든 데이터를 세그먼트(segment)로 나눠서 저장해요. 벡터와 페이로드 저장소, 각종 인덱스가 세그먼트별로 독립적으로 존재하고, 세그먼트끼리 데이터가 겹치지 않는 게 보통이에요. 이 페이지는 벡터·페이로드 저장 방식과 버전 관리(versioning) 원리를 설명해요.
본문
한 컬렉션의 모든 데이터는 세그먼트 단위로 나뉘어요. 각 세그먼트는 벡터 저장소, 페이로드 저장소, 벡터·페이로드 인덱스, 그리고 내부 id와 외부 id의 관계를 저장하는 id mapper로 구성돼요. 같은 포인트가 다른 세그먼트에 저장돼도 검색에 중복 제거 메커니즘이 있기 때문에 문제가 되지 않아요.
세그먼트는 저장 방식과 인덱스 종류에 따라 appendable 또는 non-appendable로 나뉘어요. appendable 세그먼트는 자유롭게 추가·삭제·조회가 가능하고, non-appendable 세그먼트는 읽기와 삭제만 가능해요.
벡터 저장 방식
애플리케이션 요구사항에 따라 Qdrant는 여러 저장 옵션을 고를 수 있어요. 핵심 트레이드오프는 검색 속도와 사용하는 RAM 크기 사이예요.
- In-memory 저장: 모든 벡터를 RAM에 저장해서 가장 빠르고, 디스크 접근은 영속화(persistence)할 때만 일어나요.
- Memmap 저장: 디스크의 파일과 연결된 가상 주소 공간을 만들어요. 파일을 RAM에 직접 올리지 않고 페이지 캐시로 접근해서 사용 가능한 메모리를 유연하게 써요.
Memmap 저장 설정
memmap(또는 on-disk) 저장 방식을 설정하는 두 가지 방법이 있어요.
컬렉션 생성 API에서 벡터의 on_disk 옵션을 켜는 방법 (v1.2.0부터):
PUT /collections/{collection_name}
{
"vectors": {
"size": 768,
"distance": "Cosine",
"on_disk": true
}
}
memmap_threshold 옵션을 설정하는 방법: 이 옵션은 세그먼트가 memmap 저장으로 전환되는 기준 크기를 정해요. 설정 파일에서 전역으로, 또는 컬렉션 생성 시 지정할 수 있어요.
HNSW 인덱스도 디스크에 저장하려면 컬렉션 생성·업데이트 시 hnsw_config.on_disk를 true로 설정해요.
PUT /collections/{collection_name}
{
"vectors": {
"size": 768,
"distance": "Cosine",
"on_disk": true
},
"hnsw_config": {
"on_disk": true
}
}
페이로드 저장 방식
Qdrant는 두 가지 페이로드 저장 방식을 지원해요: InMemory와 OnDisk.
InMemory 페이로드 저장은 인메모리 벡터와 같은 방식으로 구성돼요. 서비스 시작 시 페이로드 데이터가 RAM에 로드되고, 디스크는 영속화에만 사용돼요.
원하는 페이로드 저장 방식을 설정 파일로 지정하거나, 컬렉션 생성 시 on_disk_payload 파라미터로 지정할 수 있어요.
버전 관리 (Versioning)
데이터 무결성을 지키기 위해 Qdrant는 모든 데이터 변경을 2단계로 수행해요.
- 먼저 데이터를 Write-ahead-log(WAL)에 기록해요. WAL은 모든 작업을 순서대로 정렬하고 순차 번호를 부여해요. 변경이 WAL에 들어가면 전원이 끊겨도 유실되지 않아요.
- 그 다음 변경이 세그먼트로 반영돼요. 세그먼트는 자신에게 적용된 마지막 변경 버전과 각 포인트의 버전을 저장해요. 새 변경의 순차 번호가 현재 포인트 버전보다 작으면 업데이터가 그 변경을 무시해요.
이 메커니즘 덕분에 비정상 종료가 발생해도 WAL에서 저장소를 안전하고 효율적으로 복구할 수 있어요.