> For the complete documentation index, see [llms.txt](https://docs.clore.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.clore.ai/guides/guides_v2-de/rag-and-vektordatenbanken/milvus.md).

# Milvus

> **Die skalierbarste Open-Source-Vektordatenbank für KI-Anwendungen — entwickelt für Milliarden von Vektoren**

Milvus ist eine Open-Source-Vektordatenbank, die speziell für skalierbare Ähnlichkeitssuche und KI-Anwendungen entwickelt wurde. Ursprünglich von Zilliz erstellt und an die LF AI & Data Foundation gespendet, betreibt Milvus produktive KI-Workloads bei Unternehmen wie NVIDIA, AT\&T, IBM und Salesforce. Es ist die erste Wahl, wenn Sie auf Milliarden von Vektoren skalieren müssen.

**GitHub:** [milvus-io/milvus](https://github.com/milvus-io/milvus) — 32K+ ⭐

***

## Milvus vs. Qdrant — Wann man welches wählen sollte

| Kriterien               | Milvus                     | Qdrant              |
| ----------------------- | -------------------------- | ------------------- |
| Skalierung              | Milliarden von Vektoren    | Hunderte Millionen  |
| Architektur             | Verteilt (mehrere Dienste) | Einzelne Binärdatei |
| Einrichtungsaufwand     | Höher                      | Niedriger           |
| GPU-Index-Unterstützung | ✅ Native GPU-FAISS         | Begrenzt            |
| Multi-Tenancy           | ✅ Partitionen + Aliase     | Collection-basiert  |
| Streaming-Ingestion     | ✅ Kafka/Pulsar             | Begrenzt            |
| Hybride Suche           | ✅ Dense + Sparse           | ✅                   |
| Cloud-verwaltete Option | Zilliz Cloud               | Qdrant Cloud        |

{% hint style="success" %}
**Wählen Sie Milvus, wenn:** Sie auf Milliarden von Vektoren skalieren müssen, GPU-beschleunigtes Indexing (IVF\_FLAT\_GPU) benötigen oder Enterprise-Funktionen wie Multi-Tenancy, Streaming-Ingestion und rollenbasierte Zugriffskontrolle brauchen.
{% endhint %}

***

## Milvus-Architektur

Milvus im Standalone-Modus (Einzelserver) umfasst:

* **milvus** — der Hauptdienst (Proxy-, Query-, Daten- und Index-Koordinatoren)
* **etcd** — Metadatenspeicherung und Diensterkennung
* **MinIO** — Objektspeicher für Segmentdaten

Im verteilten Modus (Cluster) skaliert jede Komponente unabhängig.

***

## Voraussetzungen

* Clore.ai-Konto mit GPU-Miete
* Docker Compose (normalerweise vorinstalliert)
* Grundkenntnisse in Python
* 16 GB+ RAM (32 GB für die Produktion empfohlen)

***

## Schritt 1 — Mieten Sie einen GPU-Server auf Clore.ai

1. Gehe zu [clore.ai](https://clore.ai) → **Marktplatz**
2. **Empfohlene GPU:** RTX 4090 oder A100 für GPU-beschleunigtes Indexing
3. **CPU-Alternative:** Jeder Server mit 32 GB+ RAM für CPU-basiertes Indexing

**Mindestanforderungen:**

* CPU: 8 Kerne
* RAM: 16 GB (32 GB empfohlen)
* Festplatte: 50 GB SSD/NVMe
* GPU: Optional (nur für GPU-Index-Typen erforderlich)

{% hint style="info" %}
**GPU-Index-Typen in Milvus** (IVF\_FLAT\_GPU, IVFSQ8\_GPU) erfordern CUDA-fähige GPUs und beschleunigen den Indexaufbau für große Collections erheblich. Wenn Sie planen, regelmäßig 10 Mio.+ Vektoren zu indexieren, macht GPU-Indexing sich schnell bezahlt.
{% endhint %}

***

## Schritt 2 — Milvus Standalone bereitstellen

**Docker-Image:**

```
milvusdb/milvus:v2.4.0
```

Milvus Standalone benötigt etcd und MinIO. Verwenden Sie Docker Compose für die einfachste Einrichtung.

**Ports:**

```
22
19530
```

* **Port 19530:** Milvus SDK/gRPC-Port (primär)
* **Port 9091:** Milvus REST-API und Gesundheitsprüfung (intern)

**Umgebungsvariablen:**

```
NVIDIA_VISIBLE_DEVICES=all
NVIDIA_DRIVER_CAPABILITIES=compute,utility
```

***

## Schritt 3 — Mit Docker Compose einrichten

Melden Sie sich per SSH auf Ihrem Clore.ai-Server an und erstellen Sie die Compose-Datei:

```bash
ssh root@<server-ip> -p <ssh-port>

# Docker Compose installieren, falls nicht vorhanden
which docker-compose || pip install docker-compose
# Oder das Docker-Plugin verwenden:
docker compose version

# Projektverzeichnis erstellen
mkdir -p /opt/milvus && cd /opt/milvus

# Offizielle Milvus-Standalone-Compose-Datei herunterladen
wget https://github.com/milvus-io/milvus/releases/download/v2.4.0/milvus-standalone-docker-compose.yml \\
    -O docker-compose.yml

# Compose-Datei überprüfen
cat docker-compose.yml
```

### docker-compose.yml anpassen

```yaml
version: '3.5'

services:
  etcd:
    container_name: milvus-etcd
    image: quay.io/coreos/etcd:v3.5.5
    environment:
      - ETCD_AUTO_COMPACTION_MODE=revision
      - ETCD_AUTO_COMPACTION_RETENTION=1000
      - ETCD_QUOTA_BACKEND_BYTES=4294967296
      - ETCD_SNAPSHOT_COUNT=50000
    volumes:
      - /opt/milvus/etcd:/etcd
    command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
    healthcheck:
      test: ["CMD", "etcdctl", "endpoint", "health"]
      interval: 30s
      timeout: 20s
      retries: 3

  minio:
    container_name: milvus-minio
    image: minio/minio:RELEASE.2023-03-13T19-46-17Z
    environment:
      MINIO_ACCESS_KEY: minioadmin
      MINIO_SECRET_KEY: minioadmin
    ports:
      - "9001:9001"
      - "9000:9000"
    volumes:
      - /opt/milvus/minio:/minio_data
    command: minio server /minio_data --console-address ":9001"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 20s
      retries: 3

  standalone:
    container_name: milvus-standalone
    image: milvusdb/milvus:v2.4.0
    command: ["milvus", "run", "standalone"]
    security_opt:
      - seccomp:unconfined
    environment:
      ETCD_ENDPOINTS: etcd:2379
      MINIO_ADDRESS: minio:9000
    volumes:
      - /opt/milvus/milvus:/var/lib/milvus
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9091/healthz"]
      interval: 30s
      start_period: 90s
      timeout: 20s
      retries: 3
    ports:
      - "19530:19530"
      - "9091:9091"
    depends_on:
      - "etcd"
      - "minio"
    deploy:
      resources:
        reservations:
          devices:
            - capabilities: [gpu]  # GPU-Zugriff aktivieren
```

### Milvus starten

```bash
cd /opt/milvus
docker compose up -d

# Warten, bis die Dienste gestartet sind (~60 Sekunden)
sleep 60

# Prüfen, ob alle Dienste fehlerfrei laufen
docker compose ps

# Milvus-Gesundheitsstatus prüfen
curl http://localhost:9091/healthz
# Erwartet: {"status":"ok"}

# Logs anzeigen
docker compose logs -f standalone --tail 50
```

***

## Schritt 4 — Python-Client installieren

```bash
pip install pymilvus sentence-transformers numpy tqdm

# Verbindung überprüfen
python3 << 'EOF'
from pymilvus import connections, utility

connections.connect("default", host="localhost", port="19530")
print(f"Milvus verbunden!")
print(f"Version: {utility.get_server_version()}")
EOF
```

***

## Schritt 5 — Eine Collection erstellen

In Milvus ist eine **Collection** einer Datenbanktabelle ähnlich. Sie hat ein Schema mit typisierten Feldern, einschließlich Vektorfeldern.

```python
from pymilvus import (
    connections,
    FieldSchema,
    CollectionSchema,
    DataType,
    Collection,
    utility
)

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

# Schema definieren
fields = [
    FieldSchema(
        name="id",
        dtype=DataType.INT64,
        is_primary=True,
        auto_id=True           # IDs automatisch generieren
    ),
    FieldSchema(
        name="text",
        dtype=DataType.VARCHAR,
        max_length=2048        # Maximale Textlänge
    ),
    FieldSchema(
        name="source",
        dtype=DataType.VARCHAR,
        max_length=256
    ),
    FieldSchema(
        name="category",
        dtype=DataType.VARCHAR,
        max_length=128
    ),
    FieldSchema(
        name="year",
        dtype=DataType.INT32
    ),
    FieldSchema(
        name="embedding",
        dtype=DataType.FLOAT_VECTOR,
        dim=384                # Dimension Ihres Embedding-Modells
    )
]

schema = CollectionSchema(
    fields=fields,
    description="Dokumenten-Embeddings für die semantische Suche",
    enable_dynamic_field=True  # Das Hinzufügen von Feldern erlauben, die nicht im Schema enthalten sind
)

# Collection erstellen
collection_name = "documents"
if utility.has_collection(collection_name):
    utility.drop_collection(collection_name)

collection = Collection(
    name=collection_name,
    schema=schema,
    using="default"
)
print(f"Collection '{collection_name}' erstellt!")
```

***

## Schritt 6 — Index erstellen

Bevor Sie Daten für die Suche laden, erstellen Sie einen passenden Index:

```python
from pymilvus import Collection

collection = Collection("documents")

# HNSW-Index (für die meisten Anwendungsfälle am besten, geringe Latenz)
hnsw_params = {
    "metric_type": "COSINE",     # COSINE, L2 oder IP (Inner Product)
    "index_type": "HNSW",
    "params": {
        "M": 16,                 # HNSW-Graph-Konnektivität (8-64)
        "efConstruction": 200    # Suchtiefe während des Aufbaus
    }
}

# IVF_FLAT-Index (CPU, gut für große Collections)
ivf_params = {
    "metric_type": "COSINE",
    "index_type": "IVF_FLAT",
    "params": {
        "nlist": 1024            # Anzahl der Cluster (typischerweise die Quadratwurzel der Datengröße)
    }
}

# GPU_IVF_FLAT-Index (erfordert eine CUDA-GPU — am schnellsten für Batch-Abfragen)
gpu_ivf_params = {
    "metric_type": "L2",
    "index_type": "GPU_IVF_FLAT",
    "params": {
        "nlist": 1024,
        "cache_dataset_on_device": True
    }
}

# Index für das Embedding-Feld erstellen
collection.create_index(
    field_name="embedding",
    index_params=hnsw_params,
    index_name="embedding_idx"
)

# Skalarindex für gefilterte Suche erstellen
collection.create_index(field_name="category", index_name="category_idx")
collection.create_index(field_name="year", index_name="year_idx")

print("Indizes erstellt!")
collection.load()  # Für die Suche in den Speicher laden
```

***

## Schritt 7 — Daten einfügen

```python
from pymilvus import Collection
from sentence_transformers import SentenceTransformer
import tqdm

collection = Collection("documents")
model = SentenceTransformer("all-MiniLM-L6-v2", device="cuda")

# Ihre Dokumente
documents = [
    {
        "text": "Milvus ist eine Open-Source-Vektordatenbank für skalierbare KI-Anwendungen.",
        "source": "Dokumentation",
        "category": "Datenbank",
        "year": 2024
    },
    {
        "text": "HNSW bietet eine schnelle, approximative Suche nach den nächsten Nachbarn mit hoher Trefferquote.",
        "source": "Forschung",
        "category": "Algorithmus",
        "year": 2023
    },
    {
        "text": "GPU-beschleunigtes Indexing verkürzt die Aufbauzeit für große Vektor-Collections erheblich.",
        "source": "Blog",
        "category": "Performance",
        "year": 2024
    },
    # Fügen Sie hier Tausende weitere Dokumente hinzu
]

def insert_batch(docs: list, batch_size: int = 1000):
    texts = [d["text"] for d in docs]
    
    # GPU-beschleunigtes Embedding
    embeddings = model.encode(
        texts,
        batch_size=256,
        show_progress_bar=False,
        normalize_embeddings=True
    )
    
    # In Milvus einfügen
    data = {
        "text": [d["text"] for d in docs],
        "source": [d["source"] for d in docs],
        "category": [d["category"] for d in docs],
        "year": [d["year"] for d in docs],
        "embedding": embeddings.tolist()
    }
    
    result = collection.insert(data)
    return result.insert_count

# In Batches einfügen
BATCH_SIZE = 1000
total_inserted = 0

for i in range(0, len(documents), BATCH_SIZE):
    batch = documents[i:i + BATCH_SIZE]
    count = insert_batch(batch)
    total_inserted += count
    print(f"{total_inserted}/{len(documents)} Dokumente eingefügt")

# Flush ausführen, um sicherzustellen, dass die Daten persistiert und indiziert werden
collection.flush()
print(f"Insgesamt eingefügt und geflusht: {total_inserted}")
```

***

## Schritt 8 — Suchen und Abfragen

### Einfache semantische Suche

```python
from pymilvus import Collection
from sentence_transformers import SentenceTransformer

collection = Collection("documents")
collection.load()

model = SentenceTransformer("all-MiniLM-L6-v2", device="cuda")

def search(query: str, top_k: int = 10):
    query_embedding = model.encode(
        [query],
        normalize_embeddings=True
    )[0].tolist()
    
    results = collection.search(
        data=[query_embedding],
        anns_field="embedding",
        param={
            "metric_type": "COSINE",
            "params": {"ef": 64}    # HNSW-Parameter zur Suchzeit (ef >= top_k)
        },
        limit=top_k,
        output_fields=["text", "source", "category", "year"]
    )
    
    return results[0]

# Suchen
hits = search("wie funktioniert die Vektorsuche nach Ähnlichkeit")
for hit in hits:
    print(f"Punktzahl: {hit.score:.4f}")
    print(f"Text: {hit.entity.get('text')[:100]}")
    print(f"Quelle: {hit.entity.get('source')}")
    print()
```

### Gefilterte Suche

```python
from pymilvus import Collection

collection = Collection("documents")

# Suche mit Metadaten-Filter (boolescher Ausdruck)
results = collection.search(
    data=[query_embedding],
    anns_field="embedding",
    param={"metric_type": "COSINE", "params": {"ef": 64}},
    limit=10,
    expr='category == "Datenbank" and year >= 2023',  # Boolescher Filter
    output_fields=["text", "category", "year"]
)
```

### Hybride Suche (dicht + spärlich)

```python
# Milvus 2.4+ unterstützt hybride Dense+Sparse-Suche
from pymilvus import AnnSearchRequest, WeightedRanker, Collection

collection = Collection("documents")

# Anfrage für dichte Suche
dense_req = AnnSearchRequest(
    data=[dense_embedding],
    anns_field="embedding",
    param={"metric_type": "COSINE", "params": {"ef": 64}},
    limit=20
)

# Anfrage für spärliche Suche (erfordert ein Sparse-Vektor-Feld)
sparse_req = AnnSearchRequest(
    data=[sparse_embedding],
    anns_field="sparse_embedding",
    param={"metric_type": "IP"},
    limit=20
)

# Mit Reciprocal Rank Fusion kombinieren
results = collection.hybrid_search(
    [dense_req, sparse_req],
    rerank=WeightedRanker(0.7, 0.3),  # 70 % dicht, 30 % spärlich
    limit=10,
    output_fields=["text"]
)
```

***

## Schritt 9 — Einen RAG-Dienst aufbauen

```bash
pip install fastapi uvicorn openai

cat > /workspace/milvus_rag.py << 'EOF'
from fastapi import FastAPI
from pydantic import BaseModel
from pymilvus import Collection, connections
from sentence_transformers import SentenceTransformer
from openai import OpenAI
import os

app = FastAPI(title="Milvus RAG API")

# Beim Start initialisieren
connections.connect("default", host="localhost", port="19530")
collection = Collection("documents")
collection.load()
embedder = SentenceTransformer("all-MiniLM-L6-v2", device="cuda")
llm = OpenAI(api_key=os.environ["OPENAI_API_KEY"])

class QueryRequest(BaseModel):
    question: str
    n_results: int = 5

@app.get("/health")
async def health():
    return {"status": "ok", "vectors": collection.num_entities}

@app.post("/search")
async def semantic_search(req: QueryRequest):
    embedding = embedder.encode(
        [req.question],
        normalize_embeddings=True
    )[0].tolist()
    
    results = collection.search(
        data=[embedding],
        anns_field="embedding",
        param={"metric_type": "COSINE", "params": {"ef": 64}},
        limit=req.n_results,
        output_fields=["text", "source", "category"]
    )
    
    return {
        "results": [
            {
                "text": hit.entity.get("text"),
                "source": hit.entity.get("source"),
                "score": hit.score
            }
            for hit in results[0]
        ]
    }

@app.post("/rag")
async def rag(req: QueryRequest):
    embedding = embedder.encode([req.question], normalize_embeddings=True)[0].tolist()
    
    hits = collection.search(
        data=[embedding],
        anns_field="embedding",
        param={"metric_type": "COSINE", "params": {"ef": 64}},
        limit=req.n_results,
        output_fields=["text", "source"]
    )[0]
    
    context = "\n\n".join([
        f"[{hit.entity.get('source')}]: {hit.entity.get('text')}"
        for hit in hits if hit.score > 0.4
    ])
    
    response = llm.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": "Beantworte basierend auf dem Kontext. Sei prägnant."},
            {"role": "user", "content": f"Kontext:\n{context}\n\nFrage: {req.question}"}
        ]
    )
    
    return {"answer": response.choices[0].message.content, "context_used": len(hits)}

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)
EOF

python3 /workspace/milvus_rag.py
```

***

## Schritt 10 — Überwachen und Verwalten

```python
from pymilvus import connections, utility, Collection

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

# Alle Collections auflisten
print("Sammlungen:", utility.list_collections())

# Sammlungsstatistiken
col = Collection("documents")
print(f"Entitätsanzahl: {col.num_entities:,}")
print(f"Schema: {col.schema}")

# Partitionsverwaltung
col.create_partition("2024_docs")
col.create_partition("2023_docs")

# Mit Partition einfügen
col.insert(data, partition_name="2024_docs")

# Bestimmte Partition durchsuchen
results = col.search(
    data=[query_vec],
    anns_field="embedding",
    param={"metric_type": "COSINE", "params": {"ef": 64}},
    limit=10,
    partition_names=["2024_docs"]  # Nur diese Partition durchsuchen
)
```

***

## Fehlerbehebung

### Dienste starten nicht

```bash
# Container-Logs prüfen
docker compose logs etcd
docker compose logs minio
docker compose logs standalone

# Speicherplatz prüfen
df -h /opt/milvus

# Dienste neu starten
docker compose restart
```

### Verbindung auf 19530 verweigert

```bash
# Prüfen, ob Milvus lauscht
netstat -tlnp | grep 19530

# Gesundheitsstatus prüfen
curl http://localhost:9091/healthz

# Zeit für den Start einplanen (90 Sekunden)
docker compose logs standalone | tail -20
```

### Zeitüberschreitung beim Erstellen des Indexes für große Collections

```python
# Zeitüberschreitung für große Index-Erstellungen erhöhen
from pymilvus import Collection

collection = Collection("documents")
collection.create_index(
    field_name="embedding",
    index_params=hnsw_params,
    timeout=3600  # Zeitüberschreitung von 1 Stunde
)
```

### Hohe Speichernutzung

```bash
# Milvus-Speicherlimits in docker-compose.yml konfigurieren
# Zum Standalone-Service hinzufügen:
deploy:
  resources:
    limits:
      memory: 16g
```

***

## Leitfaden zur Auswahl des Indextyps

| Indextyp       | Am besten geeignet für        | Speicher             | Geschwindigkeit | GPU erforderlich |
| -------------- | ----------------------------- | -------------------- | --------------- | ---------------- |
| FLAT           | Klein (<1 Mio.), exakte Suche | Hoch                 | Langsam         | Nein             |
| IVF\_FLAT      | Mittel (1 Mio.–10 Mio.)       | Mittel               | Gut             | Nein             |
| HNSW           | Geringe Latenz, <100 Mio.     | Hoch                 | Hervorragend    | Nein             |
| IVF\_SQ8       | Komprimiert, groß             | Niedrig              | Gut             | Nein             |
| GPU\_IVF\_FLAT | Schnelle Batch-Abfragen       | GPU+RAM              | Am besten       | Ja               |
| DISKANN        | Im Milliardenmaßstab          | Niedrig (Festplatte) | Gut             | Nein             |

***

## Leistungsbenchmarks

| Collection-Größe  | Index          | GPU      | QPS      |
| ----------------- | -------------- | -------- | -------- |
| 1 Mio. Vektoren   | HNSW           | RTX 3090 | \~8,000  |
| 10 Mio. Vektoren  | IVF\_FLAT      | RTX 4090 | \~2,500  |
| 10 Mio. Vektoren  | GPU\_IVF\_FLAT | A100     | \~12,000 |
| 100 Mio. Vektoren | DISKANN        | A100     | \~1,200  |

***

## Zusätzliche Ressourcen

* [Milvus-Dokumentation](https://milvus.io/docs)
* [Milvus GitHub](https://github.com/milvus-io/milvus)
* [PyMilvus-Dokumentation](https://milvus.io/api-reference/pymilvus/v2.4.x/About.md)
* [Milvus Bootcamp](https://github.com/milvus-io/bootcamp) — Beispielanwendungen
* [Zilliz Cloud](https://cloud.zilliz.com/) — Verwaltetes Milvus
* [Vergleich von Vektordatenbanken](https://milvus.io/docs/benchmark.md)
* [Attu GUI](https://github.com/zilliztech/attu) — Web-Oberfläche zur Milvus-Verwaltung

***

*Milvus auf Clore.ai ist die ideale Lösung für KI-Anwendungen, die über Hunderte Millionen von Vektoren hinaus skalieren müssen. In Kombination mit GPU-beschleunigter Embedding-Generierung können Sie erstklassige semantische Such- und RAG-Systeme zu einem Bruchteil der Kosten verwalteter Cloud-Dienste aufbauen.*

***

## GPU-Empfehlungen für Clore.ai

| Anwendungsfall                | Empfohlene GPU   | Geschätzte Kosten bei Clore.ai |
| ----------------------------- | ---------------- | ------------------------------ |
| Entwicklung/Testen            | RTX 3090 (24 GB) | 0,07–0,21 $/GPU/Stunde         |
| Produktions-Vektorsuche       | RTX 3090 (24 GB) | 0,07–0,21 $/GPU/Stunde         |
| Embedding mit hohem Durchsatz | RTX 4090 (24 GB) | 0,14–0,42 $/GPU/Stunde         |

> 💡 Alle Beispiele in diesem Leitfaden können bereitgestellt werden auf [Clore.ai](https://clore.ai/marketplace) GPU-Servern. Durchsuchen Sie verfügbare GPUs und mieten Sie stundenweise — keine Verpflichtungen, voller Root-Zugriff.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.clore.ai/guides/guides_v2-de/rag-and-vektordatenbanken/milvus.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
