Skip to main content
NetApp artificial intelligence solutions
La versione in lingua italiana fornita proviene da una traduzione automatica. Per eventuali incoerenze, fare riferimento alla versione in lingua inglese.

Configurazione del cluster Milvus con Kubernetes in locale

Questa sezione illustra la configurazione del cluster Milvus per la soluzione di database vettoriale per NetApp.

Configurazione del cluster Milvus con Kubernetes in locale

Le sfide dei clienti per scalare in modo indipendente su storage e calcolo, una gestione efficace dell'infrastruttura e la gestione dei dati, Kubernetes e i database vettoriali insieme formano una soluzione potente e scalabile per la gestione di operazioni su grandi quantità di dati. Kubernetes ottimizza le risorse e gestisce i container, mentre i database vettoriali gestiscono in modo efficiente i dati ad alta dimensionalità e le ricerche di similarità. Questa combinazione consente l'elaborazione rapida di query complesse su grandi set di dati e si adatta perfettamente ai crescenti volumi di dati, rendendola ideale per applicazioni big data e carichi di lavoro di intelligenza artificiale.

  1. In questa sezione, descriviamo in dettaglio il processo di installazione di un cluster Milvus su Kubernetes, utilizzando un controller di archiviazione NetApp sia per i dati del cluster che per i dati dei clienti.

  2. Per installare un cluster Milvus, sono necessari volumi persistenti (PV) per archiviare i dati provenienti da vari componenti del cluster Milvus. Questi componenti includono etcd (tre istanze), pulsar-bookie-journal (tre istanze), pulsar-bookie-ledgers (tre istanze) e pulsar-zookeeper-data (tre istanze).

    Nota Nel cluster Milvus, possiamo utilizzare sia Pulsar che Kafka come motore sottostante che supporta l'archiviazione affidabile e la pubblicazione/sottoscrizione dei flussi di messaggi del cluster Milvus. Per Kafka con NFS, NetApp ha apportato miglioramenti in ONTAP 9.12.1 e versioni successive, e questi miglioramenti, insieme alle modifiche di NFSv4.1 e Linux incluse in RHEL 8.7 o 9.1 e versioni successive, risolvono il problema della "rinomina stupida" che può verificarsi quando si esegue Kafka su NFS. Se sei interessato a informazioni più approfondite sull'esecuzione di Kafka con la soluzione NetApp NFS, consulta:"questo collegamento" .
  3. Abbiamo creato un singolo volume NFS da NetApp ONTAP e stabilito 12 volumi persistenti, ciascuno con 250 GB di storage. La dimensione dello storage può variare a seconda delle dimensioni del cluster; ad esempio, abbiamo un altro cluster in cui ogni PV ha 50 GB. Per maggiori dettagli fare riferimento a uno dei file PV YAML qui sotto; in totale avevamo 12 file di questo tipo. In ogni file, storageClassName è impostato su "default" e lo storage e il percorso sono univoci per ogni PV.

    root@node2:~# cat sai_nfs_to_default_pv1.yaml
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: karthik-pv1
    spec:
      capacity:
        storage: 250Gi
      volumeMode: Filesystem
      accessModes:
      - ReadWriteOnce
      persistentVolumeReclaimPolicy: Retain
      storageClassName: default
      local:
        path: /vectordbsc/milvus/milvus1
      nodeAffinity:
        required:
          nodeSelectorTerms:
          - matchExpressions:
            - key: kubernetes.io/hostname
              operator: In
              values:
              - node2
              - node3
              - node4
              - node5
              - node6
    root@node2:~#
  4. Eseguire il comando 'kubectl apply' per ogni file YAML PV per creare i volumi persistenti, quindi verificare la loro creazione utilizzando 'kubectl get pv'

    root@node2:~# for i in $( seq 1 12 ); do kubectl apply -f sai_nfs_to_default_pv$i.yaml; done
    persistentvolume/karthik-pv1 created
    persistentvolume/karthik-pv2 created
    persistentvolume/karthik-pv3 created
    persistentvolume/karthik-pv4 created
    persistentvolume/karthik-pv5 created
    persistentvolume/karthik-pv6 created
    persistentvolume/karthik-pv7 created
    persistentvolume/karthik-pv8 created
    persistentvolume/karthik-pv9 created
    persistentvolume/karthik-pv10 created
    persistentvolume/karthik-pv11 created
    persistentvolume/karthik-pv12 created
    root@node2:~#
  5. Per l'archiviazione dei dati dei clienti, Milvus supporta soluzioni di archiviazione di oggetti come MinIO, Azure Blob e S3. In questa guida utilizziamo S3. I passaggi seguenti si applicano sia all'archivio oggetti ONTAP S3 che a StorageGRID . Utilizziamo Helm per distribuire il cluster Milvus. Scarica il file di configurazione, values.yaml, dalla posizione di download di Milvus. Fare riferimento all'appendice per il file values.yaml utilizzato in questo documento.

  6. Assicurarsi che 'storageClass' sia impostato su 'default' in ogni sezione, comprese quelle per log, etcd, zookeeper e bookkeeper.

  7. Nella sezione MinIO, disabilitare MinIO.

  8. Creare un bucket NAS dall'archiviazione di oggetti ONTAP o StorageGRID e includerli in un S3 esterno con le credenziali dell'archiviazione di oggetti.

    ###################################
    # External S3
    # - these configs are only used when `externalS3.enabled` is true
    ###################################
    externalS3:
      enabled: true
      host: "192.168.150.167"
      port: "80"
      accessKey: "24G4C1316APP2BIPDE5S"
      secretKey: "Zd28p43rgZaU44PX_ftT279z9nt4jBSro97j87Bx"
      useSSL: false
      bucketName: "milvusdbvol1"
      rootPath: ""
      useIAM: false
      cloudProvider: "aws"
      iamEndpoint: ""
      region: ""
      useVirtualHost: false
  9. Prima di creare il cluster Milvus, assicurarsi che PersistentVolumeClaim (PVC) non disponga di risorse preesistenti.

    root@node2:~# kubectl get pvc
    No resources found in default namespace.
    root@node2:~#
  10. Utilizzare Helm e il file di configurazione values.yaml per installare e avviare il cluster Milvus.

    root@node2:~# helm upgrade --install my-release milvus/milvus --set global.storageClass=default  -f values.yaml
    Release "my-release" does not exist. Installing it now.
    NAME: my-release
    LAST DEPLOYED: Thu Mar 14 15:00:07 2024
    NAMESPACE: default
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    root@node2:~#
  11. Verificare lo stato dei PersistentVolumeClaims (PVC).

    root@node2:~# kubectl get pvc
    NAME                                                             STATUS   VOLUME         CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    data-my-release-etcd-0                                           Bound    karthik-pv8    250Gi      RWO            default        3s
    data-my-release-etcd-1                                           Bound    karthik-pv5    250Gi      RWO            default        2s
    data-my-release-etcd-2                                           Bound    karthik-pv4    250Gi      RWO            default        3s
    my-release-pulsar-bookie-journal-my-release-pulsar-bookie-0      Bound    karthik-pv10   250Gi      RWO            default        3s
    my-release-pulsar-bookie-journal-my-release-pulsar-bookie-1      Bound    karthik-pv3    250Gi      RWO            default        3s
    my-release-pulsar-bookie-journal-my-release-pulsar-bookie-2      Bound    karthik-pv1    250Gi      RWO            default        3s
    my-release-pulsar-bookie-ledgers-my-release-pulsar-bookie-0      Bound    karthik-pv2    250Gi      RWO            default        3s
    my-release-pulsar-bookie-ledgers-my-release-pulsar-bookie-1      Bound    karthik-pv9    250Gi      RWO            default        3s
    my-release-pulsar-bookie-ledgers-my-release-pulsar-bookie-2      Bound    karthik-pv11   250Gi      RWO            default        3s
    my-release-pulsar-zookeeper-data-my-release-pulsar-zookeeper-0   Bound    karthik-pv7    250Gi      RWO            default        3s
    root@node2:~#
  12. Controllare lo stato dei baccelli.

    root@node2:~# kubectl get pods -o wide
    NAME                                            READY   STATUS      RESTARTS        AGE    IP              NODE    NOMINATED NODE   READINESS GATES
    <content removed to save page space>

    Assicurati che lo stato dei pod sia "in esecuzione" e funzioni come previsto

  13. Scrittura e lettura dei dati di prova in Milvus e nell'archiviazione di oggetti NetApp .

    • Scrivere i dati utilizzando il programma Python "prepare_data_netapp_new.py".

      root@node2:~# date;python3 prepare_data_netapp_new.py ;date
      Thu Apr  4 04:15:35 PM UTC 2024
      === start connecting to Milvus     ===
      === Milvus host: localhost         ===
      Does collection hello_milvus_ntapnew_update2_sc exist in Milvus: False
      === Drop collection - hello_milvus_ntapnew_update2_sc ===
      === Drop collection - hello_milvus_ntapnew_update2_sc2 ===
      === Create collection `hello_milvus_ntapnew_update2_sc` ===
      === Start inserting entities       ===
      Number of entities in hello_milvus_ntapnew_update2_sc: 3000
      Thu Apr  4 04:18:01 PM UTC 2024
      root@node2:~#
    • Leggere i dati utilizzando il file Python "verify_data_netapp.py".

      root@node2:~# python3 verify_data_netapp.py
      === start connecting to Milvus     ===
      === Milvus host: localhost         ===
      
      Does collection hello_milvus_ntapnew_update2_sc exist in Milvus: True
      {'auto_id': False, 'description': 'hello_milvus_ntapnew_update2_sc', 'fields': [{'name': 'pk', 'description': '', 'type': <DataType.INT64: 5>, 'is_primary': True, 'auto_id': False}, {'name': 'random', 'description': '', 'type': <DataType.DOUBLE: 11>}, {'name': 'var', 'description': '', 'type': <DataType.VARCHAR: 21>, 'params': {'max_length': 65535}}, {'name': 'embeddings', 'description': '', 'type': <DataType.FLOAT_VECTOR: 101>, 'params': {'dim': 16}}]}
      Number of entities in Milvus: hello_milvus_ntapnew_update2_sc : 3000
      
      === Start Creating index IVF_FLAT  ===
      
      === Start loading                  ===
      
      === Start searching based on vector similarity ===
      
      hit: id: 2998, distance: 0.0, entity: {'random': 0.9728033590489911}, random field: 0.9728033590489911
      hit: id: 2600, distance: 0.602496862411499, entity: {'random': 0.3098157043984633}, random field: 0.3098157043984633
      hit: id: 1831, distance: 0.6797959804534912, entity: {'random': 0.6331477114129169}, random field: 0.6331477114129169
      hit: id: 2999, distance: 0.0, entity: {'random': 0.02316334456872482}, random field: 0.02316334456872482
      hit: id: 2524, distance: 0.5918987989425659, entity: {'random': 0.285283165889066}, random field: 0.285283165889066
      hit: id: 264, distance: 0.7254047393798828, entity: {'random': 0.3329096143562196}, random field: 0.3329096143562196
      search latency = 0.4533s
      
      === Start querying with `random > 0.5` ===
      
      query result:
      -{'random': 0.6378742006852851, 'embeddings': [0.20963514, 0.39746657, 0.12019053, 0.6947492, 0.9535575, 0.5454552, 0.82360446, 0.21096309, 0.52323616, 0.8035404, 0.77824664, 0.80369574, 0.4914803, 0.8265614, 0.6145269, 0.80234545], 'pk': 0}
      search latency = 0.4476s
      
      === Start hybrid searching with `random > 0.5` ===
      
      hit: id: 2998, distance: 0.0, entity: {'random': 0.9728033590489911}, random field: 0.9728033590489911
      hit: id: 1831, distance: 0.6797959804534912, entity: {'random': 0.6331477114129169}, random field: 0.6331477114129169
      hit: id: 678, distance: 0.7351570129394531, entity: {'random': 0.5195484662306603}, random field: 0.5195484662306603
      hit: id: 2644, distance: 0.8620758056640625, entity: {'random': 0.9785952878381153}, random field: 0.9785952878381153
      hit: id: 1960, distance: 0.9083120226860046, entity: {'random': 0.6376039340439571}, random field: 0.6376039340439571
      hit: id: 106, distance: 0.9792704582214355, entity: {'random': 0.9679994241326673}, random field: 0.9679994241326673
      search latency = 0.1232s
      Does collection hello_milvus_ntapnew_update2_sc2 exist in Milvus: True
      {'auto_id': True, 'description': 'hello_milvus_ntapnew_update2_sc2', 'fields': [{'name': 'pk', 'description': '', 'type': <DataType.INT64: 5>, 'is_primary': True, 'auto_id': True}, {'name': 'random', 'description': '', 'type': <DataType.DOUBLE: 11>}, {'name': 'var', 'description': '', 'type': <DataType.VARCHAR: 21>, 'params': {'max_length': 65535}}, {'name': 'embeddings', 'description': '', 'type': <DataType.FLOAT_VECTOR: 101>, 'params': {'dim': 16}}]}

      Sulla base della convalida di cui sopra, l'integrazione di Kubernetes con un database vettoriale, come dimostrato attraverso l'implementazione di un cluster Milvus su Kubernetes utilizzando un controller di storage NetApp , offre ai clienti una soluzione solida, scalabile ed efficiente per la gestione di operazioni sui dati su larga scala. Questa configurazione offre ai clienti la possibilità di gestire dati ad alta dimensionalità ed eseguire query complesse in modo rapido ed efficiente, rendendola una soluzione ideale per applicazioni big data e carichi di lavoro di intelligenza artificiale. L'utilizzo di volumi persistenti (PV) per vari componenti del cluster, insieme alla creazione di un singolo volume NFS da NetApp ONTAP, garantisce un utilizzo ottimale delle risorse e una gestione dei dati. Il processo di verifica dello stato dei PersistentVolumeClaim (PVC) e dei pod, nonché il test di scrittura e lettura dei dati, garantiscono ai clienti operazioni sui dati affidabili e coerenti. L'utilizzo dell'archiviazione di oggetti ONTAP o StorageGRID per i dati dei clienti migliora ulteriormente l'accessibilità e la sicurezza dei dati. Nel complesso, questa configurazione fornisce ai clienti una soluzione di gestione dei dati resiliente e ad alte prestazioni, in grado di adattarsi senza problemi alle crescenti esigenze di dati.