Milvus 벡터 데이터베이스 실무: Java 연동 가이드

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
  • 파티셔닝: 데이터 카테고리별 분할 관리
  • 배치 처리: 벡터 일괄 삽입/검색 활용
  • 메모리 최적화: 빈번한 접근 컬렉션 메모리 상주

태그: Milvus java VectorDatabase RAG Embedding

6월 1일 18:38에 게시됨