Configuration de clusters Milvus avec Kubernetes sur site
Cette section traite de la configuration de cluster milvus pour la solution de base de données vectorielle pour NetApp.
Configuration de clusters Milvus avec Kubernetes sur site
Challenges des clients : faire évoluer leurs ressources de stockage et de calcul de manière indépendante, gérer efficacement l'infrastructure et gérer les données
Ensemble, Kubernetes et les bases de données vectorielles forment une solution puissante et évolutive pour la gestion des opérations de données volumineuses. Kubernetes optimise les ressources et gère les conteneurs, tandis que les bases de données vectorielles gèrent efficacement les recherches de similarités et de données de grande taille. Cette combinaison permet de traiter rapidement les requêtes complexes sur des datasets volumineux et d'évoluer de manière transparente avec des volumes de données croissants, ce qui en fait la solution idéale pour les applications Big Data et les charges de travail d'IA.
-
Dans cette section, nous détaillons le processus d'installation d'un cluster Milvus sur Kubernetes avec un contrôleur de stockage NetApp pour les données de cluster et les données client.
-
Pour installer un cluster Milvus, des volumes persistants (PVS) sont nécessaires au stockage des données issues de divers composants du cluster Milvus. Ces composants comprennent les données etcd (trois instances), pulsar-bookie-journal (trois instances), pulsar-bookie-ledgers (trois instances) et pulsar-zookeeper-data (trois instances).
Dans le cluster milvus, nous pouvons utiliser pulsar ou kafka pour le moteur sous-jacent prenant en charge le stockage fiable du cluster Milvus et la publication/l'abonnement des flux de messages. Pour Kafka avec NFS, NetApp a apporté des améliorations à ONTAP 9.12.1 et versions ultérieures. Ces améliorations, ainsi que les modifications NFSv4.1 et Linux incluses dans RHEL 8.7 ou 9.1 et versions ultérieures, résolvent le problème de « changement de nom silly » qui peut survenir lors de l'exécution de Kafka avec NFS. Si vous souhaitez obtenir des informations plus détaillées sur l'exécution de kafka avec la solution NFS NetApp, veuillez consulter - "ce lien". -
Nous avons créé un volume NFS unique à partir de NetApp ONTAP et établi 12 volumes persistants, chacun avec 250 Go de stockage. La taille du stockage peut varier en fonction de la taille du cluster. Par exemple, nous disposons d'un autre cluster où chaque volume persistant dispose de 50 Go. Veuillez vous reporter à l'un des fichiers PV YAML pour plus de détails ; nous avions 12 fichiers de ce type au total. Dans chaque fichier, le nom de classe de stockage est défini sur « par défaut », et le stockage et le chemin sont uniques à chaque 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:~#
-
Exécutez la commande 'kubectl Apply' pour chaque fichier YAML PV pour créer les volumes persistants, puis vérifiez leur création à l'aide de '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:~#
-
Milvus prend en charge les solutions de stockage objet telles que MiniO, Azure Blob et S3 pour le stockage des données des clients. Dans ce guide, nous utilisons S3. Les étapes suivantes s'appliquent aux magasins d'objets ONTAP S3 et StorageGRID. Nous utilisons Helm pour déployer le cluster Milvus. Téléchargez le fichier de configuration, Values.yaml, à partir de l'emplacement de téléchargement Milvus. Veuillez vous reporter à l'annexe pour le fichier values.yaml que nous avons utilisé dans ce document.
-
Assurez-vous que la 'StorageClass' est définie sur 'par défaut' dans chaque section, y compris celles du journal, de l'ETCD, du zookeeper et du bookkeeper.
-
Dans la section MiniO, désactivez MiniO.
-
Créez un compartiment NAS à partir d'un stockage objet ONTAP ou StorageGRID et ajoutez-les dans un S3 externe avec les identifiants du stockage objet.
################################### # 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
-
Avant de créer le cluster Milvus, assurez-vous que la demande de volume persistant ne dispose pas de ressources préexistantes.
root@node2:~# kubectl get pvc No resources found in default namespace. root@node2:~#
-
Utilisez Helm et le fichier de configuration Values.yaml pour installer et démarrer le 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:~#
-
Vérifiez l'état des demandes de volume persistant.
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:~#
-
Vérifier l'état des 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>
Assurez-vous que l'état des modules est « en cours d'exécution » et qu'ils fonctionnent comme prévu
-
Testez l'écriture et la lecture de données dans Milvus et le stockage objet NetApp.
-
Écrivez les données à l'aide du programme 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:~#
-
Lisez les données à l'aide du fichier 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}}]}
Sur la base de la validation ci-dessus, l'intégration de Kubernetes avec une base de données vectorielle, comme l'illustre le déploiement d'un cluster Milvus sur Kubernetes à l'aide d'un contrôleur de stockage NetApp, offre aux clients une solution robuste, évolutive et efficace pour la gestion des opérations de données à grande échelle. Cette configuration permet aux clients de gérer des données à dimension élevée et d'exécuter des requêtes complexes de manière rapide et efficace. Elle constitue ainsi la solution idéale pour les applications Big Data et les workloads d'IA. L'utilisation des volumes persistants (PVS) pour divers composants du cluster, ainsi que la création d'un volume NFS unique à partir de NetApp ONTAP, assurent une utilisation optimale des ressources et une gestion optimale des données. Le processus consistant à vérifier l'état des demandes de volume persistant et des pods, ainsi qu'à tester l'écriture et la lecture des données, garantit la fiabilité et la cohérence des opérations de données. L'utilisation du stockage objet ONTAP ou StorageGRID pour les données des clients renforce encore l'accessibilité et la sécurité des données. Cette configuration offre une solution de gestion des données résiliente et haute performance qui peut évoluer de manière transparente en fonction de l'évolution de vos besoins en termes de données.
-