Mise en cache du pipeline

Azure DevOps Services

La mise en cache du pipeline peut aider à réduire le temps de génération en permettant de réutiliser les sorties ou les dépendances téléchargées d’une exécution dans les exécutions ultérieures, ce qui réduit ou évite le coût de recréation ou de retéléchargement des mêmes fichiers. La mise en cache est particulièrement utile dans les scénarios où les mêmes dépendances sont téléchargées à plusieurs reprises au début de chaque exécution. Il s’agit souvent d’un processus long impliquant des centaines ou des milliers d’appels réseau.

La mise en cache peut être efficace pour améliorer le temps de génération, à condition que le temps de restauration et d’enregistrement du cache soit inférieur au temps nécessaire pour produire à nouveau la sortie à partir de zéro. Pour cette raison, la mise en cache peut ne pas être efficace dans tous les scénarios et peut avoir un impact négatif sur le temps de génération.

La mise en cache est actuellement prise en charge dans les travaux CI et de déploiement, mais pas dans les travaux de mise en production classiques.

Quand utiliser des artefacts ou la mise en cache

La mise en cache de pipeline et les artefacts de pipeline exécutent des fonctions similaires, mais sont conçus pour différents scénarios et ne doivent pas être utilisés indifféremment.

  • Utilisez des artefacts de pipeline quand vous devez prendre des fichiers spécifiques produits dans un travail et les partager avec d’autres travaux (et que ces autres travaux échouent vraisemblablement sans eux).

  • Utilisez la mise en cache de pipeline quand vous voulez améliorer le temps de génération en réutilisant les fichiers des exécutions précédentes (et que l’absence de ces fichiers n’impacte pas la capacité d’exécution du travail).

Notes

La mise en cache de pipeline et les artefacts de pipeline sont gratuits pour tous les niveaux (gratuits et payants). Pour plus d’informations, consultez Consommation de stockage des artefacts.

Tâche de cache : comment elle fonctionne

La mise en cache est ajoutée à un pipeline en utilisant la tâche de cache. Cette tâche fonctionne comme toutes autres tâches et est ajoutée à la section steps d’un travail.

Quand une étape de cache est rencontrée pendant une exécution, la tâche restaure le cache en fonction des entrées fournies. Si aucun cache n’est trouvé, l’étape se termine et l’étape suivante du travail est exécutée.

Une fois que toutes les étapes du travail ont été exécutées et en supposant un état de travail réussi, une étape spéciale « Post-travail : Cache » est automatiquement ajoutée et déclenchée pour chaque étape de « restauration du cache » qui n’a pas été ignorée. Cette étape enregistre le cache.

Notes

Les caches sont immuables, ce qui signifie qu’une fois qu’un cache est créé, son contenu ne peut pas être changé.

Configuration de la tâche de cache

La tâche de cache a deux arguments obligatoires : key et path :

  • path : chemin du dossier à mettre en cache. Peut être un chemin absolu ou relatif. Les chemins relatifs sont résolus par rapport à $(System.DefaultWorkingDirectory).

Notes

Vous pouvez utiliser des variables prédéfinies pour stocker le chemin du dossier que vous souhaitez mettre en cache, mais les caractères génériques ne sont pas pris en charge.

  • key : doit être défini sur l’identificateur du cache que vous voulez restaurer ou enregistrer. Les clés sont composées d’une combinaison de valeurs de chaîne, de chemins de fichier ou de modèles de fichier, où chaque segment est séparé par un caractère |.
  • Chaînes :
    Valeur fixe (comme le nom du cache ou un nom d’outil) ou tirée d’une variable d’environnement (comme le système d’exploitation actuel ou le nom du travail actuel)

  • Chemins de fichier :
    Chemin d’un fichier spécifique dont le contenu doit être haché. Ce fichier doit exister au moment de l’exécution de la tâche. N’oubliez pas que tout segment de clé qui « ressemble à un chemin de fichier » est traité comme un chemin de fichier. En particulier, cela comprend les segments contenant un .. Cela peut entraîner l’échec de la tâche si ce « fichier » n’existe pas.

    Conseil

    Pour éviter qu’un segment de chaîne de type chemin soit traité comme un chemin, placez-le entre guillemets doubles, par exemple : "my.key" | $(Agent.OS) | key.file

  • Modèles de fichier :
    Liste séparée par des virgules de modèles génériques de style glob qui doivent correspondre à au moins un fichier. Par exemple :

    • **/yarn.lock : tous les fichiers yarn.lock sous le répertoire des sources
    • */asset.json, !bin/** : tous les fichiers asset.json situés dans un répertoire sous le répertoire des sources, à l’exception du répertoire bin

Le contenu d’un fichier identifié par un chemin ou un modèle de fichier est haché pour produire une clé de cache dynamique. C’est utile quand votre projet contient des fichiers qui identifient de manière unique ce qui est mis en cache. Par exemple, les fichiers de type package-lock.json, yarn.lock, Gemfile.lock ou Pipfile.lock sont couramment référencés dans une clé de cache, car ils représentent tous un ensemble unique de dépendances.

Les chemins de fichier relatifs ou les modèles de fichier sont résolus par rapport à $(System.DefaultWorkingDirectory).

Exemple :

Voici un exemple montrant comment mettre en cache les dépendances installées par Yarn :

variables:
  YARN_CACHE_FOLDER: $(Pipeline.Workspace)/s/.yarn

steps:
- task: Cache@2
  inputs:
    key: '"yarn" | "$(Agent.OS)" | yarn.lock'
    restoreKeys: |
       "yarn" | "$(Agent.OS)"
       "yarn"
    path: $(YARN_CACHE_FOLDER)
  displayName: Cache Yarn packages

- script: yarn --frozen-lockfile

Dans cet exemple, la clé de cache contient trois parties : une chaîne statique (« yarn »), le système d’exploitation sur lequel le travail s’exécute, car ce cache est unique par système d’exploitation, et le hachage du fichier yarn.lock qui identifie de manière unique l’ensemble de dépendances dans le cache.

Pendant la première exécution après l’ajout de la tâche, l’étape de cache signale un « échec de cache », car le cache identifié par cette clé n’existe pas. Après la dernière étape, un cache est créé à partir des fichiers dans $(Pipeline.Workspace)/s/.yarn et chargé. Pendant l’exécution suivante, l’étape de cache signale une « correspondance dans le cache », et le contenu du cache est téléchargé et restauré.

Lorsque vous utilisez checkout: self, le référentiel est extrait vers $(Pipeline.Workspace)/s, et votre dossier .yarn réside généralement dans le référentiel lui-même.

Remarque

Pipeline.Workspace est le chemin local sur l’agent exécutant votre pipeline où tous les répertoires sont créés. Cette variable a la même valeur que Agent.BuildDirectory.

Veillez à mettre à jour la variable YARN_CACHE_FOLDER si vous utilisez autre chose que checkout: self, car elle doit pointer vers le référentiel où réside .yarn.

Clés de restauration

restoreKeys peut être utilisé pour interroger plusieurs clés exactes ou préfixes de clé. Permet de revenir à une autre clé si un key ne donne pas de correspondance dans le cache. La clé de restauration recherche une clé par préfixe et génère la dernière entrée de cache créée. C’est utile si le pipeline ne trouve pas de correspondance exacte, mais veut utiliser une correspondance partielle dans le cache à la place. Pour insérer plusieurs clés de restauration, séparez-les par une nouvelle ligne pour indiquer la clé de restauration (voir l’exemple pour plus d’informations). Les clés de restauration sont essayées de haut en bas.

Logiciel nécessaire sur l’agent auto-hébergé

Logiciel d’archivage / Plateforme Windows Linux Mac
GNU Tar Obligatoire Obligatoire Non
BSD Tar Non Non Obligatoire
7-Zip Recommandé Non Non

Les exécutables ci-dessus doivent être dans un dossier listé dans la variable d’environnement PATH. Gardez à l’esprit que les agents hébergés sont fournis avec le logiciel. Cela s’applique uniquement aux agents auto-hébergés.

Exemple :

Voici un exemple d’utilisation des clés de restauration par Yarn :

variables:
  YARN_CACHE_FOLDER: $(Pipeline.Workspace)/.yarn

steps:
- task: Cache@2
  inputs:
    key: '"yarn" | "$(Agent.OS)" | yarn.lock'
    restoreKeys: |
       yarn | "$(Agent.OS)"
       yarn
    path: $(YARN_CACHE_FOLDER)
  displayName: Cache Yarn packages

- script: yarn --frozen-lockfile

Dans cet exemple, la tâche de cache tente de déterminer si la clé existe dans le cache. Si la clé n’existe pas dans le cache, elle tente d’utiliser la première clé de restauration yarn | $(Agent.OS). Cette clé tente de rechercher toutes les clés qui correspondent exactement à cette clé ou qui ont cette clé comme préfixe. Une correspondance de préfixe peut se produire s’il existe un autre segment de hachage yarn.lock. Par exemple, si la clé suivante yarn | $(Agent.OS) | old-yarn.lock était dans le cache où old-yarn.lock a produit un hachage différent de yarn.lock, la clé de restauration génère un résultat partiel. S’il y a un échec pour la première clé de restauration, elle utilise la clé de restauration yarn suivante qui essaie de trouver une clé qui commence par yarn. Pour les correspondances de préfixe, le résultat produit la clé de cache la plus récente créée.

Notes

Un pipeline peut avoir une ou plusieurs tâches de cache. Il n’existe aucune limite pour la capacité de stockage de mise en cache, et les travaux et tâches du même pipeline peuvent accéder au même cache et le partager.

Isolement et sécurité du cache

Pour garantir l’isolement entre les caches de différents pipelines et différentes branches, chaque cache appartient à un conteneur logique appelé étendue. Les étendues fournissent une limite de sécurité qui garantit qu’un travail de pipeline ne peut pas accéder aux caches à partir d’un autre pipeline, et qu’un travail qui génère une PR a un accès en lecture aux caches de la branche cible de la PR (pour le même pipeline), mais ne peut pas écrire (créer) des caches dans l’étendue de la branche cible.

Quand une étape de cache est rencontrée pendant une exécution, le cache identifié par la clé est demandé au serveur. Le serveur recherche un cache avec cette clé dans les étendues visibles pour le travail, puis renvoie le cache (si disponible). Pendant l’enregistrement du cache (à la fin du travail), un cache est écrit dans l’étendue représentant le pipeline et la branche. Vous trouverez plus de détails à la suite.

Exécutions CI, manuelles et planifiées

Étendue Lire Write
Branche source Oui Oui
Branche primaire (branche par défaut) Oui Non

Exécutions de demande de tirage

Étendue Lire Write
Branche source Oui Non
Branche cible Oui Non
Branche intermédiaire (par exemple, refs/pull/1/merge) Oui Oui
Branche primaire (branche par défaut) Oui Non

Exécutions de duplication de demande de tirage

Branche Lire Write
Branche cible Oui Non
Branche intermédiaire (par exemple, refs/pull/1/merge) Oui Oui
Branche primaire (branche par défaut) Oui Non

Conseil

Comme les caches sont déjà étendus à un projet, un pipeline et une branche, vous n’avez pas besoin d’ajouter les identificateurs de projet, de pipeline ou de branche dans la clé de cache.

Conditions pour la restauration du cache

Dans certains scénarios, la restauration du cache doit entraîner l’exécution d’un ensemble différent d’étapes. Par exemple, une étape qui installe des dépendances peut être ignorée si le cache a été restauré. Cela est possible avec l’entrée de tâche cacheHitVar. Si vous définissez cette entrée sur le nom d’une variable d’environnement, la variable est définie sur true en cas de correspondance dans le cache, inexact en cas de correspondance dans le cache de la clé de restauration. Sinon, elle est définie sur false. Cette variable peut ensuite être référencée dans une condition d’étape ou à partir d’un script.

Dans l’exemple suivant, l’étape install-deps.sh est ignorée quand le cache est restauré :

steps:
- task: Cache@2
  inputs:
    key: mykey | mylockfile
    restoreKeys: mykey
    path: $(Pipeline.Workspace)/mycache
    cacheHitVar: CACHE_RESTORED

- script: install-deps.sh
  condition: ne(variables.CACHE_RESTORED, 'true')

- script: build.sh

Bundler

Pour les projets Ruby utilisant Bundler, remplacez la variable d’environnement BUNDLE_PATH utilisée par Bundler pour définir le chemin dans lequel Bundler recherche Gems.

Exemple :

variables:
  BUNDLE_PATH: $(Pipeline.Workspace)/.bundle

steps:
- task: Cache@2
  displayName: Bundler caching
  inputs:
    key: 'gems | "$(Agent.OS)" | Gemfile.lock'
    path: $(BUNDLE_PATH)
    restoreKeys: | 
      gems | "$(Agent.OS)"
      gems   

Ccache (C/C++)

Ccache est un cache de compilateur pour C/C++. Pour utiliser Ccache dans votre pipeline, vérifiez que Ccache est installé et éventuellement ajouté à votre PATH (voir Modes d’exécution de Ccache). Définissez la variable d’environnement CCACHE_DIR sur un chemin sous $(Pipeline.Workspace) et mettez en cache ce répertoire.

Exemple :

variables:
  CCACHE_DIR: $(Pipeline.Workspace)/ccache

steps:
- bash: |
    sudo apt-get install ccache -y    
    echo "##vso[task.prependpath]/usr/lib/ccache"
  displayName: Install ccache and update PATH to use linked versions of gcc, cc, etc

- task: Cache@2
  displayName: Ccache caching
  inputs:
    key: 'ccache | "$(Agent.OS)" | $(Build.SourceVersion)'
    path: $(CCACHE_DIR)
    restoreKeys: | 
      ccache | "$(Agent.OS)"

Pour plus d’informations, consultez Paramètres de configuration de Ccache.

docker images

La mise en cache des images Docker réduit considérablement le temps d’exécution de votre pipeline.

variables:
  repository: 'myDockerImage'
  dockerfilePath: '$(Build.SourcesDirectory)/app/Dockerfile'
  tag: '$(Build.BuildId)'

pool:
  vmImage: 'ubuntu-latest'
steps:
  - task: Cache@2
    displayName: Cache task
    inputs:
      key: 'docker | "$(Agent.OS)" | cache'
      path: $(Pipeline.Workspace)/docker
      cacheHitVar: CACHE_RESTORED                #Variable to set to 'true' when the cache is restored
    
  - script: |
      docker load -i $(Pipeline.Workspace)/docker/cache.tar
    displayName: Docker restore
    condition: and(not(canceled()), eq(variables.CACHE_RESTORED, 'true'))

  - task: Docker@2
    displayName: 'Build Docker'
    inputs:
      command: 'build'
      repository: '$(repository)'
      dockerfile: '$(dockerfilePath)'
      tags: |
        '$(tag)'

  - script: |
      mkdir -p $(Pipeline.Workspace)/docker
      docker save -o $(Pipeline.Workspace)/docker/cache.tar $(repository):$(tag)
    displayName: Docker save
    condition: and(not(canceled()), not(failed()), ne(variables.CACHE_RESTORED, 'true'))
  • key : (obligatoire) identificateur unique du cache.
  • path : (obligatoire) chemin du dossier ou du fichier que vous voulez mettre en cache.

Golang

Pour les projets Golang, vous pouvez spécifier les packages à télécharger dans le fichier go.mod. Si votre variable GOCACHE n’est pas déjà définie, définissez-la sur l’emplacement où télécharger le cache.

Exemple :

variables:
  GO_CACHE_DIR: $(Pipeline.Workspace)/.cache/go-build/

steps:
- task: Cache@2
  inputs:
    key: 'go | "$(Agent.OS)" | go.mod'
    restoreKeys: | 
      go | "$(Agent.OS)"
    path: $(GO_CACHE_DIR)
  displayName: Cache GO packages

Gradle

L’utilisation de la prise en charge de la mise en cache intégrée de Gradle peut avoir un impact significatif sur le temps de génération. Pour activer le cache de build, définissez la variable d’environnement GRADLE_USER_HOME sur un chemin sous $(Pipeline.Workspace), et exécutez votre build avec --build-cache ou ajoutez org.gradle.caching=true à votre fichier gradle.properties.

Exemple :

variables:
  GRADLE_USER_HOME: $(Pipeline.Workspace)/.gradle

steps:
- task: Cache@2
  inputs:
    key: 'gradle | "$(Agent.OS)" | **/build.gradle.kts' # Swap build.gradle.kts for build.gradle when using Groovy
    restoreKeys: |
      gradle | "$(Agent.OS)"
      gradle
    path: $(GRADLE_USER_HOME)
  displayName: Configure gradle caching

- task: Gradle@2
  inputs:
    gradleWrapperFile: 'gradlew'
    tasks: 'build'
    options: '--build-cache'
  displayName: Build

- script: |   
    # stop the Gradle daemon to ensure no files are left open (impacting the save cache operation later)
    ./gradlew --stop    
  displayName: Gradlew stop
  • restoreKeys : clés de secours en cas d’échec de la clé primaire (facultatif)

Notes

Les caches sont immuables, dès qu’un cache avec une clé particulière est créé pour une étendue spécifique (branche), le cache ne peut pas être mis à jour. Cela signifie que si la clé est une valeur fixe, toutes les builds suivantes pour la même branche ne peuvent pas mettre à jour le cache même si le contenu du cache a changé. Si vous voulez utiliser une valeur de clé fixe, vous devez utiliser l’argument restoreKeys comme option de secours.

Maven

Maven a un référentiel local où il stocke les téléchargements et les artefacts générés. Pour l’activer, définissez l’option maven.repo.local sur un chemin sous $(Pipeline.Workspace) et mettez en cache ce dossier.

Exemple :

variables:
  MAVEN_CACHE_FOLDER: $(Pipeline.Workspace)/.m2/repository
  MAVEN_OPTS: '-Dmaven.repo.local=$(MAVEN_CACHE_FOLDER)'

steps:
- task: Cache@2
  inputs:
    key: 'maven | "$(Agent.OS)" | **/pom.xml'
    restoreKeys: |
      maven | "$(Agent.OS)"
      maven
    path: $(MAVEN_CACHE_FOLDER)
  displayName: Cache Maven local repo

- script: mvn install -B -e

Si vous utilisez une tâche Maven, veillez à passer également la variable MAVEN_OPTS, car sinon elle est remplacée :

- task: Maven@4
  inputs:
    mavenPomFile: 'pom.xml'
    mavenOptions: '-Xmx3072m $(MAVEN_OPTS)'

.NET/NuGet

Si vous utilisez PackageReferences pour gérer les dépendances NuGet directement dans votre fichier projet et que vous avez un fichier packages.lock.json, vous pouvez activer la mise en cache en définissant la variable d’environnement NUGET_PACKAGES sur un chemin sous $(UserProfile) et en mettant en cache ce répertoire. Pour plus d’informations sur le verrouillage des dépendances, consultez Référence de package dans les fichiers projet. Si vous voulez utiliser plusieurs packages.lock.json, vous pouvez toujours utiliser l’exemple suivant sans faire de changements. Le contenu de tous les fichiers packages.lock.json est haché et si l’un des fichiers est changé, une nouvelle clé de cache est générée.

Exemple :

variables:
  NUGET_PACKAGES: $(Pipeline.Workspace)/.nuget/packages

steps:
- task: Cache@2
  inputs:
    key: 'nuget | "$(Agent.OS)" | $(Build.SourcesDirectory)/**/packages.lock.json'
    restoreKeys: |
       nuget | "$(Agent.OS)"
       nuget
    path: $(NUGET_PACKAGES)
  displayName: Cache NuGet packages

Node.js/npm

Il existe différentes façons d’activer la mise en cache dans un projet Node.js, mais la méthode recommandée est de mettre en cache le répertoire de cache partagé de npm. Ce répertoire est géré par npm et contient une version en cache de tous les modules téléchargés. Pendant l’installation, npm recherche d’abord (par défaut) dans ce répertoire les modules qui peuvent réduire ou éliminer les appels réseau au registre npm public ou à un registre privé.

Comme le chemin par défaut du répertoire de cache partagé de npm n’est pas le même sur toutes les plateformes, nous vous recommandons de remplacer la variable d’environnement npm_config_cache par un chemin sous $(Pipeline.Workspace). Cela garantit également que le cache est accessible à partir de travaux de conteneur et non-conteneur.

Exemple :

variables:
  npm_config_cache: $(Pipeline.Workspace)/.npm

steps:
- task: Cache@2
  inputs:
    key: 'npm | "$(Agent.OS)" | package-lock.json'
    restoreKeys: |
       npm | "$(Agent.OS)"
    path: $(npm_config_cache)
  displayName: Cache npm

- script: npm ci

Si votre projet n’a pas de fichier package-lock.json, référencez plutôt le fichier package.json dans l’entrée de clé de cache.

Conseil

Parce que npm ci supprime le dossier node_modules pour qu’un ensemble cohérent et reproductible de modules soit utilisé, vous devez éviter la mise en cache de node_modules quand vous appelez npm ci.

Node.js/Yarn

Comme avec npm, il existe différentes façons de mettre en cache les packages installés avec Yarn. La méthode recommandée est de mettre en cache le dossier de cache partagé de Yarn. Ce répertoire est géré par Yarn et contient une version en cache de tous les packages téléchargés. Pendant l’installation, Yarn recherche d’abord (par défaut) dans ce répertoire les modules, ce qui peut réduire ou éliminer les appels réseau aux registres publics ou privés.

Exemple :

variables:
  YARN_CACHE_FOLDER: $(Pipeline.Workspace)/.yarn

steps:
- task: Cache@2
  inputs:
    key: 'yarn | "$(Agent.OS)" | yarn.lock'
    restoreKeys: |
       yarn | "$(Agent.OS)"
       yarn
    path: $(YARN_CACHE_FOLDER)
  displayName: Cache Yarn packages

- script: yarn --frozen-lockfile

Python/Anaconda

Configurez la mise en cache de votre pipeline avec des environnements Anaconda :

Exemple

variables:
  CONDA_CACHE_DIR: /usr/share/miniconda/envs

# Add conda to system path
steps:
- script: echo "##vso[task.prependpath]$CONDA/bin"
  displayName: Add conda to PATH

- bash: |
    sudo chown -R $(whoami):$(id -ng) $(CONDA_CACHE_DIR)
  displayName: Fix CONDA_CACHE_DIR directory permissions

- task: Cache@2
  displayName: Use cached Anaconda environment
  inputs:
    key: 'conda | "$(Agent.OS)" | environment.yml'
    restoreKeys: | 
      python | "$(Agent.OS)"
      python
    path: $(CONDA_CACHE_DIR)
    cacheHitVar: CONDA_CACHE_RESTORED

- script: conda env create --quiet --file environment.yml
  displayName: Create Anaconda environment
  condition: eq(variables.CONDA_CACHE_RESTORED, 'false')
  • Windows

    - task: Cache@2
      displayName: Cache Anaconda
      inputs:
        key: 'conda | "$(Agent.OS)" | environment.yml'
        restoreKeys: | 
          python | "$(Agent.OS)"
          python
        path: $(CONDA)/envs
        cacheHitVar: CONDA_CACHE_RESTORED
    
    - script: conda env create --quiet --file environment.yml
      displayName: Create environment
      condition: eq(variables.CONDA_CACHE_RESTORED, 'false')
    

PHP/Composer

Pour les projets PHP utilisant Composer, remplacez la COMPOSER_CACHE_DIRvariable d’environnement utilisée par Composer.

Exemple :

variables:
  COMPOSER_CACHE_DIR: $(Pipeline.Workspace)/.composer

steps:
- task: Cache@2
  inputs:
    key: 'composer | "$(Agent.OS)" | composer.lock'
    restoreKeys: |
      composer | "$(Agent.OS)"
      composer
    path: $(COMPOSER_CACHE_DIR)
  displayName: Cache composer

- script: composer install

Problèmes connus et commentaires

Si vous rencontrez des problèmes pendant la configuration de la mise en cache de votre pipeline, consultez la liste des problèmes ouverts dans le référentiel microsoft/azure-pipelines-tasks. Si vous ne voyez pas votre problème répertorié, créez-en un et fournissez les informations nécessaires à propos de votre scénario.

Questions et réponses

Q : Puis-je effacer un cache ?

R : L’effacement d’un cache n’est actuellement pas pris en charge. Toutefois, vous pouvez ajouter un littéral de chaîne (par exemple, version2) à votre clé de cache existante pour changer la clé de manière à éviter toute correspondance dans les caches existants. Par exemple, remplacez la clé de cache suivante :

key: 'yarn | "$(Agent.OS)" | yarn.lock'

par ceci :

key: 'version2 | yarn | "$(Agent.OS)" | yarn.lock'

Q : Quand un cache expire-t-il ?

R : Les caches expirent au bout de sept jours en cas d’inactivité.

Q : Quand le cache est-il chargé ?

R : Après la dernière étape de votre pipeline, un cache est créé et chargé à partir de votre cache path. Pour plus d’informations, consultez l’exemple.

Q : Existe-t-il une limite de taille du cache ?

R : Aucune limite n’est appliquée à la taille des caches individuels ou à la taille totale de tous les caches d’une organisation.