Skip to main content
NetApp Solutions
Se proporciona el idioma español mediante traducción automática para su comodidad. En caso de alguna inconsistencia, el inglés precede al español.

Configuración de clústeres de Milvus con Kubernetes en las instalaciones

Colaboradores

En esta sección se describe la configuración del cluster Milvus para la solución de base de datos vectorial para NetApp.

Configuración de clúster de Milvus con Kubernetes en las instalaciones

Los retos del cliente para escalar de manera independiente en el almacenamiento y la computación, así como en la gestión de datos y la gestión de la infraestructura eficaz.
Kubernetes y las bases de datos vectoriales forman una solución potente y escalable para gestionar grandes operaciones de datos. Kubernetes optimiza los recursos y gestiona los contenedores, mientras que las bases de datos vectoriales manejan de manera eficiente datos de alta dimensión y búsquedas de similitud. Esta combinación permite el procesamiento rápido de consultas complejas en conjuntos de datos de gran tamaño y se escala sin problemas con volúmenes de datos en crecimiento, lo que la hace ideal para las aplicaciones de Big Data y las cargas de trabajo de IA.

  1. En esta sección detallamos el proceso de instalación de un clúster Milvus en Kubernetes, utilizando una controladora de almacenamiento de NetApp tanto para los datos de clúster como para los de cliente.

  2. Para instalar un clúster Milvus, se requieren volúmenes persistentes (VP) para almacenar datos de varios componentes del clúster Milvus. Estos componentes incluyen etcd (tres instancias), pulsar-bookie-journal (tres instancias), pulsar-bookie-ledgers (tres instancias) y pulsar-zookeeper-data (tres instancias).

    Nota En milvus cluster, podemos usar pulsar o kafka para el motor subyacente que soporta el almacenamiento confiable del clúster Milvus y la publicación/suscripción de flujos de mensajes. En el caso de Kafka con NFS, NetApp ha realizado mejoras en ONTAP 9.12.1 y versiones posteriores. Además, estas mejoras, junto con los cambios NFSv4,1 y Linux que se incluyen en RHEL 8,7 o 9,1 y posteriores, solucionan el problema «nombre tonto» que puede producirse al ejecutar Kafka a través de NFS. Si desea obtener información más detallada sobre el tema de ejecutar kafka con solución NFS de NetApp, consulte - "este enlace".
  3. Creamos un único volumen NFS en NetApp ONTAP y establecimos 12 volúmenes persistentes, cada uno con 250GB TB de almacenamiento. El tamaño del almacenamiento puede variar dependiendo del tamaño del clúster; por ejemplo, tenemos otro clúster en el que cada VP tiene 50GB TB. Por favor refiérase a continuación a uno de los archivos PV YAML para más detalles; teníamos 12 archivos de este tipo en total. En cada archivo, el storageClassName se establece en 'almacén', y el almacenamiento y la ruta de acceso son únicos para cada VP.

    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. Ejecute el comando 'kubectl apply' para cada archivo PV YAML para crear los volúmenes persistentes, y luego verifique su creación usando '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. Para almacenar datos de clientes, Milvus admite soluciones de almacenamiento de objetos como MinIO, Azure Blob y S3. En esta guía, utilizamos S3. Los siguientes pasos se aplican tanto al almacén de objetos de ONTAP S3 como a StorageGRID. Utilizamos Helm para desplegar el cluster Milvus. Descargue el archivo de configuración VALUES.yaml desde la ubicación de descarga de Milvus. Consulte el apéndice del archivo VALUES.yaml que utilizamos en este documento.

  6. Asegúrese de que 'torageClass' está establecido en 'default' en cada sección, incluidos los correspondientes al log, el ETCD, el zookeeper y el contador.

  7. En la sección MinIO, desactive MinIO.

  8. Cree un bloque NAS a partir del almacenamiento de objetos ONTAP o StorageGRID e inclúyalos en un S3 externo con las credenciales de almacenamiento de objetos.

    ###################################
    # 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. Antes de crear el clúster de Milvus, asegúrese de que PersistentVolumeClaim (RVP) no tenga recursos preexistentes.

    root@node2:~# kubectl get pvc
    No resources found in default namespace.
    root@node2:~#
  10. Utilice Helm y el archivo de configuración values.yaml para instalar e iniciar el clúster 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. Compruebe el estado de las reclamaciones de volúmenes persistentes (RVP).

    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. Compruebe el estado de los pods.

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

    Asegúrese de que el estado de PODS es 'en ejecución' y funciona según lo esperado

  13. Prueba de escritura y lectura de datos en el almacenamiento de objetos Milvus y NetApp.

    • Escriba datos con el programa 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:~#
    • Lea los datos con el archivo 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}}]}

      Basada en la validación anterior, la integración de Kubernetes con una base de datos vectorial, como se demuestra mediante la puesta en marcha de un clúster Milvus en Kubernetes mediante una controladora de almacenamiento de NetApp, ofrece a los clientes una solución sólida, escalable y eficiente para la gestión de operaciones de datos a gran escala. Esta configuración proporciona a los clientes la capacidad de manejar datos de alta dimensión y ejecutar consultas complejas de forma rápida y eficiente, lo que la convierte en una solución ideal para las aplicaciones de Big Data y las cargas de trabajo de IA. El uso de volúmenes persistentes (VP) para varios componentes del cluster, junto con la creación de un único volumen NFS desde NetApp ONTAP, garantiza una utilización óptima de los recursos y una gestión de datos. El proceso de verificación del estado de PersistentVolumeClaims (RVP) y Pods, así como la realización de pruebas de escritura y lectura de datos, proporciona a los clientes la garantía de realizar operaciones de datos fiables y coherentes. El uso del almacenamiento de objetos de ONTAP o StorageGRID para los datos de clientes mejora aún más la accesibilidad de los datos y la seguridad. En general, esta configuración ofrece a los clientes una solución de gestión de datos resiliente y de alto rendimiento que puede escalarse sin problemas a medida que vayan aumentando sus necesidades relacionadas con datos.