저장
저장 (Storage)
Weaviate는 영구적이고 내결함성이 있는 데이터베이스예요. 이 페이지에서는 Weaviate 안에서 객체와 벡터가 어떻게 저장되고, 임포트 시점에 역인덱스가 어떻게 만들어지는지 개요를 보여 줍니다. Weaviate만의 독특한 기능들은 이 저장 구조 위에서 만들어져요.
출처: 공식문서
저장 구조가 만드는 Weaviate의 특징
- 모든 쓰기 연산은 즉시 영구화되고, 애플리케이션·시스템 크래시에도 견딜 수 있어요.
- 벡터 검색 쿼리에서 Weaviate는 ID 같은 참조만이 아니라 전체 객체(다른 DB에서는 가끔 "문서"라고 하는)를 반환해요.
- 구조화 검색을 벡터 검색과 결합할 때, 필터는 벡터 검색보다 먼저 적용돼요. 그래서 최종 결과 수가 예측 불가능한 사후 필터링과 달리 항상 지정한 개수의 요소를 받을 수 있어요.
논리적 저장 단위: Index, Shard, Store
사용자 정의 스키마의 각 클래스는 내부적으로 하나의 인덱스를 만들게 돼요. 인덱스는 하나 이상의 샤드(shard)로 구성된 래퍼 타입이에요. 인덱스 안의 샤드는 자기 완결적인 저장 단위예요.
여러 샤드를 사용해 여러 서버 노드로 부하를 자동 분산할 수 있어요.
샤드의 구성 요소
각 샤드는 세 가지 핵심 컴포넌트를 담아요.
- 객체 저장소(object store) — 본질적으로 키-값 저장소
- 역인덱스(inverted index)
- 벡터 인덱스 저장소(플러그 가능하며, 현재는 HNSW의 커스텀 구현)
객체·역인덱스 저장소
v1.5.0부터 객체 저장소와 역인덱스 저장소는 LSM-Tree 방식으로 구현돼요. 이는 데이터를 메모리 속도로 수집하고, 구성된 임계값을 넘으면 정렬된 전체 memtable을 디스크 세그먼트로 쓰는 방식이에요. 읽기 요청이 오면 Weaviate는 먼저 Memtable에서 특정 객체의 최신 업데이트를 확인해요.
역인덱스에서는 데이터가 거의 교체되지 않고 주로 추가(append) 돼요. 병합은 과거의 모든 세그먼트를 확인해 결과를 집계하는 대신, 단일(또는 몇 개의 큰) 세그먼트만 확인해 관련 객체 포인터를 모두 즉시 찾을 수 있게 해요.
v1.5.0 이전 버전의 Weaviate는 B+Tree 저장 메커니즘을 사용했어요. LSM 방식이 더 빠르고 상수 시간으로 동작하며 쓰기 성능을 향상시켜요. LSM 저장소에 대해 더 알고 싶다면 Go 패키지 저장소의 LSM 라이브러리 문서를 참고하세요.
HNSW 벡터 인덱스 저장소
각 샤드는 객체·역인덱스 저장소에 대응하는 벡터 인덱스를 포함해요. 벡터 저장소는 다른 저장소와 독립적이라 세그먼테이션을 관리할 필요가 없어요. 벡터 인덱스를 샤드 안의 객체 저장소와 함께 묶음으로써, 각 샤드를 완전히 자기 완결적인 유닛으로 만들어 자신이 소유한 데이터 요청을 독립적으로 서빙할 수 있게 해요.
샤드 컴포넌트 최적화
Weaviate의 저장 메커니즘은 구조화/객체 데이터에 세그먼테이션을 사용해요. 세그먼트는 병합 비용이 싸고, Bloom 필터 덕분에 병합되지 않은 세그먼트도 효율적으로 탐색할 수 있어요. 그 결과 수집 속도가 높고 시간이 지나도 저하되지 않아요.
Weaviate는 벡터 인덱스를 샤드 내에서 최대한 크게 유지해요. HNSW 인덱스는 효율적으로 병합할 수 없기 때문에, 작은 인덱스 여러 개를 순차적으로 쿼리하는 것보다 큰 인덱스 하나를 쿼리하는 것이 더 효율적이에요.
Lazy 샤드 로딩
Weaviate가 시작되면 배포의 모든 샤드에서 데이터를 로드해요. 이 과정은 오래 걸릴 수 있어요. 모든 테넌트가 샤드 하나이므로, 테넌트가 많은 멀티테넌트 배포는 재시작 후 가용성이 떨어질 수 있어요.
Lazy 샤드 로딩을 사용하면 데이터 작업을 더 빨리 시작할 수 있어요. 재시작 후 샤드는 백그라운드에서 로드돼요. 쿼리하려는 샤드가 이미 로드됐다면 결과를 더 빨리 받을 수 있고, 아직 로드되지 않았다면 Weaviate가 그 샤드 로딩을 우선시해 준비되면 응답을 반환해요.
벡터 캐시 프리필 동작
v1.36.6 이전에는 lazy 샤드 로딩이 모든 컬렉션에서 기본으로 활성화됐어요. v1.36.6부터는 멀티테넌트 컬렉션이 개수나 크기 임계값을 넘기 전까지 샤드를 기본적으로 eager하게 로드해요.
영속성과 크래시 복구
HNSW 스냅샷
Weaviate는 디스크 상태를 여러 방식으로 보호해요. 스냅샷과 압축된 커밋 로그는 임시 경로에 쓰여진 뒤 원자적으로 제자리로 이름이 바뀌어요. 그래서 중단된 쓰기가 완전한 파일로 오인될 수 없고, 고아 임시 파일은 다음 시작 시 정리돼요.
정리
이 페이지에서 Weaviate의 저장 메커니즘을 소개했어요. 모든 쓰기는 승인 전에 로그에 영구화되고, 데이터셋을 잘 확장시키기 위한 패턴이 어떤지 살펴봤어요. 구조화 데이터에 대해 Weaviate는 세그먼테이션을 사용해 쓰기 시간을 상수로 유지해요.