Java中的缓存:Redis、Caffeine、Ehcache和JCache
缓存是提升Java应用程序性能的关键工具之一。它可以缩短响应时间,减轻数据库和外部API的负载。在本文中,我们将介绍三种流行的解决方案:Redis(外部分布式缓存)、Caffeine(高性能内存缓存)和Ehcache(支持磁盘的混合缓存)。此外,我们还将探讨统一缓存操作的标准JCache(JSR 107)。
为什么在Java中需要缓存?
主要使用场景:
- 降低延迟——从缓存中获取数据只需微秒,而非毫秒(如数据库查询)。
- 减轻负载——缓存保护数据库免受重复查询的影响。
- 节省资源——减少外部服务调用次数,从而降低基础设施成本。
1. Redis——用于微服务的分布式缓存
Redis是一种内存数据存储,常被用作分布式缓存。它支持多种数据结构:字符串、哈希、列表、集合。Java有两个主要客户端:Jedis和Lettuce(推荐用于Spring Boot)。
通过Spring Data Redis连接的示例:
@Configurationpublic class RedisConfig { @Bean public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(connectionFactory); template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return template; }}
@Servicepublic class UserService { @Autowired private RedisTemplate<String, Object> redisTemplate;
public User getUserById(String id) { String key = "user:" + id; User cached = (User) redisTemplate.opsForValue().get(key); if (cached != null) return cached;
User user = database.findUserById(id); // 代价高昂的查询 redisTemplate.opsForValue().set(key, user, 10, TimeUnit.MINUTES); return user; }}Redis的优点:分布式、支持TTL、发布/订阅、持久化。缺点:网络延迟、服务器内存消耗。
2. Caffeine——超快的内存缓存
Caffeine是一个基于W-TinyLFU算法的本地缓存库。它在最小内存消耗下提供接近100%的命中率。非常适合单线程和多线程应用程序。
Caffeine使用示例:
Cache<String, User> cache = Caffeine.newBuilder() .expireAfterWrite(5, TimeUnit.MINUTES) .maximumSize(10_000) .recordStats() .build();
public User getUser(String id) { return cache.get(id, key -> database.findUserById(key));}
// 获取统计信息CacheStats stats = cache.stats();System.out.println("Hit rate: " + stats.hitRate());Caffeine的优点:极低延迟(纳秒级)、内置统计、自动淘汰旧条目。缺点:仅限本地缓存,不适用于分布式系统。
3. Ehcache——支持磁盘写入的混合缓存
Ehcache是Java最古老的缓存库之一。支持内存和磁盘缓存,并通过Terracotta实现集群。常与Hibernate一起使用。
Ehcache 3配置示例(XML):
<config xmlns:xsi="http://www.w3.org