> 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-Vektor-Datenbank für KI-Anwendungen — entwickelt für Milliarden von Vektoren**

Milvus ist eine Open-Source-Vektor-Datenbank, die speziell für skalierbare Similarity-Suche und KI-Anwendungen entwickelt wurde. Ursprünglich von Zilliz erstellt und an die LF AI & Data Foundation gespendet, betreibt Milvus Produktions-KI-Workloads bei Unternehmen wie NVIDIA, AT\&T, IBM und Salesforce. Es ist die bevorzugte 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 welches wählen

| 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     | Sammlungsbasiert    |
| Streaming-Ingestion     | ✅ Kafka/Pulsar             | Begrenzt            |
| Hybride Suche           | ✅ Dicht + spärlich         | ✅                   |
| Cloudverwaltete 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 erforderlich sind.
{% endhint %}

***

## Milvus-Architektur

Milvus im Standalone-Modus (Einzelserver) umfasst:

* **milvus** — der Hauptdienst (Proxy-, Query-, Data-, Index-Koordinatoren)
* **etcd** — Metadatenspeicher und Service-Discovery
* **MinIO** — Objektspeicher für Segmentdaten

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

***

## Voraussetzungen

* Clore.ai-Konto mit GPU-Vermietung
* Docker Compose (in der Regel vorinstalliert)
* Grundkenntnisse in Python
* 16GB+ RAM (32GB für 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 32GB+ RAM für CPU-basiertes Indexing

**Mindestanforderungen:**

* CPU: 8 Kerne
* RAM: 16GB (32GB empfohlen)
* Festplatte: 50GB 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 Sammlungen erheblich. Wenn Sie planen, häufig 10M+ Vektoren zu indexieren, amortisiert sich GPU-Indexing schnell.
{% 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 Health-Check (intern)

**Umgebungsvariablen:**

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

***

## Schritt 3 — Einrichtung mit Docker Compose

SSH auf Ihren Clore.ai-Server und erstellen Sie die Compose-Datei:

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

# Installieren Sie Docker Compose, falls nicht vorhanden
which docker-compose || pip install docker-compose
# Oder verwenden Sie das Docker-Plugin:
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

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

### Passen Sie docker-compose.yml an

```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 Sie, bis die Dienste gestartet sind (~60 Sekunden)
sleep 60

# Prüfen Sie, ob alle Dienste gesund sind
docker compose ps

# Milvus-Health 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 verifizieren
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 — Erstelle eine Collection

In Milvus ist eine **Sammlung** ähnlich wie eine Datenbanktabelle. 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 semantische Suche",
    enable_dynamic_field=True  # Erlaubt das Hinzufügen von Feldern, die nicht im Schema 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"Sammlung '{collection_name}' erstellt!")
```

***

## Schritt 6 — Index erstellen

Erstellen Sie vor dem Laden der Daten für die Suche einen geeigneten Index:

```python
from pymilvus import Collection

collection = Collection("documents")

# HNSW-Index (am besten für die meisten Anwendungsfälle, 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    # Bauzeit-Suchtiefe
    }
}

# IVF_FLAT-Index (CPU, gut für große Sammlungen)
ivf_params = {
    "metric_type": "COSINE",
    "index_type": "IVF_FLAT",
    "params": {
        "nlist": 1024            # Anzahl der Cluster (Quadratwurzel der Datenmenge ist typisch)
    }
}

# GPU_IVF_FLAT-Index (erfordert 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 auf dem 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()  # In den Speicher laden, um zu suchen
```

***

## 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-Vektor-Datenbank für skalierbare KI-Anwendungen.",
        "source": "documentation",
        "category": "database",
        "year": 2024
    },
    {
        "text": "HNSW bietet schnelle approximative Nearest-Neighbor-Suche mit hoher Wiederfindungsrate.",
        "source": "research",
        "category": "algorithm",
        "year": 2023
    },
    {
        "text": "GPU-beschleunigtes Indexing reduziert die Aufbauzeit für große Vektorsammlungen drastisch.",
        "source": "blog",
        "category": "performance",
        "year": 2024
    },
    # Tausende weitere Dokumente hier hinzufügen
]

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 Chargen 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"Eingefügt {total_inserted}/{len(documents)} Dokumente")

# Flush, um sicherzustellen, dass Daten persistiert und indexiert sind
collection.flush()
print(f"Insgesamt eingefügt und geflusht: {total_inserted}")
```

***

## Schritt 8 — Suche und Abfragen

### Basis 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-Suchzeit-Parameter (ef >= top_k)
        },
        limit=top_k,
        output_fields=["text", "source", "category", "year"]
    )
    
    return results[0]

# Suche
hits = search("how does vector similarity search work")
for hit in hits:
    print(f"Score: {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 Metadatenfilter (boolescher Ausdruck)
results = collection.search(
    data=[query_embedding],
    anns_field="embedding",
    param={"metric_type": "COSINE", "params": {"ef": 64}},
    limit=10,
    expr='category == "database" and year >= 2023',  # Boolescher Filter
    output_fields=["text", "category", "year"]
)
```

### Hybride Suche (Dicht + Spärlich)

```python
# Milvus 2.4+ unterstützt hybride dicht+spärlich Suche
from pymilvus import AnnSearchRequest, WeightedRanker, Collection

collection = Collection("documents")

# Dichte Suchanfrage
dense_req = AnnSearchRequest(
    data=[dense_embedding],
    anns_field="embedding",
    param={"metric_type": "COSINE", "params": {"ef": 64}},
    limit=20
)

# Spärliche Suchanfrage (erfordert spärliches Vektorfeld)
sparse_req = AnnSearchRequest(
    data=[sparse_embedding],
    anns_field="sparse_embedding",
    param={"metric_type": "IP"},
    limit=20
)

# Kombination mit Reciprocal Rank Fusion
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-Service 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": "Antwort basierend auf dem Kontext. Seien Sie 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"Eintragsanzahl: {col.num_entities:,}")
print(f"Schema: {col.schema}")

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

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

# Spezifische 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
# Überprüfen Sie die Container-Logs
docker compose logs etcd
docker compose logs minio
docker compose logs standalone

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

# Dienste neu starten
docker compose restart
```

### Connection Refused auf 19530

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

# Prüfe Gesundheitszustand
curl http://localhost:9091/healthz

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

### Index-Bau-Timeout für große Sammlungen

```python
# Timeout für große Index-Builds erhöhen
from pymilvus import Collection

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

### Hoher Speicherverbrauch

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

***

## Leitfaden zur Auswahl des Index-Typs

| Index-Typ      | Am besten für             | Speicher             | Geschwindigkeit | GPU erforderlich |
| -------------- | ------------------------- | -------------------- | --------------- | ---------------- |
| FLAT           | Klein (<1M), exakte Suche | Hoch                 | Langsam         | Nein             |
| IVF\_FLAT      | Mittel (1M–10M)           | Mittel               | Gut             | Nein             |
| HNSW           | Geringe Latenz, <100M     | Hoch                 | Ausgezeichnet   | Nein             |
| IVF\_SQ8       | Komprimiert, groß         | Niedrig              | Gut             | Nein             |
| GPU\_IVF\_FLAT | Schnelle Batch-Abfragen   | GPU+RAM              | Beste           | Ja               |
| DISKANN        | Milliarden-Skala          | Niedrig (Festplatte) | Gut             | Nein             |

***

## Leistungs-Benchmarks

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

***

## Weitere 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
* [Vektor-Datenbank-Vergleich](https://milvus.io/docs/benchmark.md)
* [Attu GUI](https://github.com/zilliztech/attu) — Web-UI für Milvus-Verwaltung

***

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

***

## Clore.ai GPU-Empfehlungen

| Anwendungsfall                | Empfohlene GPU  | Geschätzte Kosten auf Clore.ai |
| ----------------------------- | --------------- | ------------------------------ |
| Entwicklung/Tests             | RTX 3090 (24GB) | \~$0.12/gpu/hr                 |
| Produktionsfähige Vektorsuche | RTX 3090 (24GB) | \~$0.12/gpu/hr                 |
| Hochdurchsatz-Embedding       | RTX 4090 (24GB) | \~$0.70/gpu/hr                 |

> 💡 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.
