当前位置: 首页 > 知识库问答 >
问题:

Spring Boot缓存注释在使用Redis进行缓存的应用程序中扮演什么角色?

艾仲渊
2023-03-14

我使用Redis作为内存中的数据存储,用于spring boot应用程序中的缓存目的。目前,我已经为我需要缓存的实体实现了基本CRUD功能的Redis支持[Scenario 1]。但突然间,我发现有很多资源使用额外的Spring Boot缓存注释,比如@Cachable@CahceEvict来实现Redis的缓存[Scenario 2]。我监控到,当我们开始在find(params)这样的操作中使用这些注释时,只有第一个方法调用会被调用到Redis。从第二种方法开始,Redis就不会被击中。所以根据我的观察,我认为Spring boot有一个单独的缓存。但我的问题是,我们已经在使用Redis作为缓存。那么,停止第二次Redis数据存储命中并维护另一个缓存有什么好处呢。我的意思是Redis已经在RAM中了,而且它具有很强的缓存能力。为什么我们需要保留两个缓存?拥有这种机制有什么好处吗?或者只实现Redis就足够了吗?。

情景1:

public class RestController{

@GetMapping("/{id}")
public Product findProductById(@PathVariable int Id){
           return dao.findProductById(id);
}


}
@Repository
public class ProductDao {

    public static final String HASH_KEY = "Product";

    @Autowired
    private RedisTemplate template;
  

    public Product findProductById(int id){
        return (Product) template.opsForHash().get(HASH_KEY,id);
    }

}

情景2:

public class RestController{

@GetMapping("/{id}")
@Cachable(key = "#id" ,value="Product")
public Product findProductById(@PathVariable int Id){
           return dao.findProductById(id);
}

}
@Repository
public class ProductDao {

    public static final String HASH_KEY = "Product";

    @Autowired
    private RedisTemplate template;
  

    public Product findProductById(int id){
        System.out.println("called findProductById() from DB");//Here only for the first time method will be called
        return (Product) template.opsForHash().get(HASH_KEY,id);
    }

}

实施方案1的参考资料

场景2实现的参考资料

共有1个答案

柯唯
2023-03-14

Spring缓存抽象提供了一个缓存抽象层,您可以配置它来支持不同的、可插拔的底层缓存机制,包括通过Spring数据的Redis。

您正在使用Redis作为实际的持久性机制。因此,您可能不需要任何缓存,并且由于Redis数据库的内存性质,场景1可能是合适的。

话虽如此,请考虑一个不同的观点。

让我们考虑一个后端,它使用一个具有底层非内存数据库、关系或NoSQL的其他味道的持久层。

这是Spring Cache、@Cacheable和其他相关注释的完美用例,可以有效地缓存结果。

那么,Redis如何适应这个难题?因为您将Spring配置为使用Redis作为实际的缓存管理器。例如:

@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
    return RedisCacheManager.create(connectionFactory);
}

在引擎盖下,RedisCacheManager将提供必要的机制,以便根据应用程序缓存的要求透明地从Redis写入和读取。

有了这个新观点,具有上述差异的场景2是可以选择的,事实上是您在构建企业应用程序时通常会发现的一个常见场景。

在任何情况下,您问题中描述的场景2,我的意思是,除了Spring Cache之外,直接使用Redis作为持久性机制,如果您正在尝试:

  • 减少针对Redis执行的请求数量和相关成本。如果您在云提供商中使用Redis(或类似Redis的服务,如GCP Memorystore),这可能是相关的。
  • 尽管Redis足够快,但您可以使用缓存将结果存储在运行应用程序的机器的本地内存中,以提高性能,就像任何其他数据库系统一样。
  • 或者因为你需要以某种特定的方式与Redis互动。

如果您仅将Redis用于缓存,并且不需要任何特定的东西,那么可能最好通过Spring Cache抽象来使用它,而不是手动执行缓存操作:它不会提供性能优势,但您将获得几个优势,如一个结构良好的缓存框架,具有一组有用的注释和可移植性/可用性,因为您可以在需要时仅使用不同的配置来切换缓存实现,例如用于测试或本地开发。

 类似资料:
  • jboss网站。xml 独立的。xml 网状物xml(摘录) 登录servlet。java(与doPost(…)相同) 我有一个自定义验证器,它扩展了DatabaseServerLoginModule,并覆盖createPasswordHash方法以确保其自身的安全性。 我的问题是,当我使用经理角色登录并使用其他浏览器更改登录用户的角色时,它会缓存该用户的角色。只有当我注销用户并再次登录时,他才能

  • 我的情况是,我有Grails 2.1.2应用程序,并希望引入使用缓存插件和cache-ehcache插件作为实现的方法级缓存。 我的缓存配置为在内存中,如下所示: 我有一个像这样的方法,它只接受int参数,所以密钥生成不是问题: 我的问题是,当调用这个方法时,我得到了一个< code > Java . lang . out of memory error:Java heap space 异常。原因

  • 问题内容: 我想在python中创建一个redis缓存,作为任何自尊的科学家,我都做了一个基准测试性能。 有趣的是,redis的表现并不那么好。Python做一些不可思议的事情(存储文件),或者我的redis版本太慢了。 我不知道这是否是因为我的代码的结构方式或原因,但是我希望redis比它做得更好。 为了进行Redis缓存,我将二进制数据(在本例中为HTML页面)设置为从文件名派生的密钥,有效期

  • 问题内容: 我最近看到很多人使用Redis作为缓存,为什么不使用Mongo?据我所知,Redis可以在诸如memcache之类的索引上设置过期日期,但是是否有任何理由不使用Mongo? 我问,因为我在MySQL中进行大型联接,然后在选择后更改数据。我已经在网站的其他部分上使用了内存缓存,但是将其保存在Mongo中将使我能够对缓存的数据进行地理空间搜索。 问题答案: 很多人的确将MongoDB用于中

  • 我了解到,使用服务工作者进行脱机缓存与浏览器缓存类似。如果是这样的话,那么为什么您希望使用服务工作者进行此缓存?浏览器缓存将检查文件是否被修改,然后从缓存中提供服务,通过服务工作者,我们将从代码中处理相同的事情。默认情况下,浏览器具有该功能,那么为什么更喜欢服务人员呢?

  • 本文向大家介绍SpringBoot使用Redis缓存的实现方法,包括了SpringBoot使用Redis缓存的实现方法的使用技巧和注意事项,需要的朋友参考一下 (1)pom.xml引入jar包,如下:   (2)修改项目启动类,增加注解@EnableCaching,开启缓存功能,如下:   (3)application.properties中配置Redis连接信息,如下:   (4)新建Redis