Mise en cache en Java : Redis, Memcached et solutions intégrées : de A à Z
La mise en cache est l'un des outils clés pour améliorer les performances des applications Java. Elle permet de réduire le temps de réponse, de diminuer la charge sur les bases de données et les API externes, et d'améliorer l'expérience utilisateur. Dans cet article, nous analyserons trois approches principales de la mise en cache en Java : les solutions intégrées (ConcurrentHashMap, Caffeine, Ehcache), les systèmes distribués (Redis) et les caches réseau légers (Memcached). Vous apprendrez quand et quoi choisir, et obtiendrez des exemples de code prêts à l'emploi.
Qu'est-ce que la mise en cache et pourquoi en a-t-on besoin en Java ?
La mise en cache est le stockage temporaire de données fréquemment demandées dans un stockage rapide (généralement en mémoire vive). En Java, cela est particulièrement pertinent pour :
- Réduire les latences — les données du cache sont renvoyées en microsecondes, et non en millisecondes (comme depuis la base de données).
- Diminuer la charge sur les ressources — les bases de données, les services externes et les disques travaillent moins.
- Économiser les ressources — moins d'opérations CPU et d'E/S.
Les métriques principales du cache : hit ratio (pourcentage d'accès réussis) et TTL (durée de vie d'une entrée).
Solutions intégrées : du simple au plus avancé
Pour les petits projets ou les scénarios monothread, on peut utiliser des structures de données simples. Cependant, pour les applications industrielles, les bibliothèques spécialisées sont plus adaptées.
1. ConcurrentHashMap — cache de base
La façon la plus simple est d'utiliser ConcurrentHashMap. Il est thread-safe, mais ne dispose pas de mécanismes de nettoyage automatique (TTL, éviction).
import java.util.concurrent.ConcurrentHashMap;
public class SimpleCache { private final ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>();
public void put(String key, Object value) { cache.put(key, value); }
public Object get(String key) { return cache.get(key); }
public void evict(String key) { cache.remove(key); }
public void clear() { cache.clear(); }}Avantages : simplicité, zéro dépendance.
Inconvénients : pas d'invalidation automatique, gestion manuelle de la mémoire.
2. Caffeine — cache moderne haute performance
La bibliothèque Caffeine est le standard de facto pour la mise en cache in-memory en Java. Elle prend en charge :
- L'expulsion automatique basée sur le temps (TTL) et la taille.
- Le chargement asynchrone.
- Les statistiques (hit rate, miss rate).
import com.github.benmanes.caffeine.cache.Cache;import com.github.benmanes.caffeine.cache.Caffeine;import java.util.concurrent.TimeUnit;
public class CaffeineExample { public static void main(String[] args) { Cache<String, String> cache = Caffeine.newBuilder() .expireAfterWrite(10, TimeUnit.MINUTES) .maximumSize(1000) .recordStats() // pour collecter les statistiques .build();
// Ajout cache.put("user:1", "Alice");
// Récupération avec chargement automatique String value = cache.get("user:2", key -> loadFromDB(key)); System.out.println(value); }
private static String loadFromDB(String key) { // Simulation de chargement depuis la base de données return "Bob"; }}Avantages : haute performance, flexibilité, taille réduite (environ 600 Ko).
Inconvénients : uniquement local (non distribué).
3. Ehcache — cache in-process puissant
Ehcache est une bibliothèque mature (partie d'Hibernate). Elle prend en charge :
- Le stockage sur disque (persistance).
- La clustering (via Terracotta).
Blogs
Book Recommendations
Lire aussi
Tests en JavaScript : Unit, Integration, E2E avec exemples