Tous les produits
Search
Centre de documentation

Container Service for Kubernetes:Bonnes pratiques pour l'optimisation du cache de données Fluid

Dernière mise à jour :Aug 29, 2026

Configurez la mise en cache des données Fluid pour équilibrer les performances, la stabilité et la cohérence en lecture/écriture.

Chaque section présente les configurations recommandées et des exemples YAML pour les modèles de charge de travail courants.

Quand la mise en cache des données est utile

La mise en cache profite aux charges de travail qui lisent à plusieurs reprises les mêmes données. Vérifiez si votre charge de travail correspond à ce modèle avant de configurer un système de cache.

Modèle de charge de travail Avantage de la mise en cache Exemple
Lectures répétées des mêmes données Élevé Entraînement IA itérant sur un jeu de données sur plusieurs époques
Lectures concurrentes de fichiers partagés Élevé Service d'inférence chargeant un modèle partagé dans la mémoire GPU au démarrage
Données partagées entre les tâches Élevé Tâches SparkSQL traitant des données de commande référencées par plusieurs requêtes analytiques
Lectures uniques Aucun Nettoyage de données ETL ou migration de données ponctuelle
Charges de travail en écriture seule Aucun Aucune opération de lecture sur le même chemin de données
Accès très peu fréquent Aucun Le cache expire ou est évincé avant réutilisation

Si la mise en cache s'applique à votre charge de travail, configurez les politiques ci-dessous.

Optimisation des performances

Configurez l'infrastructure (types d'instance ECS et supports de cache), ajustez les paramètres du cache et alignez la planification des Pods avec le placement du cache.

Sélectionner les types d'instance ECS pour le système de cache

Un cache distribué agrège le stockage et la bande passante sur plusieurs nœuds. Estimez les limites supérieures pour votre cluster de cache :

  • Capacité de cache disponible = Capacité de cache par Pod Worker x Nombre de réplicas de Pod Worker

  • Bande passante de cache disponible = Nombre de réplicas de Pod Worker x min{Bande passante maximale disponible du nœud ECS où s'exécute le Pod Worker, débit d'E/S du support de cache utilisé par le Pod Worker}

  • Bande passante théorique maximale de l'application = min{Bande passante disponible du nœud ECS où s'exécute le Pod d'application, Bande passante de cache disponible}

La bande passante réelle dépend de la bande passante disponible du nœud d'application et du modèle d'accès (séquentiel ou aléatoire). Lorsque plusieurs Pods d'application accèdent aux données simultanément, la bande passante du cache est partagée.

Exemple d'estimation

Ajoutez deux instances ecs.g7nex.8xlarge à votre cluster ACK en tant que Pods Worker de cache, chacune disposant de 100 GiB de mémoire sur un nœud distinct. Le Pod d'application s'exécute sur une instance ecs.gn7i-c8g1.2xlarge (8 vCPU, 30 GiB de mémoire, bande passante de 16 Gbps).

Métrique Calcul Résultat
Capacité de cache disponible 100 GiB x 2 200 GiB
Bande passante de cache disponible 2 x min{40 Gbps, Débit d'E/S d'accès mémoire} 80 Gbps
Bande passante maximale de l'application (en cas de succès du cache) min{80 Gbps, 16 Gbps} 16 Gbps

Le goulot d'étranglement est la bande passante de 16 Gbps du nœud d'application, et non le cluster de cache. Pour augmenter le débit, utilisez un type d'instance à plus haute bande passante ou répartissez la charge de travail sur plusieurs Pods d'application.

Types d'instance ECS recommandés

Choisissez des types d'instance à haute bande passante pour les nœuds de cache. Utilisez la mémoire pour un débit maximal, ou des SSD locaux pour une capacité plus importante à moindre coût.

Famille d'instances ECS Type d'instance ECS Configuration
g7nex, usage général amélioré pour le réseau ecs.g7nex.8xlarge 32 vCPU, 128 GiB de mémoire, bande passante de 40 Gbps
ecs.g7nex.16xlarge 64 vCPU, 256 GiB de mémoire, bande passante de 80 Gbps
ecs.g7nex.32xlarge 128 vCPU, 512 GiB de mémoire, bande passante de 160 Gbps
i4g, stockage SSD local ecs.i4g.16xlarge 64 vCPU, 256 GiB de mémoire, 2 x 1920 Go de SSD local, bande passante de 32 Gbps
ecs.i4g.32xlarge 128 vCPU, 512 GiB de mémoire, 4 x 1920 Go de SSD local, bande passante de 64 Gbps
g7ne, usage général amélioré pour le réseau ecs.g7ne.8xlarge 32 vCPU, 128 GiB de mémoire, bande passante de 25 Gbps
ecs.g7ne.12xlarge 48 vCPU, 192 GiB de mémoire, bande passante de 40 Gbps
ecs.g7ne.24xlarge 96 vCPU, 384 GiB de mémoire, bande passante de 80 Gbps
g8i, usage général ecs.g8i.24xlarge 96 vCPU, 384 GiB de mémoire, bande passante de 50 Gbps
ecs.g8i.16xlarge 64 vCPU, 256 GiB de mémoire, bande passante de 32 Gbps

Consultez Familles d'instances pour les spécifications.

Sélectionner le support de cache

Le support de cache détermine le plafond de débit d'E/S pour chaque nœud. Même si une instance ECS dispose d'une bande passante réseau élevée, un support de cache lent devient le goulot d'étranglement.

Important

Un SSD entreprise (ESSD) ne peut souvent pas répondre aux besoins de performance des charges de travail intensives en données. Par exemple, un seul disque PL2 a un débit maximal de 750 Mo/s. Si vous utilisez un disque PL2 comme support de cache sur une instance avec une bande passante de 40 Gbps, la bande passante effective du cache est limitée à 750 Mo/s, gaspillant ainsi la capacité réseau de l'instance.

Supports de cache disponibles :

Support de cache **mediumtype** **volumeType** **path** Idéal pour
Mémoire MEM emptyDir /dev/shm Débit maximal ; le jeu de données tient en mémoire
Disque système (SSD local) SSD emptyDir /var/lib/fluid/cache Capacité plus importante à moindre coût ; cycle de vie du cache lié au Pod Worker
Disque de données SSD monté SSD hostPath /mnt/disk1 Disque dédié au stockage du cache
Plusieurs disques de données SSD SSD hostPath /mnt/disk1,/mnt/disk2 Capacité locale la plus élevée ; capacité répartie uniformément sur les disques

Configurez le support de cache et la capacité dans spec.tieredstore sur la ressource Runtime :

Mémoire comme support de cache

spec:
  tieredstore:
    levels:
      - mediumtype: MEM
        volumeType: emptyDir
        path: /dev/shm
        quota: 30Gi # Cache capacity per Worker Pod replica.
        high: "0.99"
        low: "0.95"

Stockage local comme support de cache

Choisissez en fonction de votre configuration de disque :

Stockage sur disque système :

spec:
  tieredstore:
    levels:
      - mediumtype: SSD
        volumeType: emptyDir # emptyDir ties the cache lifecycle to the Worker Pod, preventing residual data.
        path: /var/lib/fluid/cache
        quota: 100Gi # Cache capacity per Worker Pod replica.
        high: "0.99"
        low: "0.95"

Disque de données SSD monté :

spec:
  tieredstore:
    levels:
      - mediumtype: SSD
        volumeType: hostPath
        path: /mnt/disk1 # Mount path of the local SSD on the host.
        quota: 100Gi # Cache capacity per Worker Pod replica.
        high: "0.99"
        low: "0.95"

Plusieurs disques de données SSD :

spec:
  tieredstore:
    levels:
      - mediumtype: SSD
        volumeType: hostPath
        path: /mnt/disk1,/mnt/disk2 # Mount paths of the data disks on the host.
        quota: 100Gi # Cache capacity per Worker Pod replica. Capacity is evenly distributed: /mnt/disk1 and /mnt/disk2 each get 50 GiB.
        high: "0.99"
        low: "0.95"
Les seuils high et low contrôlent l'éviction du cache. Lorsque l'utilisation du cache dépasse le seuil high , le système de cache évince les données jusqu'à ce que l'utilisation descende au seuil low .

Configurer l'affinité de planification entre le cache et les applications

La latence réseau inter-zones entre les Pods d'application et les Pods Worker de cache dégrade les performances d'accès aux données. Déployez-les dans la même zone.

Plus précisément :

  • Déployez les Pods Worker de cache dans la même zone dans la mesure du possible.

  • Déployez les Pods d'application dans la même zone que les Pods Worker de cache dans la mesure du possible.

Important

Concentrer tous les Pods dans une seule zone réduit la capacité de reprise après sinistre. Équilibrez les performances et la disponibilité en fonction de votre accord de niveau de service (SLA).

Définissez la zone de cache en configurant spec.nodeAffinity sur la ressource Dataset :

apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: demo-dataset
spec:
  ...
  nodeAffinity:
    required:
      nodeSelectorTerms:
        - matchExpressions:
            - key: topology.kubernetes.io/zone
              operator: In
              values:
                - <ZONE_ID> # The zone to deploy cache Worker Pods in, for example, cn-beijing-i.

Cela place les Pods Worker de cache sur les nœuds de la zone spécifiée. Fluid peut également injecter automatiquement des règles d'affinité afin que les Pods d'application soient planifiés aux côtés des Pods Worker de cache. Consultez Optimiser la planification en fonction de l'affinité du cache de données.

Ajuster les paramètres de prélecture pour les lectures séquentielles de gros fichiers

Les charges de travail qui effectuent des lectures séquentielles complètes sur de gros fichiers peuvent bénéficier de paramètres de prélecture agressifs. Voici quelques exemples courants :

  • Entraînement IA sur des jeux de données au format TFRecord ou Tar

  • Chargement des fichiers de paramètres de modèle au démarrage du service d'inférence

  • Analytique distribuée lisant des fichiers Parquet

Une prélecture agressive augmente l'amplification des lectures. Pour les lectures aléatoires ou les petits fichiers, ces paramètres gaspillent de la bande passante sur des données inutilisées. Utilisez les valeurs par défaut pour les charges de travail mixtes ou à lecture aléatoire.

La configuration de la prélecture varie selon le runtime.

JindoRuntime

Configurez la prélecture FUSE (Filesystem in Userspace) dans spec.fuse.properties :

kind: JindoRuntime
metadata:
  ...
spec:
  fuse:
    properties:
      fs.oss.download.thread.concurrency: "200"
      fs.oss.read.buffer.size: "8388608"
      fs.oss.read.readahead.max.buffer.count: "200"
      fs.oss.read.sequence.ambiguity.range: "2147483647" # About 2 GB.
Paramètre Description
fs.oss.download.thread.concurrency Nombre de threads de prélecture simultanés.
fs.oss.read.buffer.size Taille d'un seul tampon de prélecture.
fs.oss.read.readahead.max.buffer.count Nombre maximal de tampons pour une prélecture à flux unique.
fs.oss.read.sequence.ambiguity.range Plage utilisée pour déterminer si un modèle de lecture est séquentiel.

JuiceFSRuntime

Configurez la prélecture dans spec.fuse.options et spec.worker.options :

kind: JuiceFSRuntime
metadata:
  ...
spec:
  fuse:
    options:
      buffer-size: "2048"
      cache-size: "0"
      max-uploads: "150"
  worker:
    options:
      buffer-size: "2048"
      max-downloads: "200"
      max-uploads: "150"
  master:
    resources:
      requests:
        memory: 2Gi
      limits:
        memory: 8Gi
  ...
Paramètre Description
buffer-size Taille du tampon de lecture/écriture.
max-downloads Concurrence des téléchargements de prélecture.
max-uploads Concurrence des téléchargements.
fuse cache-size Capacité du cache local pour FUSE.

Le paramètre cache-size: "0" désactive le cache local FUSE, qui utilise alors la mémoire du nœud comme cache de pages Linux. En cas d'échec du cache, il lit à partir du cache distribué JuiceFSRuntime Worker. Consultez la documentation JuiceFS pour un ajustement détaillé.

Optimisation de la stabilité

Les politiques suivantes traitent des risques de stabilité courants : surcharge des métadonnées, perte de données au redémarrage du Pod, plantages FUSE dus à une erreur de mémoire (OOM) et défaillances des points de montage.

Éviter de monter des répertoires contenant trop de fichiers

Le système de cache maintient les métadonnées pour chaque fichier du répertoire monté. Monter un répertoire contenant trop de fichiers (comme la racine d'un système de stockage à grande échelle) consomme une quantité excessive de mémoire et de CPU.

Montez des sous-répertoires spécifiques correspondant à votre périmètre de données. Créez des Datasets distincts pour différentes collections de données.

apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: demo-dataset
spec:
  ...
  mounts:
  - mountPoint: oss://<BUCKET>/<PATH1>/<SUBPATH>/
    name: sub-bucket
Plusieurs systèmes de cache ajoutent de la complexité opérationnelle. Choisissez la granularité appropriée en fonction de vos besoins.
Scénario Approche
Petit jeu de données avec peu de fichiers et forte pertinence Un Dataset et un système de cache
Grand jeu de données avec de nombreux fichiers Diviser en plusieurs Datasets par répertoire de données. Les Pods d'application peuvent monter plusieurs Datasets.
Plusieurs utilisateurs ou exigences d'isolation des données Créer des Datasets éphémères par utilisateur ou tâche. Envisagez un opérateur Kubernetes pour une gestion dynamique.

Persister les métadonnées avec un stockage durable

JindoRuntime et les systèmes de cache similaires utilisent une architecture Master-Worker. Le Pod Master stocke les métadonnées de fichiers et l'état du cache pour le stockage backend monté. Sans métadonnées persistantes, un redémarrage nécessite une reconstruction complète de l'état.

Utilisez une revendication de volume persistant (PVC) sauvegardée par un ESSD pour stocker les métadonnées de manière durable :

apiVersion: data.fluid.io/v1alpha1
kind: JindoRuntime
metadata:
  name: sd-dataset
spec:
  ...
  volumes:
    - name: meta-vol
      persistentVolumeClaim:
        claimName: demo-jindo-master-meta
  master:
    resources:
      requests:
        memory: 4Gi
      limits:
        memory: 8Gi
    volumeMounts:
      - name: meta-vol
        mountPath: /root/jindofs-meta
    properties:
      namespace.meta-dir: "/root/jindofs-meta"

Ici, demo-jindo-master-meta est une PVC précréée sauvegardée par un ESSD. Les métadonnées survivent aux redémarrages de Pod et migrent avec le Pod. Consultez Utiliser JindoRuntime pour persister l'état du Pod Master.

Allouer des ressources au Pod FUSE

Le Pod FUSE monte un système de fichiers FUSE sur le nœud et le monte par liaison dans le Pod d'application, exposant une interface POSIX pour lire les données distantes comme des fichiers locaux.

Pour éviter les échecs de montage liés à une erreur de mémoire (OOM), évitez de définir une limite de mémoire pour le Pod FUSE, ou définissez-la proche de la mémoire allouable du nœud :

spec:
  fuse:
    resources:
      requests:
        memory: 8Gi
    # limits:
    #   memory: <ECS_ALLOCATABLE_MEMORY>
Si le Pod FUSE est arrêté par le tueur OOM, le point de montage du Pod d'application se rompt. Redémarrez l'application pour rétablir le montage, sauf si l'auto-réparation FUSE est activée (voir ci-dessous).

Activer l'auto-réparation FUSE

Par défaut, un plantage FUSE rend le point de montage inaccessible. Le conteneur d'application doit redémarrer pour déclencher à nouveau le montage par liaison.

Le mécanisme d'auto-réparation FUSE de Fluid récupère automatiquement l'accès au point de montage après un redémarrage FUSE sans nécessiter le redémarrage du conteneur d'application.

Important

Pendant la fenêtre de redémarrage FUSE, le point de montage est inaccessible. L'application doit gérer les erreurs d'E/S et inclure une logique de nouvelle tentative.

L'auto-réparation FUSE présente des limitations. Activez-la uniquement lorsque le redémarrage est perturbateur, comme dans les environnements interactifs Jupyter Notebook ou VS Code.

Consultez Comment activer la capacité d'auto-récupération FUSE.

Cohérence en lecture/écriture du cache

La mise en cache introduit des défis de cohérence — une cohérence forte dégrade souvent les performances. Choisissez une politique qui correspond au modèle de lecture/écriture de votre charge de travail.

Le tableau suivant résume les cinq scénarios. Consultez chaque sous-section pour les détails de configuration.

Scénario Modifications des données backend Mode d'accès Approche de configuration
Lecture seule, données statiques Aucune ReadOnlyMany (par défaut) Configuration Dataset par défaut
Lecture seule, modifications périodiques Périodique (planifiée) ReadOnlyMany DataLoad avec politique Cron
Lecture seule, modifications pilotées par événements À la demande ReadOnlyMany Désactiver le cache de métadonnées ; définir les délais d'expiration des métadonnées FUSE
Lecture/écriture, répertoires séparés Via un chemin d'écriture séparé ReadOnlyMany + ReadWriteMany Deux Datasets avec différents modes d'accès
Lecture/écriture, même répertoire Sur place ReadWriteMany Dataset unique ; backend compatible POSIX

Scénario 1 : Données en lecture seule sans modifications backend

Quand l'utiliser : Une seule tâche d'entraînement IA lit un jeu de données fixe sur plusieurs époques. Le cache est vidé après l'entraînement.

Configuration : Fluid utilise par défaut le mode lecture seule. Utilisez la configuration Dataset par défaut ou définissez-la explicitement :

apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: demo-dataset
spec:
  ...
  # accessModes: ["ReadOnlyMany"] ReadOnlyMany is the default value.

Le paramètre accessModes: ["ReadOnlyMany"] empêche les écritures accidentelles dans le jeu de données pendant l'entraînement.

Scénario 2 : Données en lecture seule avec modifications backend périodiques

Quand l'utiliser : Les données métier sont collectées quotidiennement dans le stockage backend. Des tâches d'analyse nocturnes traitent les données du jour. Les résultats sont écrits directement dans le stockage backend, en contournant le cache.

Configuration : Utilisez une ressource DataLoad avec une politique Cron pour synchroniser les modifications depuis le stockage backend à intervalles réguliers :

apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: demo-dataset
spec:
  ...
  # accessModes: ["ReadOnlyMany"] ReadOnlyMany is the default value.
---
apiVersion: data.fluid.io/v1alpha1
kind: DataLoad
metadata:
  name: demo-dataset-warmup
spec:
  ...
  policy: Cron
  schedule: "0 0 * * *" # Prefetch data at 00:00 every day.
  loadMetadata: true # Sync metadata changes from backend storage during prefetch.
  target:
  - path: /path/to/warmup # Path in backend storage to prefetch.

Le paramètre loadMetadata: true actualise également les métadonnées lors de chaque préchargement, maintenant ainsi la cohérence du cache avec le stockage backend.

Scénario 3 : Données en lecture seule avec modifications backend pilotées par événements

Quand l'utiliser : Les utilisateurs téléversent des modèles personnalisés dans le stockage backend et les sélectionnent pour l'inférence. Le cache doit refléter les nouveaux téléversements sans attendre une synchronisation planifiée.

Configuration : Désactivez le cache de métadonnées côté serveur et définissez des délais d'expiration courts pour les métadonnées FUSE afin de forcer les vérifications du stockage backend à chaque accès.

Utilisation de JindoRuntime :

apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: demo-dataset
spec:
  mounts:
    - mountPoint: <MOUNTPOINT>
      name: data
      path: /
      options:
        metaPolicy: ALWAYS # Disable server-side metadata cache.
---
apiVersion: data.fluid.io/v1alpha1
kind: JindoRuntime
metadata:
  name: demo-dataset
spec:
  fuse:
    args:
      - -oauto_cache
      # Metadata timeout in seconds. Setting to 0 provides strong consistency but may greatly reduce read efficiency.
      - -oattr_timeout=30
      - -oentry_timeout=30
      - -onegative_timeout=30
      - -ometrics_port=0

Le paramètre metaPolicy: ALWAYS désactive le cache de métadonnées côté serveur, forçant chaque accès aux métadonnées à interroger directement le stockage backend.

La définition de attr_timeout , entry_timeout et negative_timeout à 0 offre une cohérence forte mais peut réduire considérablement les performances de lecture. Une valeur de 30 (secondes) équilibre la fraîcheur et les performances pour la plupart des scénarios pilotés par événements.

Scénario 4 : Lecture et écriture dans des répertoires séparés

Quand l'utiliser : L'entraînement distribué à grande échelle lit les données depuis le répertoire A et écrit des points de contrôle dans le répertoire B à chaque époque. La mise en cache des écritures améliore l'efficacité des points de contrôle.

Configuration : Créez deux Datasets. Définissez l'un en lecture seule pour les données d'entraînement et l'autre en lecture-écriture pour les points de contrôle :

apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: train-samples
spec:
  ...
  # accessModes: ["ReadOnlyMany"] ReadOnlyMany is the default value.
---
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: model-ckpt
spec:
  ...
  accessModes: ["ReadWriteMany"]

Montez les deux Datasets sur le Pod d'application :

apiVersion: v1
kind: Pod
metadata:
  ...
spec:
  containers:
  ...
    volumeMounts:
    - name: train-samples-vol
      mountPath: /data/A
    - name: model-ckpt-vol
      mountPath: /data/B
  volumes:
    - name: train-samples-vol
      persistentVolumeClaim:
        claimName: train-samples
    - name: model-ckpt-vol
      persistentVolumeClaim:
        claimName: model-ckpt

Cela isole le jeu de données d'entraînement des points de contrôle. Le Dataset train-samples en lecture seule empêche les problèmes de cohérence liés à l'écriture, tandis que le Dataset model-ckpt en lecture-écriture permet les écritures mises en cache.

Scénario 5 : Lecture et écriture dans le même répertoire

Quand l'utiliser : Développement interactif, tel qu'un espace de travail Jupyter Notebook ou VS Code en ligne, où les fichiers sont fréquemment créés, modifiés et supprimés dans un répertoire partagé.

Configuration : Définissez le mode d'accès du Dataset en lecture-écriture. Utilisez un backend de stockage compatible POSIX :

apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: myworkspace
spec:
  ...
  accessModes: ["ReadWriteMany"]

Le paramètre ReadWriteMany permet l'accès simultané en lecture/écriture au même répertoire par plusieurs utilisateurs ou processus.

Références