我有一个 spring boot 2.7.3 应用程序,它使用 hibernate、hazelcast 作为二级缓存工厂、mysql。我的目标是使用二级缓存来查找所有查询并使查询更快。 数据库中有大约 5012 个实体用于开发目的。
我面临的问题是,当我第一次运行 findAll 方法时,它会从数据库中获取每个实体并将它们放入二级缓存。然而,在第二次查询后,它只命中了其中的 30 个,并再次将丢失的数据放入缓存。因此,这个放置过程需要大量时间并且系统速度变慢。当我关闭二级缓存时,很有趣,但系统运行得更快。
我的application.yml文件:
properties:
hibernate.jdbc.time_zone: UTC
hibernate.id.new_generator_mappings: true
hibernate.connection.provider_disables_autocommit: true
hibernate.cache.use_second_level_cache: true
hibernate.cache.use_query_cache: false
hibernate.generate_statistics: false
# modify batch size as necessary
hibernate.jdbc.batch_size: 25
hibernate.order_inserts: true
hibernate.order_updates: true
hibernate.query.fail_on_pagination_over_collection_fetch: true
hibernate.query.in_clause_parameter_padding: true
hibernate.cache.region.factory_class: com.hazelcast.hibernate.HazelcastCacheRegionFactory
我向实体类添加了
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
的注释以使其可缓存。
我的 Hazelcast 配置:
@Bean
public Config hazelcastConfig() {
Config config = new Config();
config.setInstanceName("placeholder");
MapConfig mapConfig = new MapConfig("default");
mapConfig.setBackupCount(1);
mapConfig.getEvictionConfig().setEvictionPolicy(EvictionPolicy.LRU);
mapConfig.getEvictionConfig().setMaxSizePolicy(MaxSizePolicy.USED_HEAP_SIZE);
mapConfig.setTimeToLiveSeconds(3600);
config.addMapConfig(mapConfig);
return Hazelcast.newHazelcastInstance(config);
}
我有一个非常基本的查找所有方法:
public List<SinkSourceAddDTO> findAll() {
return HouseRepository.findAll()
.stream().map(HouseAddMapper::toDto)
.collect(Collectors.toCollection(LinkedList::new));
}
会话指标: 第一个方法调用:
Session Metrics {
1968100 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
41430100 nanoseconds spent preparing 32 JDBC statements;
52658900 nanoseconds spent executing 32 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
2712459300 nanoseconds spent performing 5012 L2C puts;
0 nanoseconds spent performing 0 L2C hits;
8894900 nanoseconds spent performing 30 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
97100 nanoseconds spent executing 2 partial-flushes (flushing a total of 0 entities and 0 collections)
}
将 5012 个条目放入缓存。
第二、第三等方法调用:
Session Metrics {
290100 nanoseconds spent acquiring 1 JDBC connections;
0 nanoseconds spent releasing 0 JDBC connections;
111100 nanoseconds spent preparing 2 JDBC statements;
14781000 nanoseconds spent executing 2 JDBC statements;
0 nanoseconds spent executing 0 JDBC batches;
1450759900 nanoseconds spent performing 4982 L2C puts;
9978700 nanoseconds spent performing 30 L2C hits;
0 nanoseconds spent performing 0 L2C misses;
0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
11100 nanoseconds spent executing 2 partial-flushes (flushing a total of 0 entities and 0 collections)
}
仅命中其中 30 个并将剩余内容放入缓存,这需要 1.4 秒才能完成。
我尝试了很多方法,例如迁移 EhCache、增加缓存大小、增加生存时间、机会驱逐策略等,但没有一个有效并解决问题。
此答案旨在为您的问题提供一些指导。我知道这不是一个直接的答案,因为在没有看到你的环境的情况下不可能说出一些话
从你的日志我们大概可以推断出这一点