Dernièrement, en configurant un système de recherche sémantique pour un client e-commerce, j'ai rencontré une erreur qui m'a fait perdre trois heures précieuses :

ConnectionError: [Errno 111] Connection refused
pymilvus.exceptions.MilvusException: 
Server not ready, resize failed. Server diagnostics: 
check milvus etcd: context deadline exceeded

Cette erreur de connexion à Milvus en production est plus fréquente qu'on ne le pense. Aujourd'hui, je vais vous guider à travers le déploiement complet de Milvus avec Docker Compose, en partageant les leçons apprises de mes propres erreurs et les meilleures pratiques pour éviter ces pièges.

Pourquoi Milvus pour la recherche vectorielle ?

Milvus est devenu le standard de l'industrie pour la recherche de similarité à grande échelle. Avec des latences inférieures à 50ms via HolySheep AI et des coûts réduits de 85% grâce au taux de change ¥1=$1, il est désormais accessible à tous les projets.

Prérequis système

Architecture du déploiement Milvus

Notre configuration utilise quatre composants essentiels : etcd pour la métadonnée, MinIO pour le stockage objet, Milvus Coordinator et Query Nodes pour le traitement des requêtes vectorielles.

# Structure du projet
milvus-deployment/
├── docker-compose.yml
├── .env
├── volumes/
│   ├── etcd/
│   ├── minio/
│   └── milvus/
└── scripts/
    └── init_collection.py

Configuration Docker Compose complète

# docker-compose.yml
version: '3.8'

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:
      - ./volumes/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
    networks:
      - milvus

  minio:
    container_name: milvus-minio
    image: minio/minio:RELEASE.2023-03-20T20-16-18Z
    environment:
      MINIO_ACCESS_KEY: minioadmin
      MINIO_SECRET_KEY: minioadmin
    ports:
      - "9001:9001"
      - "9000:9000"
    volumes:
      - ./volumes/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
    networks:
      - milvus

  milvus-standalone:
    container_name: milvus-standalone
    image: milvusdb/milvus:v2.3.3
    command: ["milvus", "run", "standalone"]
    environment:
      ETCD_ENDPOINTS: etcd:2379
      MINIO_ADDRESS: minio:9000
    volumes:
      - ./volumes/milvus:/var/lib/milvus
    ports:
      - "19530:19530"
      - "9091:9091"
    depends_on:
      - etcd
      - minio
    networks:
      - milvus

networks:
  milvus:
    driver: bridge
# .env
ETCD_VERSION=v3.5.5
MINIO_VERSION=RELEASE.2023-03-20T20-16-18Z
MILVUS_VERSION=v2.3.3
ETCD_PORT=2379
MILVUS_GRPC_PORT=19530
MILVUS_HTTP_PORT=9091
MINIO_API_PORT=9000
MINIO_CONSOLE_PORT=9001

Installation et démarrage

# Cloner le projet et démarrer
git clone https://github.com/milvus-io/milvus-helm.git
cd milvus-helm/charts/milvus-standalone

Démarrer avec Docker Compose

docker-compose up -d

Vérifier le statut

docker-compose ps

Consulter les logs

docker-compose logs -f milvus-standalone
# Script Python de test de connexion
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType

Connexion au serveur Milvus

HOST = "localhost" PORT = "19530" def connect_to_milvus(): try: print(f"Connexion à Milvus sur {HOST}:{PORT}...") connections.connect( alias="default", host=HOST, port=PORT, timeout=30 ) print("✅ Connexion réussie!") # Lister les collections existantes from pymilvus import list_collections collections = list_collections() print(f"Collections existantes: {collections}") return True except Exception as e: print(f"❌ Erreur de connexion: {e}") return False

Exemple d'intégration avec HolySheep AI pour embeddings

import openai openai.api_key = "YOUR_HOLYSHEEP_API_KEY" openai.api_base = "https://api.holysheep.ai/v1" def get_embedding(text: str): response = openai.Embedding.create( model="text-embedding-ada-002", input=text ) return response['data'][0]['embedding']

Test complet

if connect_to_milvus(): # Créer une collection de test fields = [ FieldSchema(name="id", dtype=DataType.INT64, is_primary=True), FieldSchema(name="embedding", dtype=DataType.FLOAT_VECTOR, dim=1536), FieldSchema(name="text", dtype=DataType.VARCHAR, max_length=65535) ] schema = CollectionSchema(fields=fields, description="Collection de test") collection = Collection(name="documents", schema=schema) print("✅ Collection créée avec succès!")

Test de la recherche vectorielle

# scripts/test_search.py
from pymilvus import connections, Collection, FieldSchema, CollectionSchema, DataType
from pymilvus import CollectionUtility
import numpy as np
import openai

Configuration HolySheep

openai.api_key = "YOUR_HOLYSHEEP_API_KEY" openai.api_base = "https://api.holysheep.ai/v1" def semantic_search(query: str, top_k: int = 5): """Recherche sémantique via Milvus + HolySheep embeddings""" # Obtenir l'embedding de la requête response = openai.Embedding.create( model="text-embedding-ada-002", input=query ) query_vector = response['data'][0]['embedding'] # Connexion à Milvus connections.connect(host='localhost', port='19530') collection = Collection("documents") collection.load() # Recherche ANN search_params = {"metric_type": "L2", "params": {"nprobe": 10}} results = collection