Performance & Cache — Redis, Caffeine, Ehcache, Hazelcast & Tuning Hibernate
Optimisations avancées : caches locaux & distribués, patterns de cache, invalidation, tuning Hibernate, optimisation SQL, parallélisme et réduction de la charge serveur.
Introduction
La performance dans Spring Boot repose sur trois piliers principaux : réduction des accès à la base, cache intelligent et optimisation Hibernate. Les solutions de cache modernes — Redis, Caffeine, Ehcache et Hazelcast — permettent de réduire jusqu’à 90% de la charge sur les bases relationnelles.
Ce chapitre couvre les approches locales, distribuées, hybrides, les patterns de cache, l’invalidation, le replication mode, les clusters Hazelcast et les optimisations majeures d’Hibernate.
Lexique essentiel
Cache local ultra rapide (nanosecondes) basé sur LRU + Window TinyLFU.
Cache distribué en mémoire, clusterisable, persistant et ultra performant.
Cache local ou distribué, support Java niveau entreprise, tiers mature.
Plateforme in-memory distribuée, clusterisée, haute disponibilité + compute grid.
Cache des entités et queries pour réduire les hits SQL.
Lecture → cache ; mise à jour → invalidation + update base.
1. Cache local ultra rapide — Caffeine (L1 Cache)
Caffeine est le cache Java le plus performant du marché. Idéal pour : données légères, lookup rapides, résultats prévisibles, opérations millisecondes → nanosecondes.
Configuration Caffeine
@Bean
public CaffeineCacheManager cacheManager() {
CaffeineCacheManager manager = new CaffeineCacheManager();
manager.setCaffeine(Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES)
.maximumSize(10_000));
return manager;
}
Utilisation
@Cacheable("products")
public Product findProduct(String id) {
return repository.findById(id).orElseThrow();
}
- Données légères, non critiques, haute fréquence.
- Cache très court (1–10 minutes).
- Microservices avec faible latence.
2. Cache distribué — Redis (L2 Cache)
Redis est utilisé dans 80% des architectures distribuées. Haute performance, faible latence, support cluster, TTL, clés structurées, Bloom filters et capacités avancées.
Configuration Redis
spring.cache.type=redis
spring.data.redis.host=localhost
spring.data.redis.port=6379
Annotation exemple
@Cacheable(value = "customer", key = "#id")
public Customer findCustomer(String id) {
return repo.findById(id).orElseThrow();
}
Invalidation
@CacheEvict(value = "customer", key = "#customer.id")
public void updateCustomer(Customer customer) {
repo.save(customer);
}
- Applications distribuées.
- Flux de haute charge.
- TTL strict et patterns d’invalidation.
- Sessions, tokens, quotas.
3. Ehcache — cache mature & performant (local ou distribué)
Ehcache est un moteur historique, très stable, utilisé dans les environnements Java depuis des années. Bon compromis pour un cache durable et configurable.
Configuration
@Bean
public JCacheManagerCustomizer cacheCustomizer() {
return cm -> cm.createCache("orders",
new MutableConfiguration<>()
.setExpiryPolicyFactory(CreatedExpiryPolicy.factoryOf(Duration.TEN_MINUTES))
.setStoreByValue(false)
);
}
Ehcache est recommandé pour les systèmes monolithiques ou des microservices moyens.
4. Hazelcast — In-Memory Data Grid (IMDG) & Cache Distribué
Hazelcast est la solution la plus avancée de ce chapitre : cache distribué clusterisé, haute disponibilité, réplication, compute in-memory, near-cache, map distributed, topic/event bus.
Hazelcast convient aux systèmes haute disponibilité, clusters Kubernetes, microservices distribués et calculs massifs in-memory.
Configuration Hazelcast cluster
@Bean
public Config hazelcastConfig() {
Config config = new Config();
config.getNetworkConfig()
.getJoin()
.getMulticastConfig()
.setEnabled(true);
config.getMapConfig("products")
.setTimeToLiveSeconds(600)
.setBackupCount(2);
return config;
}
Utilisation
@Cacheable("products")
public Product getProduct(String id) {
return repository.findById(id).orElseThrow();
}
Near-cache (accélération x100)
MapConfig mapConfig = new MapConfig("products");
mapConfig.setNearCacheConfig(new NearCacheConfig());
👉 Le near-cache stocke localement les objets les plus demandés → latence réduite → hit-ratio maximal.
- Clusters multi-instances → besoin de synchronisation.
- Microservices à forte charge.
- Calcul distribué ou transformation en mémoire.
- Alternatives à Redis avec réplication interne.
5. Tuning Hibernate — réduire les requêtes & optimiser les performances
Activer le 2nd Level Cache
spring.jpa.properties.hibernate.cache.use_second_level_cache=true
spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.jcache.JCacheRegionFactory
Optimiser Lazy Loading
@OneToMany(fetch = FetchType.LAZY)
Avoid N+1 queries
@Query("SELECT o FROM Order o JOIN FETCH o.items WHERE o.id = :id")
Batch Fetching
spring.jpa.properties.hibernate.default_batch_fetch_size=50
- Batch fetching pour éviter N+1.
- Cache 2e niveau + queries cache quand pertinent.
- Éviter les relations EAGER.
- Utiliser Redis/Hazelcast pour les entités fréquemment lues.
Quiz : Performance & Cache
-
Q1. Quel cache est le plus rapide ?
- A. Redis
- B. Caffeine ✔
- C. Hazelcast
-
Q2. Quel outil est le plus adapté pour un cluster distribué ?
- A. Caffeine
- B. Ehcache
- C. Hazelcast ✔
Exercice d’application
Implémentez un cache multi-niveaux :
— Caffeine L1
— Hazelcast ou Redis L2
— TTL intelligent
— Invalidation métier
— Monitoring des hits/miss + tuning Hibernate
Résumé
La performance Spring Boot repose sur un cache bien conçu : Caffeine pour la rapidité locale, Redis pour la distribution, Ehcache pour la maturité, Hazelcast pour la haute disponibilité et un tuning Hibernate maîtrisé. Une stratégie multi-niveaux garantit un système rapide, stable et scalable.
