Présentation du stockage hiérarchiséCompatible with Milvus 2.6.4+

Dans Milvus, le mode traditionnel de chargement complet exige que chaque QueryNode charge tous les champs de données et index d'un segment lors de l'initialisation, même les données auxquelles on n'accèdera peut-être jamais. Cela garantit une disponibilité immédiate des données, mais entraîne souvent un gaspillage des ressources, notamment une utilisation élevée de la mémoire, une forte activité du disque et des frais généraux d'E/S importants, en particulier lors du traitement d'ensembles de données volumineux.

Lestockage hiérarchisé relève ce défi en découplant la mise en cache des données du chargement des segments. Au lieu de charger toutes les données en une seule fois, le QueryNode ne charge plus que des métadonnées légères au départ et extrait ou expulse dynamiquement les données de terrain à la demande. Cela réduit considérablement le temps de chargement, optimise l'utilisation des ressources locales et permet aux QueryNodes de traiter des ensembles de données qui dépassent de loin leur mémoire physique ou la capacité de leur disque.

Envisagez d'activer le stockage hiérarchisé dans des scénarios tels que :

  • Collections qui dépassent la mémoire disponible ou la capacité NVMe d'un seul QueryNode

  • Charges de travail analytiques ou par lots pour lesquelles un chargement plus rapide est plus important que la latence de la première requête.

  • Charges de travail mixtes qui peuvent tolérer des manques occasionnels de cache pour les données moins fréquemment consultées.

  • Lesmétadonnées comprennent les schémas, les définitions d'index, les cartes de blocs, le nombre de lignes et les références à des objets distants. Ce type de données est de petite taille, toujours mis en cache et jamais expulsé.

  • Pour plus de détails sur les segments et les morceaux, voir Segment.

Fonctionnement

Le stockage hiérarchisé modifie la façon dont QueryNode gère les données de segment. Au lieu de mettre en cache chaque champ et index au moment du chargement, QueryNode ne charge plus que les métadonnées et utilise une couche de mise en cache pour récupérer et expulser les données de manière dynamique.

Mode de chargement complet et mode de stockage hiérarchisé

Bien que les modes Full-load et Tiered Storage traitent les mêmes données, ils diffèrent quant au moment et à la manière dont QueryNode met en cache ces composants.

  • Mode pleine charge: Au moment du chargement, QueryNode met en cache les données de la collection complète, y compris les métadonnées, les données de champ et les index, à partir du stockage d'objets.

  • Mode de stockage hiérarchisé: Au moment du chargement, QueryNode met en cache uniquement les métadonnées. Les données de champ sont extraites à la demande, à la granularité des morceaux. Les fichiers d'index restent distants jusqu'à ce que la première requête en ait besoin ; ensuite, l'index complet par segment est extrait et mis en cache.

Le diagramme ci-dessous illustre ces différences.

Full Load Mode Vs Tiered Storage Mode Mode pleine charge et mode de stockage hiérarchisé

Flux de chargement des QueryNodes

Dans le cadre du stockage hiérarchisé, le flux de travail du stockage hiérarchisé comporte les phases suivantes :

Querynode Load Workflow Flux de travail de chargement des nœuds de requête

Phase 1 : Chargement paresseux

Lors de l'initialisation, Milvus effectue un chargement paresseux, mettant en cache uniquement les métadonnées au niveau du segment, telles que les définitions de schéma, les informations d'index et les mappages de morceaux.

Aucune donnée de champ ou fichier d'index n'est mis en cache à ce stade. Cela permet aux collections d'être interrogeables presque immédiatement après le démarrage, tout en conservant une consommation minimale de mémoire et de disque.

Comme les données des champs et les fichiers d'index restent stockés à distance jusqu'à ce qu'ils soient accédés pour la première fois, la première requête peut subir un temps de latence supplémentaire car les données requises doivent être récupérées à la demande. Pour atténuer cet effet pour les champs ou les index critiques, vous pouvez utiliser la stratégie Warm Up pour les précharger de manière proactive avant que le segment ne devienne interrogeable.

Configuration

Automatiquement appliqué lorsque le stockage hiérarchisé est activé. Aucun réglage manuel n'est nécessaire.

Phase 2 : Réchauffement

Pour réduire la latence de premier accès introduite par la charge paresseuse, Milvus fournit un mécanisme de réchauffement.

Avant qu'un segment ne devienne interrogeable, Milvus peut récupérer et mettre en cache de manière proactive des champs ou des index spécifiques à partir du stockage d'objets, en veillant à ce que la première requête atteigne directement les données mises en cache au lieu de déclencher un chargement à la demande.

Pendant l'échauffement, les champs seront préchargés au niveau du bloc, tandis que les index seront préchargés au niveau du segment.

Configuration de l'échauffement

Le préchauffage peut être configuré à trois niveaux :

  • Niveau cluster: Définir les valeurs par défaut dans milvus.yaml qui s'appliquent à toutes les collections.

  • Niveau collection: Remplacer les valeurs par défaut du cluster pour une collection spécifique en utilisant les méthodes SDK (create_collection, alter_collection_properties).

  • Niveau champ/indice: Ajustez les champs ou les index individuels à l'aide des méthodes du SDK (add_field, alter_collection_field, add_index, alter_index_properties).

Les paramètres de niveau supérieur prévalent sur ceux de niveau inférieur (Champ/Index > Collection > Cluster). Voir Warm Up pour les configurations détaillées.

Phase 3 : Chargement partiel

Une fois les requêtes ou les recherches lancées, le QueryNode effectue un chargement partiel, en récupérant uniquement les blocs de données ou les fichiers d'index requis dans le stockage d'objets.

  • Champs: Chargement à la demande au niveau des blocs de données. Seuls les blocs de données correspondant aux conditions de la requête en cours sont récupérés, ce qui minimise l'utilisation des E/S et de la mémoire.

  • Index: Chargés à la demande au niveau du segment. Les fichiers d'index doivent être récupérés en tant qu'unités complètes et ne peuvent pas être divisés en morceaux.

Configuration

La charge partielle est automatiquement appliquée lorsque le stockage hiérarchisé est activé. Aucun réglage manuel n'est nécessaire. Pour minimiser le temps de latence pour les données critiques, combiner avec Warm Up.

Phase 4 : Eviction

Pour maintenir une utilisation saine des ressources, Milvus libère automatiquement les données en cache inutilisées lorsque des seuils spécifiques sont atteints.

L'éviction suit une politique de moindre utilisation (LRU), garantissant que les données peu utilisées sont supprimées en premier, tandis que les données actives restent dans le cache.

L'éviction est régie par les éléments configurables suivants :

  • Filigranes: Définir des seuils de mémoire ou de disque qui déclenchent et arrêtent l'éviction.

  • TTL du cache : supprime les données périmées du cache après une durée d'inactivité définie.

Configuration

Activez et réglez les paramètres d'éviction dans milvus.yaml. Voir Eviction pour une configuration détaillée.

Mise en route

Conditions préalables

  • Milvus 2.6.4+

  • QueryNodes avec des ressources mémoire et disque dédiées

  • Backend de stockage d'objets (S3, MinIO, etc.)

Les ressources des QueryNodes ne doivent pas être partagées avec d'autres charges de travail. Les ressources partagées peuvent entraîner une mauvaise évaluation de la capacité disponible par le Tiered Storage, ce qui peut provoquer des pannes.

Modèle de configuration de base

Modifier le fichier de configuration Milvus (milvus.yaml) pour configurer les paramètres de stockage hiérarchisé au niveau de la grappe :

# milvus.yaml
queryNode:
  segcore:
    tieredStorage:
      # Warm Up Configuration
      warmup:
        scalarField: sync      # Preload scalar field data
        scalarIndex: sync      # Preload scalar indexes
        vectorField: disable   # Don't preload vector field data (large)
        vectorIndex: sync      # Preload vector indexes
      
      # Eviction Configuration
      evictionEnabled: true
      backgroundEvictionEnabled: true
      
      # Memory Watermarks
      memoryLowWatermarkRatio: 0.75   # Stop evicting at 75%
      memoryHighWatermarkRatio: 0.80  # Start evicting at 80%
      
      # Disk Watermarks  
      diskLowWatermarkRatio: 0.75
      diskHighWatermarkRatio: 0.80
      
      # Cache TTL (7 days)
      cacheTtl: 604800

Ce modèle définit les valeurs par défaut au niveau du cluster. Vous pouvez remplacer les paramètres de réchauffement pour des collections spécifiques ou des champs/index individuels à l'aide du SDK. Voir Warm Up pour plus de détails.

Prochaines étapes

  1. Configurer le préchauffage - Optimiser le préchargement pour vos modèles d'accès. Voir Warm Up.

  2. Régler l'éviction - Définir des filigranes et des TTL appropriés en fonction de vos contraintes en matière de ressources. Voir Eviction.

  3. Surveiller les performances - Suivre les taux d'accès au cache, la fréquence d'éviction et les schémas de latence des requêtes.

  4. Itération de la configuration - Ajustez les paramètres en fonction des caractéristiques observées de la charge de travail.

FAQ

Puis-je modifier les paramètres du stockage hiérarchisé au moment de l'exécution ?

Cela dépend du type de paramètre :

  • Paramètres d'échauffement: Le réchauffement au niveau de la collection et au niveau du champ/de l'index peut être configuré via le SDK avant le chargement de la collection. Une fois la collection chargée, vous devez d'abord la libérer, modifier les paramètres, puis la recharger.

  • Paramètres d'éviction et de filigrane: Ils doivent être définis sur milvus.yaml avant de lancer Milvus. Les modifications nécessitent un redémarrage pour être prises en compte.

Le stockage hiérarchisé affecte-t-il la durabilité des données ?

Non. La persistance des données est toujours gérée par le stockage d'objets à distance. Le stockage hiérarchisé gère uniquement la mise en cache sur les QueryNodes.

Les requêtes seront-elles toujours plus rapides avec le Tiered Storage ?

Pas nécessairement. Le stockage hiérarchisé réduit le temps de chargement et l'utilisation des ressources, mais les requêtes qui touchent des données non mises en cache (froides) peuvent présenter une latence plus élevée. Pour les charges de travail sensibles à la latence, il est recommandé d'utiliser le mode pleine charge.

Pourquoi un QueryNode manque-t-il toujours de ressources même si le stockage hiérarchisé est activé ?

Il y a deux causes courantes :

  • Le QueryNode a été configuré avec trop peu de ressources. Les filigranes sont relatifs aux ressources disponibles, de sorte que le sous-provisionnement amplifie les erreurs d'appréciation.

  • Les ressources du QueryNode sont partagées avec d'autres charges de travail, de sorte que Tiered Storage ne peut pas évaluer correctement la capacité disponible réelle.

Pour résoudre ce problème, nous vous recommandons d'allouer des ressources dédiées aux QueryNodes.

Pourquoi certaines requêtes échouent-elles en cas de forte concurrence ?

Si trop de requêtes atteignent les données chaudes en même temps, les limites de ressources des QueryNodes peuvent toujours être dépassées. Certains threads peuvent échouer en raison de délais de réservation des ressources. Il est possible de résoudre ce problème en réessayant une fois que la charge a diminué ou en allouant davantage de ressources.

Pourquoi la latence des recherches et des requêtes augmente-t-elle après l'activation du stockage hiérarchisé ?

Les causes possibles sont les suivantes

  • Des requêtes fréquentes sur des données froides, qui doivent être extraites du stockage.

  • Les filigranes sont trop proches les uns des autres, ce qui entraîne une éviction synchrone fréquente.