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

Setup cluster Milvus con Kubernetes on-premise

Collaboratori

In questa sezione viene descritta la configurazione del cluster milvus per la soluzione di database vettoriale per NetApp.

Setup del cluster Milvus con Kubernetes on-premise

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

  1. In questa sezione, descriviamo in dettaglio il processo di installazione di un cluster Milvus su Kubernetes, che utilizza uno storage controller NetApp sia per i dati del cluster sia per i dati del cliente.

  2. Per installare un cluster Milvus, sono necessari volumi persistenti (PVS) per memorizzare i dati di 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 In milvus cluster, possiamo utilizzare sia Pulsar o kafka per il motore sottostante che supporta la memorizzazione affidabile del cluster Milvus e la pubblicazione/sottoscrizione di flussi di messaggi. Per Kafka con NFS, NetApp ha apportato miglioramenti in ONTAP 9.12.1 e versioni successive. Tali miglioramenti, insieme alle modifiche a NFSv4,1 e Linux incluse in RHEL 8,7 o 9,1 e versioni successive, risolvono il problema del "ridenominazione semplice" che si verifica quando si esegue Kafka su NFS. Se siete interessati a informazioni più approfondite sull'argomento dell'esecuzione di kafka con la soluzione NFS NetApp, consultate - "questo link".
  3. Abbiamo creato un singolo volume NFS di NetApp ONTAP e abbiamo stabilito 12 volumi persistenti con 250GB TB di storage, ciascuno. Le dimensioni dello storage possono variare in base alle dimensioni del cluster, ad esempio disponiamo di un altro cluster in cui ogni PV ha 50GB TB. Per ulteriori dettagli, fare riferimento a uno dei file YAML PV riportati di seguito; in totale, sono disponibili 12 file. In ogni file, storageClassName è impostato su 'default', e l'archiviazione 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 storage a oggetti come MinIO, BLOB di Azure e S3. In questa guida, utilizziamo S3. I seguenti passaggi si applicano sia a ONTAP S3 che all'archivio oggetti StorageGRID. Utilizziamo Helm per implementare il cluster Milvus. Scaricare il file di configurazione, Values.yaml, dal percorso di download di Milvus. Fare riferimento all'appendice per il file Values.yaml utilizzato in questo documento.

  6. Assicurarsi che la 'torageClass' sia impostata su 'default' in ogni sezione, compresi quelli per il log, etcd, zoookeeper e bookkeeper.

  7. Nella sezione MinIO, disabilitare MinIO.

  8. Creare un bucket NAS dallo storage a oggetti ONTAP o StorageGRID e includerli in un S3 esterno con le credenziali di storage a 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 il PVC (PersistentVolumeClaim) 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 delle richieste di verifica del volume di persistenza (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 pod.

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

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

  13. Testare la scrittura e la lettura dei dati nello storage a oggetti Milvus e 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}}]}

      In base alla validazione sopra indicata, l'integrazione di Kubernetes con un database vettoriale, come dimostrata tramite l'implementazione di un cluster Milvus su Kubernetes che utilizza uno storage controller NetApp, offre ai clienti una soluzione solida, scalabile ed efficiente per gestire operazioni su dati su larga scala. Questo setup offre ai clienti la capacità di gestire dati ad alta dimensione ed eseguire query complesse in modo rapido ed efficiente, rendendolo la soluzione ideale per applicazioni big data e workload ai. L'utilizzo dei 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 di PersistentVolumeClaims (PVCS) e POD, nonché di verifica della scrittura e della lettura dei dati, fornisce ai clienti la garanzia di operazioni di dati affidabili e coerenti. L'utilizzo dello storage a oggetti ONTAP o StorageGRID per i dati dei clienti migliora ulteriormente l'accessibilità e la sicurezza dei dati. Nel complesso, questo setup offre ai clienti una soluzione per la gestione dei dati resiliente e ad alte performance, in grado di scalare perfettamente con le crescenti esigenze in termini di dati.