Tutorial Milvus: Distributed Vector Database untuk AI

# Tutorial 10: Milvus - Database Vektor Terdistribusi untuk AI ## Daftar Isi 1. [Pendahuluan](#pendahuluan) 2. [Prasyarat](#prasyarat) 3. [Arsitektur Milvus](#arsitektur-milvus) 4. [Instalasi dan Pe...

By Ruby Abdullah · · tutorial
MilvusVector DatabaseDistributedSimilarity SearchAIPython

Tutorial 10: Milvus - Database Vektor Terdistribusi untuk AI

Daftar Isi

  • Pendahuluan
  • Prasyarat
  • Arsitektur Milvus
  • Instalasi dan Pengaturan
  • Manajemen Koleksi, Partisi, dan Indeks
  • Strategi Pengindeksan Vektor
  • Pencarian Hibrida: Vektor + Filter Skalar
  • Operasi Batch
  • Penskalaan dengan Kubernetes
  • Perbandingan dengan Qdrant, ChromaDB, dan Pinecone
  • Integrasi dengan LangChain
  • Deployment Produksi
  • Praktik Terbaik
  • Kesimpulan

  • Pendahuluan

    Seiring aplikasi AI semakin bergantung pada pencarian semantik, sistem rekomendasi, dan retrieval-augmented generation (RAG), kebutuhan akan penyimpanan dan pengambilan vektor yang efisien menjadi sangat kritis. Milvus adalah database vektor open-source dan terdistribusi yang dirancang khusus untuk menangani data vektor berskala miliaran dengan latensi milidetik.

    Berbeda dengan database tujuan umum yang menambahkan pencarian vektor sebagai fitur tambahan, Milvus dirancang dari awal untuk pencarian kemiripan (similarity search). Platform ini mendukung berbagai jenis indeks (IVFFLAT, HNSW, IVFPQ, dan lainnya), pencarian hibrida yang menggabungkan kemiripan vektor dengan filter skalar, penskalaan horizontal di seluruh kluster, dan integrasi yang mulus dengan framework ML.

    Tutorial ini memberikan panduan komprehensif dan praktis tentang Milvus, dari pengaturan dasar hingga deployment produksi.


    Prasyarat

    • Python 3.9 atau lebih tinggi
    • Docker dan Docker Compose (untuk deployment Milvus lokal)
    • Pemahaman dasar tentang embedding vektor dan pencarian kemiripan
    • Keakraban dengan struktur data Python

    Instal paket yang diperlukan:

    pip install pymilvus langchain langchain-openai numpy pandas
    


    Arsitektur Milvus

    Milvus menggunakan arsitektur cloud-native yang terpisah (disaggregated) dengan empat lapisan utama:

    Lapisan Akses - Node proxy stateless yang menangani koneksi klien, perutean permintaan, dan agregasi hasil. Node-node ini dapat diskalakan secara horizontal dan berada di belakang load balancer. Layanan Koordinator - Otak dari kluster, bertanggung jawab atas manajemen metadata, koordinasi query, dan koordinasi data. Layanan ini mengelola skema koleksi, tugas pembuatan indeks, dan perutean query. Node Pekerja - Dibagi menjadi tiga jenis:
    • Node Query: Menjalankan operasi pencarian dan query pada segmen yang dimuat
    • Node Data: Menangani penyisipan, penghapusan, dan kompaksi data
    • Node Indeks: Membangun indeks vektor di latar belakang

    Lapisan Penyimpanan - Menggunakan object storage (MinIO/S3) untuk data persisten dan etcd untuk metadata. Pemisahan ini memungkinkan penskalaan komputasi dan penyimpanan secara independen.
    Aplikasi Klien
    

    |

    [Lapisan Akses - Node Proxy]

    |

    [Layanan Koordinator]

    / | \

    [Node] [Node] [Node]

    Query Data Indeks

    |

    [Object Storage + etcd]


    Instalasi dan Pengaturan

    Pengaturan Lokal dengan Docker Compose

    # Unduh file docker-compose
    

    wget https://github.com/milvus-io/milvus/releases/download/v2.4.0/milvus-standalone-docker-compose.yml -O docker-compose.yml

    Jalankan Milvus

    docker compose up -d

    Verifikasi bahwa Milvus berjalan

    docker compose ps

    Menghubungkan dari Python

    from pymilvus import connections, utility
    
    

    Hubungkan ke Milvus

    connections.connect(

    alias="default",

    host="localhost",

    port="19530"

    )

    Verifikasi koneksi

    print(f"Terhubung ke Milvus. Versi server: {utility.getserverversion()}")

    Daftar koleksi yang ada

    koleksi = utility.listcollections()

    print(f"Koleksi yang ada: {koleksi}")

    Menggunakan Milvus Lite (Dalam Proses)

    from pymilvus import MilvusClient
    
    

    Milvus Lite berjalan dalam proses, tidak perlu server

    client = MilvusClient("./milvusdemo.db")

    Ini ideal untuk pengembangan, pengujian, dan dataset kecil

    print("Klien Milvus Lite berhasil diinisialisasi.")


    Manajemen Koleksi, Partisi, dan Indeks

    Membuat Koleksi

    from pymilvus import (
    

    Collection, CollectionSchema, FieldSchema, DataType,

    connections, utility

    )

    connections.connect(host="localhost", port="19530")

    Definisikan skema

    fields = [

    FieldSchema(

    name="id",

    dtype=DataType.INT64,

    isprimary=True,

    autoid=True,

    ),

    FieldSchema(

    name="judul",

    dtype=DataType.VARCHAR,

    maxlength=500,

    ),

    FieldSchema(

    name="kategori",

    dtype=DataType.VARCHAR,

    maxlength=100,

    ),

    FieldSchema(

    name="tahun",

    dtype=DataType.INT32,

    ),

    FieldSchema(

    name="embedding",

    dtype=DataType.FLOATVECTOR,

    dim=1536, # Dimensi OpenAI text-embedding-3-small

    ),

    ]

    schema = CollectionSchema(

    fields=fields,

    description="Koleksi dokumen untuk pencarian semantik",

    enabledynamicfield=True, # Izinkan field tambahan

    )

    Buat koleksi

    namakoleksi = "dokumen"

    if utility.hascollection(namakoleksi):

    utility.dropcollection(namakoleksi)

    collection = Collection(

    name=namakoleksi,

    schema=schema,

    consistencylevel="Strong",

    )

    print(f"Koleksi '{namakoleksi}' berhasil dibuat.")

    print(f"Skema: {collection.schema}")

    Mengelola Partisi

    # Buat partisi untuk organisasi data
    

    collection = Collection("dokumen")

    Buat partisi berdasarkan kategori

    partisi = ["teknologi", "sains", "bisnis", "kesehatan"]

    for namapartisi in partisi:

    if not collection.haspartition(namapartisi):

    collection.createpartition(namapartisi)

    print(f"Partisi '{namapartisi}' berhasil dibuat.")

    Daftar semua partisi

    print(f"Semua partisi: {[p.name for p in collection.partitions]}")

    Sisipkan data ke partisi tertentu

    import numpy as np

    data = [

    ["Pengantar Machine Learning"], # judul

    ["teknologi"], # kategori

    [2024], # tahun

    [np.random.rand(1536).tolist()], # embedding

    ]

    collection.insert(data, partitionname="teknologi")

    print("Data berhasil disisipkan ke partisi 'teknologi'.")

    Manajemen Indeks

    # Buat indeks pada field vektor
    

    paramindeks = {

    "metrictype": "COSINE", # L2, IP, atau COSINE

    "indextype": "HNSW",

    "params": {

    "M": 16, # Jumlah tautan bi-directional

    "efConstruction": 256, # Lebar pencarian saat konstruksi

    },

    }

    collection.createindex(

    fieldname="embedding",

    indexparams=paramindeks,

    )

    print("Indeks HNSW dibuat pada field 'embedding'.")

    Buat indeks skalar untuk filtering

    collection.createindex(

    fieldname="kategori",

    indexparams={"indextype": "Trie"},

    )

    collection.createindex(

    fieldname="tahun",

    indexparams={"indextype": "STLSORT"},

    )

    print("Indeks skalar dibuat pada field 'kategori' dan 'tahun'.")

    Muat koleksi ke memori untuk pencarian

    collection.load()

    print("Koleksi dimuat ke memori.")


    Strategi Pengindeksan Vektor

    IVFFLAT: Keseimbangan Kecepatan dan Akurasi

    # IVFFLAT mempartisi vektor ke dalam kluster menggunakan k-means
    

    Baik untuk dataset berukuran sedang di mana akurasi penting

    paramivfflat = {

    "metrictype": "COSINE",

    "indextype": "IVFFLAT",

    "params": {

    "nlist": 1024, # Jumlah centroid kluster

    },

    }

    Parameter pencarian untuk IVFFLAT

    paramcariivf = {

    "metrictype": "COSINE",

    "params": {

    "nprobe": 64, # Jumlah kluster yang dicari (lebih tinggi = lebih akurat)

    },

    }

    Kapan menggunakan:

    - Ukuran dataset: 1 juta - 10 juta vektor

    - Butuh recall yang baik dengan kecepatan yang wajar

    - Tidak bisa mentoleransi artefak kompresi

    HNSW: Recall Tinggi dengan Pencarian Berbasis Graf

    # HNSW membangun graf navigasi multi-lapisan
    

    Terbaik untuk kebutuhan recall tinggi

    paramhnsw = {

    "metrictype": "COSINE",

    "indextype": "HNSW",

    "params": {

    "M": 32, # M lebih tinggi = recall lebih baik, lebih banyak memori

    "efConstruction": 512, # Lebih tinggi = kualitas graf lebih baik, konstruksi lebih lambat

    },

    }

    Parameter pencarian untuk HNSW

    paramcarihnsw = {

    "metrictype": "COSINE",

    "params": {

    "ef": 256, # Keluasan pencarian (lebih tinggi = recall lebih baik, lebih lambat)

    },

    }

    Kapan menggunakan:

    - Butuh recall terbaik (>99%)

    - Memiliki memori yang cukup (HNSW intensif memori)

    - Ukuran dataset: hingga ~50 juta vektor per node

    IVFPQ: Hemat Memori untuk Dataset Besar

    # IVFPQ menggabungkan inverted file index dengan product quantization
    

    Menukar akurasi dengan penghematan memori yang besar

    paramivfpq = {

    "metrictype": "L2",

    "indextype": "IVFPQ",

    "params": {

    "nlist": 2048, # Jumlah kluster

    "m": 16, # Jumlah sub-quantizer (harus membagi dimensi secara rata)

    "nbits": 8, # Bit per kode sub-quantizer

    },

    }

    Parameter pencarian untuk IVFPQ

    paramcaripq = {

    "metrictype": "L2",

    "params": {

    "nprobe": 128,

    },

    }

    Kapan menggunakan:

    - Dataset skala miliaran

    - Memori adalah kendala utama

    - Bisa mentoleransi penurunan recall ~5-10%

    - Penghematan memori: ~32x dibandingkan flat index untuk vektor 1536 dimensi

    Memilih Indeks yang Tepat

    def rekomendasikanindeks(jumlahvektor: int, dimensi: int,
    

    memorigb: float, targetrecall: float) -> str:

    """Merekomendasikan jenis indeks berdasarkan kebutuhan."""

    memoriflat = (jumlahvektor dimensi 4) / (1024*3) # GB

    if jumlahvektor < 100000:

    return "FLAT - Dataset kecil, brute force sudah cukup"

    if targetrecall > 0.99 and memoriflat < memorigb 0.5:

    return "HNSW - Kebutuhan recall tinggi, memori cukup"

    if memoriflat > memorigb:

    return "IVFPQ - Dataset terlalu besar untuk memori, gunakan kompresi"

    return "IVFFLAT - Keseimbangan baik antara kecepatan, akurasi, dan memori"

    Contoh penggunaan

    print(rekomendasikanindeks(50000, 1536, 16, 0.95))

    print(rekomendasikanindeks(5000000, 1536, 32, 0.99))

    print(rekomendasikanindeks(500000000, 768, 64, 0.90))


    Pencarian Hibrida: Vektor + Filter Skalar

    Pencarian Hibrida Dasar

    from pymilvus import Collection
    

    import numpy as np

    collection = Collection("dokumen")

    collection.load()

    Buat embedding query (dalam praktiknya, gunakan model embedding Anda)

    embeddingquery = np.random.rand(1536).tolist()

    Pencarian dengan filter skalar

    hasil = collection.search(

    data=[embeddingquery],

    annsfield="embedding",

    param={"metrictype": "COSINE", "params": {"ef": 128}},

    limit=10,

    expr='kategori == "teknologi" and tahun >= 2023',

    outputfields=["judul", "kategori", "tahun"],

    )

    for hits in hasil:

    for hit in hits:

    print(f"ID: {hit.id}")

    print(f" Skor: {hit.score:.4f}")

    print(f" Judul: {hit.entity.get('judul')}")

    print(f" Kategori: {hit.entity.get('kategori')}")

    print(f" Tahun: {hit.entity.get('tahun')}")

    print()

    Ekspresi Filter Kompleks

    # Ekspresi boolean untuk filtering
    

    filterlist = [

    'kategori == "teknologi"',

    'tahun >= 2023 and tahun <= 2025',

    'kategori in ["teknologi", "sains"]',

    'judul like "Machine%"',

    'tahun > 2020 and kategori != "bisnis"',

    ]

    for ekspresifilter in filterlist:

    hasil = collection.search(

    data=[embeddingquery],

    annsfield="embedding",

    param={"metrictype": "COSINE", "params": {"ef": 64}},

    limit=5,

    expr=ekspresifilter,

    outputfields=["judul", "kategori", "tahun"],

    )

    jumlah = sum(len(hits) for hits in hasil)

    print(f"Filter: {ekspresifilter} -> {jumlah} hasil")

    Pencarian Multi-Vektor (Reranking)

    from pymilvus import AnnSearchRequest, RRFRanker
    
    

    Pencarian dengan beberapa vektor query dan rerank

    request1 = AnnSearchRequest(

    data=[embeddingquery],

    annsfield="embedding",

    param={"metrictype": "COSINE", "params": {"ef": 128}},

    limit=20,

    expr='kategori == "teknologi"',

    )

    Vektor query kedua (misalnya, dari representasi berbeda)

    embeddingquery2 = np.random.rand(1536).tolist()

    request2 = AnnSearchRequest(

    data=[embeddingquery2],

    annsfield="embedding",

    param={"metrictype": "COSINE", "params": {"ef": 128}},

    limit=20,

    )

    Gabungkan hasil menggunakan Reciprocal Rank Fusion

    reranker = RRFRanker(k=60)

    hasil = collection.hybridsearch(

    reqs=[request1, request2],

    ranker=reranker,

    limit=10,

    outputfields=["judul", "kategori"],

    )

    for hits in hasil:

    for peringkat, hit in enumerate(hits, 1):

    print(f"Peringkat {peringkat}: {hit.entity.get('judul')} "

    f"(skor: {hit.score:.4f})")


    Operasi Batch

    Sisipan Massal (Bulk Insert)

    import numpy as np
    

    from pymilvus import Collection

    collection = Collection("dokumen")

    Buat data batch

    ukuranbatch = 10000

    judullist = [f"Dokumen {i}" for i in range(ukuranbatch)]

    kategorilist = np.random.choice(

    ["teknologi", "sains", "bisnis", "kesehatan"],

    size=ukuranbatch

    ).tolist()

    tahunlist = np.random.randint(2020, 2026, size=ukuranbatch).tolist()

    embeddinglist = np.random.rand(ukuranbatch, 1536).tolist()

    Sisipkan dalam batch untuk menghindari masalah memori

    ukuranchunk = 2000

    for i in range(0, ukuranbatch, ukuranchunk):

    akhir = min(i + ukuranchunk, ukuranbatch)

    data = [

    judullist[i:akhir],

    kategorilist[i:akhir],

    tahunlist[i:akhir],

    embeddinglist[i:akhir],

    ]

    collection.insert(data)

    print(f"Batch {i // ukuranchunk + 1} disisipkan: "

    f"rekaman {i} hingga {akhir}")

    Flush untuk memastikan data tersimpan

    collection.flush()

    print(f"Total entitas: {collection.numentities}")

    Penghapusan Massal

    # Hapus berdasarkan ekspresi
    

    collection.delete(expr='tahun < 2022')

    print("Semua dokumen sebelum 2022 berhasil dihapus.")

    Hapus berdasarkan primary key

    iduntukdihapus = [1, 2, 3, 4, 5]

    collection.delete(expr=f"id in {iduntukdihapus}")

    print(f"{len(iduntukdihapus)} dokumen berhasil dihapus berdasarkan ID.")

    Kompaksi untuk mengklaim kembali ruang

    collection.compact()

    print("Kompaksi dimulai.")

    Operasi Upsert

    # Upsert (sisipkan atau perbarui) data
    

    dataupsert = [

    [100, 101, 102], # id (eksplisit)

    ["Dokumen Diperbarui 1", "Dokumen Diperbarui 2",

    "Dokumen Diperbarui 3"], # judul

    ["teknologi", "sains", "bisnis"], # kategori

    [2025, 2025, 2025], # tahun

    [np.random.rand(1536).tolist() for in range(3)], # embedding

    ]

    Catatan: untuk upsert, autoid harus False dan ID harus disediakan

    collection.upsert(dataupsert)


    Penskalaan dengan Kubernetes

    Deployment dengan Helm Chart

    # Tambahkan repositori Helm Milvus
    

    helm repo add milvus https://zilliztech.github.io/milvus-helm/

    helm repo update

    Instal kluster Milvus

    helm install milvus-saya milvus/milvus \

    --set cluster.enabled=true \

    --set queryNode.replicas=3 \

    --set dataNode.replicas=2 \

    --set indexNode.replicas=2 \

    --set proxy.replicas=2 \

    --namespace milvus \

    --create-namespace

    Konfigurasi Sumber Daya

    # values.yaml untuk deployment produksi
    

    cluster:

    enabled: true

    queryNode:

    replicas: 3

    resources:

    requests:

    cpu: "4"

    memory: "16Gi"

    limits:

    cpu: "8"

    memory: "32Gi"

    dataNode:

    replicas: 2

    resources:

    requests:

    cpu: "2"

    memory: "8Gi"

    limits:

    cpu: "4"

    memory: "16Gi"

    indexNode:

    replicas: 2

    resources:

    requests:

    cpu: "4"

    memory: "16Gi"

    limits:

    cpu: "8"

    memory: "32Gi"

    proxy:

    replicas: 2

    resources:

    requests:

    cpu: "1"

    memory: "4Gi"

    limits:

    cpu: "2"

    memory: "8Gi"

    minio:

    persistence:

    size: 500Gi

    resources:

    requests:

    cpu: "2"

    memory: "4Gi"

    etcd:

    replicaCount: 3

    persistence:

    size: 20Gi


    Perbandingan dengan Qdrant, ChromaDB, dan Pinecone

    """
    

    Matriks Perbandingan Database Vektor

    | Fitur | Milvus | Qdrant | ChromaDB | Pinecone |

    |----------------------|----------------|----------------|----------------|----------------|

    | Deployment | Self-hosted/ | Self-hosted/ | Self-hosted/ | Fully managed |

    | | Zilliz Cloud | Qdrant Cloud | Embedded | |

    | Maks Vektor | Miliaran | Miliaran | Jutaan | Miliaran |

    | Jenis Indeks | IVF, HNSW, PQ, | HNSW | HNSW | Proprietary |

    | | DiskANN, +lain | | | |

    | Pencarian Hibrida | Ya | Ya | Terbatas | Ya |

    | Filter Skalar | SQL-like penuh | JSON payload | Metadata | Metadata |

    | Multi-tenancy | Partisi | Koleksi | Koleksi | Namespace |

    | Akselerasi GPU | Ya | Tidak | Tidak | N/A |

    | Replikasi | Ya | Ya | Tidak | Dikelola |

    | Lisensi | Apache 2.0 | Apache 2.0 | Apache 2.0 | Proprietary |

    | Terbaik Untuk | Skala besar | Skala menengah | Prototipe, | Tanpa ops, |

    | | produksi | ramah | aplikasi kecil | enterprise |

    | | | pengembang | | |

    """

    Perbandingan cepat dalam kode

    def bandingkankinerjasisipan():

    """Membandingkan operasi dasar di berbagai database vektor."""

    # Milvus

    from pymilvus import Collection

    import time

    import numpy as np

    collection = Collection("dokumen")

    vektor = np.random.rand(1000, 1536).tolist()

    judul = [f"Dok {i}" for i in range(1000)]

    kategori = ["teknologi"] 1000

    tahun = [2024] 1000

    mulai = time.time()

    collection.insert([judul, kategori, tahun, vektor])

    collection.flush()

    waktumilvus = time.time() - mulai

    print(f"Milvus sisipan 1000 vektor: {waktumilvus:.3f} detik")


    Integrasi dengan LangChain

    Menggunakan Milvus sebagai Vector Store LangChain

    from langchainopenai import OpenAIEmbeddings, ChatOpenAI
    

    from langchaincommunity.vectorstores import Milvus

    from langchaincore.documents import Document

    from langchaincore.prompts import ChatPromptTemplate

    from langchaincore.outputparsers import StrOutputParser

    Inisialisasi embeddings

    embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

    Buat dokumen

    dokumen = [

    Document(

    pagecontent="Milvus adalah database vektor open-source yang dirancang untuk aplikasi AI.",

    metadata={"sumber": "docs", "kategori": "database", "tahun": 2024},

    ),

    Document(

    pagecontent="HNSW adalah indeks berbasis graf yang memberikan recall tinggi untuk pencarian vektor.",

    metadata={"sumber": "docs", "kategori": "pengindeksan", "tahun": 2024},

    ),

    Document(

    pagecontent="RAG menggabungkan retrieval dan generation untuk respons AI yang berbasis pengetahuan.",

    metadata={"sumber": "blog", "kategori": "arsitektur", "tahun": 2024},

    ),

    Document(

    pagecontent="Kuantisasi vektor mengurangi penggunaan memori dengan mengompresi representasi vektor.",

    metadata={"sumber": "paper", "kategori": "optimisasi", "tahun": 2023},

    ),

    Document(

    pagecontent="Pencarian hibrida menggabungkan kemiripan vektor dense dengan pencocokan kata kunci sparse.",

    metadata={"sumber": "docs", "kategori": "pencarian", "tahun": 2024},

    ),

    ]

    Buat vector store Milvus

    vectorstore = Milvus.fromdocuments(

    documents=dokumen,

    embedding=embeddings,

    collectionname="langchaindocs",

    connectionargs={"host": "localhost", "port": "19530"},

    dropold=True,

    )

    print("Vector store berhasil dibuat dengan integrasi LangChain.")

    Pipeline RAG dengan Milvus

    # Buat retriever
    

    retriever = vectorstore.asretriever(

    searchtype="similarity",

    searchkwargs={"k": 3},

    )

    Bangun chain RAG

    llm = ChatOpenAI(model="gpt-4o", temperature=0)

    prompt = ChatPromptTemplate.fromtemplate(

    "Jawab pertanyaan berdasarkan konteks yang diberikan.\n\n"

    "Konteks:\n{context}\n\n"

    "Pertanyaan: {question}\n\n"

    "Jawaban:"

    )

    def formatdocs(docs):

    return "\n\n".join(doc.pagecontent for doc in docs)

    chain = (

    {"context": retriever | formatdocs, "question": lambda x: x}

    | prompt

    | llm

    | StrOutputParser()

    )

    Query pipeline RAG

    jawaban = chain.invoke("Apa itu pencarian hibrida dan bagaimana cara kerjanya?")

    print(f"Jawaban: {jawaban}")

    Pencarian dengan filter metadata

    hasilterfilter = vectorstore.similaritysearch(

    "teknik pengindeksan vektor",

    k=3,

    expr='kategori == "pengindeksan" or kategori == "optimisasi"',

    )

    for doc in hasilterfilter:

    print(f"Konten: {doc.pagecontent[:80]}...")

    print(f"Metadata: {doc.metadata}")

    print()


    Deployment Produksi

    Monitoring Kesehatan

    from pymilvus import connections, utility
    
    

    def periksakesehatanmilvus() -> dict:

    """Pemeriksaan kesehatan komprehensif untuk Milvus."""

    try:

    connections.connect(host="localhost", port="19530")

    kesehatan = {

    "terhubung": True,

    "versi": utility.getserverversion(),

    "koleksi": [],

    }

    for nama in utility.listcollections():

    from pymilvus import Collection

    col = Collection(nama)

    infokoleksi = {

    "nama": nama,

    "jumlahentitas": col.numentities,

    "dimuat": utility.loadstate(nama).name,

    "partisi": len(col.partitions),

    "indeks": [idx.todict() for idx in col.indexes],

    }

    kesehatan["koleksi"].append(infokoleksi)

    return kesehatan

    except Exception as e:

    return {"terhubung": False, "error": str(e)}

    Jalankan pemeriksaan kesehatan

    status = periksakesehatanmilvus()

    print(f"Status Milvus: {'Sehat' if status['terhubung'] else 'Tidak Sehat'}")

    if status["terhubung"]:

    print(f"Versi: {status['versi']}")

    for col in status["koleksi"]:

    print(f" Koleksi '{col['nama']}': {col['jumlahentitas']} entitas, "

    f"status: {col['dimuat']}")

    Backup dan Pemulihan

    # Menggunakan alat milvus-backup
    

    Instal: https://github.com/zilliztech/milvus-backup

    import subprocess

    def backupkoleksi(namakoleksi: str, namabackup: str):

    """Backup koleksi Milvus."""

    cmd = [

    "milvus-backup", "create",

    "-n", namabackup,

    "-c", namakoleksi,

    "--config", "/path/to/backup.yaml"

    ]

    hasil = subprocess.run(cmd, captureoutput=True, text=True)

    print(f"Hasil backup: {hasil.stdout}")

    def pulihkankoleksi(namabackup: str):

    """Memulihkan koleksi Milvus dari backup."""

    cmd = [

    "milvus-backup", "restore",

    "-n", namabackup,

    "--config", "/path/to/backup.yaml"

    ]

    hasil = subprocess.run(cmd, captureoutput=True, text=True)

    print(f"Hasil pemulihan: {hasil.stdout}")

    Penyetelan Kinerja

    # Optimalkan kinerja pencarian
    

    def setelparampencarian(namakoleksi: str, vektorquery: list,

    groundtruth: list) -> dict:

    """Temukan parameter pencarian optimal dengan menguji berbagai konfigurasi."""

    from pymilvus import Collection

    import time

    collection = Collection(namakoleksi)

    collection.load()

    konfigurasi = [

    {"ef": 64},

    {"ef": 128},

    {"ef": 256},

    {"ef": 512},

    ]

    hasillist = []

    for konfig in konfigurasi:

    mulai = time.time()

    hasilcari = collection.search(

    data=vektorquery,

    annsfield="embedding",

    param={"metrictype": "COSINE", "params": konfig},

    limit=10,

    )

    durasi = time.time() - mulai

    hasillist.append({

    "params": konfig,

    "latensims": durasi * 1000,

    "jumlahhasil": sum(len(hits) for hits in hasilcari),

    })

    print("Hasil Penyetelan Parameter Pencarian:")

    for r in hasillist:

    print(f" ef={r['params']['ef']}: "

    f"latensi={r['latensims']:.1f}ms, "

    f"hasil={r['jumlahhasil']}")

    return hasillist


    Praktik Terbaik

  • Pilih jenis indeks yang tepat untuk kasus penggunaan Anda. Gunakan HNSW untuk aplikasi yang kritis terhadap recall di bawah 50 juta vektor, IVFFLAT untuk beban kerja seimbang, dan IVF_PQ ketika memori terbatas pada skala miliaran.
  • Partisi data Anda secara strategis. Gunakan partisi untuk mengisolasi data berdasarkan tenant, kategori, atau rentang waktu. Ini memungkinkan operasi tingkat partisi dan pencarian yang lebih efisien.
  • Atur ukuran segmen dengan tepat. Milvus mengorganisir data ke dalam segmen. Ukuran segmen default 512MB bekerja dengan baik untuk sebagian besar kasus. Tingkatkan untuk dataset yang sangat besar untuk mengurangi jumlah segmen.
  • Pra-filter dengan indeks skalar. Buat indeks skalar pada field yang sering difilter. Ini secara dramatis meningkatkan kinerja pencarian hibrida dengan mengurangi set kandidat sebelum perbandingan vektor.
  • Batch sisipan Anda. Sisipkan data dalam batch 1000-5000 vektor daripada satu per satu. Ini mengurangi overhead jaringan dan meningkatkan throughput 10-50x.
  • Pantau penggunaan memori. Indeks HNSW intensif memori. Koleksi 10 juta dengan vektor 1536 dimensi dan HNSW memerlukan sekitar 60-80GB RAM. Rencanakan kapasitas dengan tepat.
  • Gunakan tingkat konsistensi dengan bijak. Konsistensi kuat memastikan pembacaan melihat penulisan terbaru tetapi menambah latensi. Gunakan konsistensi "Eventually" untuk beban kerja baca-intensif di mana sedikit keterlambatan dapat diterima.
  • Terapkan connection pooling. Gunakan kembali koneksi daripada membuat yang baru untuk setiap permintaan. Gunakan fitur alias koneksi untuk mengelola beberapa pool koneksi.
  • Lakukan kompaksi secara teratur. Setelah banyak penghapusan, kompaksi mengklaim kembali ruang dan meningkatkan kinerja query. Jadwalkan kompaksi selama jam tidak sibuk.
  • Uji dengan data realistis. Benchmark dengan vektor dari model embedding aktual Anda, bukan vektor acak. Vektor acak memiliki properti distribusi yang berbeda dan menghasilkan angka kinerja yang menyesatkan.

  • Kesimpulan

    Milvus menyediakan fondasi yang kuat dan siap produksi untuk aplikasi AI yang memerlukan pencarian kemiripan vektor dalam skala besar. Arsitektur terpisahnya memungkinkan penskalaan komputasi dan penyimpanan secara independen, sementara dukungannya untuk berbagai jenis indeks memberikan fleksibilitas untuk mengoptimalkan kebutuhan latensi, recall, dan memori yang spesifik.

    Keputusan utama saat men-deploy Milvus adalah memilih jenis indeks yang tepat untuk skala dan kebutuhan akurasi Anda, merancang strategi partisi untuk multi-tenancy dan filtering yang efisien, dan mengatur ukuran kluster dengan tepat untuk beban kerja Anda. Dengan teknik-teknik yang dibahas dalam tutorial ini, Anda memiliki pengetahuan untuk membuat keputusan ini dengan percaya diri dan membangun pencarian vektor berkinerja tinggi ke dalam aplikasi AI Anda.

    Mulailah dengan Milvus Lite untuk pengembangan, beralih ke standalone Docker untuk staging, dan deploy kluster Kubernetes penuh untuk produksi. API-nya tetap sama di semua mode deployment, membuat transisi berjalan mulus.

    Artikel Terkait

    Tutorial Lengkap Qdrant: Vector Database untuk Aplikasi AI

    Tutorial Lengkap Qdrant: Vector Database untuk Aplikasi AI Qdrant adalah vector database performa tinggi yang dirancang ...

    Tutorial Lengkap LlamaIndex: Membangun Aplikasi RAG dengan LLM

    Tutorial Lengkap LlamaIndex: Membangun Aplikasi RAG dengan LLM LlamaIndex adalah framework data yang powerful untuk memb...

    Tutorial Lengkap ChromaDB: Vector Database Sederhana untuk AI

    Tutorial Lengkap ChromaDB: Vector Database Sederhana untuk AI ChromaDB adalah open-source vector database yang dirancang...

    Tutorial Lengkap Pinecone: Vector Database untuk AI dan Semantic Search

    Tutorial Lengkap Pinecone: Vector Database untuk AI dan Semantic Search Pinecone adalah managed vector database yang dir...