Milvus 핵심 개념
벡터 데이터베이스는 RAG 시스템에서 고차원 벡터를 저장하고 검색하는 핵심 요소입니다. Milvus는 대규모 벡터 처리를 지원하는 대표적인 오픈소스 솔루션입니다.
- 컬렉션: 벡터 데이터 집합(테이블 개념)
- 파티션: 쿼리 성능 향상을 위한 논리적 분할
- 벡터 필드: 다차원 벡터 저장 전용 필드
- 인덱스: 검색 효율 결정(IVF_FLAT, HNSW 등)
- 유사도 측정: 코사인, L2, 내적 거리 계산 방식
Docker 기반 Milvus 실행
# Docker 설정 파일 다운로드
curl -O https://github.com/milvus-io/milvus/releases/download/v2.3.3/milvus-standalone-docker-compose.yml
# 컨테이너 실행
docker compose -f milvus-standalone-docker-compose.yml up -d
# 실행 상태 확인
docker container ls --filter name=milvus
Java 클라이언트 설정
<dependency>
<groupId>io.milvus</groupId>
<artifactId>milvus-sdk-java</artifactId>
<version>2.3.4</version>
</dependency>
import io.milvus.client.MilvusServiceClient;
import io.milvus.param.ConnectParam;
public class MilvusConnector {
private static final String SERVER = "127.0.0.1";
private static final int CONN_PORT = 19530;
public static MilvusServiceClient initConnection() {
ConnectParam config = ConnectParam.newBuilder()
.withHost(SERVER)
.withPort(CONN_PORT)
.build();
return new MilvusServiceClient(config);
}
}
데이터 컬렉션 생성
public void buildCollection(MilvusServiceClient milvusClient) {
// 스키마 필드 정의
FieldType recordId = FieldType.newBuilder()
.withName("record_id")
.withDataType(DataType.Int64)
.withPrimaryKey(true)
.build();
FieldType contentVector = FieldType.newBuilder()
.withName("content_vector")
.withDataType(DataType.FloatVector)
.withDimension(1536) // OpenAI 임베딩 차원
.build();
// 컬렉션 생성 파라미터
CreateCollectionParam collectionConfig = CreateCollectionParam.newBuilder()
.withCollectionName("knowledge_base")
.addFieldType(recordId)
.addFieldType(contentVector)
.build();
milvusClient.createCollection(collectionConfig);
}
벡터 데이터 적재
public void loadVectors(MilvusServiceClient client, List<Float[]> embeddings) {
List<Long> ids = LongStream.range(1, embeddings.size()+1)
.boxed().collect(Collectors.toList());
List<List<Float>> vectors = embeddings.stream()
.map(Arrays::asList)
.collect(Collectors.toList());
InsertParam insertRequest = InsertParam.newBuilder()
.withCollectionName("knowledge_base")
.addField(new InsertParam.Field("record_id", ids))
.addField(new InsertParam.Field("content_vector", vectors))
.build();
client.insert(insertRequest);
client.loadCollection(LoadCollectionParam.newBuilder()
.withCollectionName("knowledge_base").build());
}
유사도 검색 수행
public void querySimilar(MilvusServiceClient client, float[] searchVector, int resultCount) {
SearchParam searchConfig = SearchParam.newBuilder()
.withCollectionName("knowledge_base")
.withVectorFieldName("content_vector")
.withTopK(resultCount)
.withVectors(Collections.singletonList(
Arrays.asList(
ArrayUtils.toObject(searchVector))
))
.withMetricType(MetricType.COSINE)
.build();
SearchResults results = client.search(searchConfig);
results.getRowRecords().forEach(item ->
System.out.println("유사도: " + item.getScore()
+ " | ID: " + item.get("record_id"))
);
}
성능 개선 전략
- 인덱스 선택: 정밀 검색엔 HNSW, 대용량엔 IVF_FLAT
- 파티셔닝: 데이터 카테고리별 분할 관리
- 배치 처리: 벡터 일괄 삽입/검색 활용
- 메모리 최적화: 빈번한 접근 컬렉션 메모리 상주