java—在使用redis进行缓存的应用程序中,SpringBootCache注解的作用是什么?

uqjltbpv  于 2021-07-13  发布在  Java
关注(0)|答案(1)|浏览(301)

我使用redis作为内存中的数据存储,以便在spring引导应用程序中进行缓存。目前,我已经为我需要缓存的实体实现了redis支持的基本crud功能[场景1]。但是突然我发现有很多资源使用了额外的spring引导缓存注解,比如 @Cachable @CahceEvict 使用redis实现缓存[场景2]。我监测到,当我们开始在find(params)这样的操作中使用这些注解时,只有第一个方法调用将被发送到redis。从第二种方法开始,redis就不会被击中。所以根据我的观察,我认为springboot有一个单独的缓存。但我的问题是我们已经在使用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实现的参考

ssm49v7z

ssm49v7z1#

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进行读写。
从这个新的Angular 来看,场景2与上面提到的不同之处是可以选择的,事实上,这是在构建企业应用程序时通常会遇到的常见场景。
在任何情况下,您的问题中描述的场景2,我的意思是,除了spring cache之外,直接使用redis作为持久性机制,如果您正在尝试:
减少针对redis执行的请求数量和相关成本。这可能与云提供商中使用redis(或类似redis的服务,如gcp memorystore)有关。
尽管redis足够快,但您可以使用缓存将结果存储在运行应用程序的计算机的本地ram中,以提高性能,就像其他任何数据库系统一样。
或者因为你需要以某种特定的方式与redis交互。
如果您仅将redis用于缓存,并且不需要任何特定的东西,那么最好通过spring缓存抽象来使用它,而不是手动执行缓存操作:它不会带来性能方面的好处,但是您会获得一些优势,比如结构良好的缓存框架,具有一组有用的注解和可移植性/可用性,因为您可以仅在需要时使用不同的配置来切换缓存实现,例如用于测试或本地开发。

相关问题