redis 缓存空值


redis 缓存空值

 

redis缓存空值可以在一定程度上应对高并发的场景下的缓存穿透

 

 

*********************

相关类

 

RedisCacheConfiguration

public class RedisCacheConfiguration {
    private final Duration ttl;               //过期时间
    private final boolean cacheNullValues;    //缓存空值
    private final CacheKeyPrefix keyPrefix;   //缓存键的前缀
    private final boolean usePrefix;          //是否使用前缀
    private final SerializationPair<String> keySerializationPair;
    private final SerializationPair<Object> valueSerializationPair;
    private final ConversionService conversionService;


***********
构造函数

    private RedisCacheConfiguration(Duration ttl, Boolean cacheNullValues, Boolean usePrefix, CacheKeyPrefix keyPrefix, SerializationPair<String> keySerializationPair, SerializationPair<?> valueSerializationPair, ConversionService conversionService) {
        this.ttl = ttl;
        this.cacheNullValues = cacheNullValues;
        this.usePrefix = usePrefix;
        this.keyPrefix = keyPrefix;
        this.keySerializationPair = keySerializationPair;
        this.valueSerializationPair = valueSerializationPair;
        this.conversionService = conversionService;
    }


***********
静态方法:返回RedisCacheConfiguration对象实例,默认可缓存空值

    public static RedisCacheConfiguration defaultCacheConfig() {
        return defaultCacheConfig((ClassLoader)null);
    }

    public static RedisCacheConfiguration defaultCacheConfig(@Nullable ClassLoader classLoader) {
        DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService();
        registerDefaultConverters(conversionService);
        return new RedisCacheConfiguration(Duration.ZERO, true, true, CacheKeyPrefix.simple(), SerializationPair.fromSerializer(RedisSerializer.string()), SerializationPair.fromSerializer(RedisSerializer.java(classLoader)), conversionService);
    }//返回RedisCacheConfiguration对象实例,默认可缓存空值


***********
常用方法

    public RedisCacheConfiguration entryTtl(Duration ttl) {
                                   //设置缓存过期时间

    public RedisCacheConfiguration prefixKeysWith(String prefix) {
                                   //设置缓存前缀

    public RedisCacheConfiguration disableCachingNullValues() {  //禁用缓存空值
    public RedisCacheConfiguration disableKeyPrefix() {          //禁用缓存前缀

    public RedisCacheConfiguration serializeKeysWith(SerializationPair<String> keySerializationPair) {    //设置key序列化器
    public RedisCacheConfiguration serializeValuesWith(SerializationPair<?> valueSerializationPair) {  //设置value序列化器

    public boolean usePrefix() {                 //是否使用缓存前缀
    public boolean getAllowCacheNullValues() {   //是否允许缓存空值

    public SerializationPair<String> getKeySerializationPair() {     //获取key序列化转换器
    public SerializationPair<Object> getValueSerializationPair() {   //获取value序列化转换器
    public String getKeyPrefixFor(String cacheName) {  //获取cacheName的缓存前缀

    。。。。
}

 

 

*********************

使用示例

 

**************

config 层

 

RedisCacheConfig

@Configuration
@EnableCaching
public class RedisCacheConfig {

    @Bean
    public CacheManager initCacheManager(RedisConnectionFactory connectionFactory){
        RedisCacheConfiguration cacheConfiguration= RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new JdkSerializationRedisSerializer()))
                .entryTtl(Duration.ofMinutes(2L));

        Map<String,RedisCacheConfiguration> map=new HashMap<>();
        map.put("custom",cacheConfiguration);

        return RedisCacheManager.builder(connectionFactory)
                .withInitialCacheConfigurations(map)
                .transactionAware()
                .build();
    }
}

 

**************

serviceImpl 层

 

PersonServiceImpl

@Service
public class PersonServiceImpl extends ServiceImpl<PersonMapper, Person> implements PersonService {

    @Resource
    private PersonMapper personMapper;

    @Override
    @Cacheable(value = "custom",key="'person'+#id")
    public Person getById(Integer id) {
        System.out.println("查询id为:"+id+"的person");
        return personMapper.selectById(id);
    }

    @Override
    @CachePut(value = "custom",key = "'person'+#person.id")
    public Person add(Person person) {
        personMapper.insert(person);

        return person;
    }

    @Override
    @CacheEvict(value = "custom",key = "'person'+#id")
    public void deleteById(Integer id) {
        personMapper.deleteById(id);
    }
}

 

**************

controller 层

 

PersonController

@RestController
@RequestMapping("/person")
public class PersonController {

    @Resource
    private PersonService personService;

    @RequestMapping("/add")
    public String add(){
        for (int i=0;i<100;i++){
            Person person=new Person();
            person.setName("瓜田李下"+i);
            person.setAge(10+i%10);

            personService.add(person);
        }

        return "success";
    }

    @RequestMapping("/get")
    public String get(@RequestParam("id") Integer id){
        Person person= personService.getById(id);

        if (person!=null){
            System.out.println(person);
            return person.toString();
        }else {
            System.out.println("查找的id为:"+id+" 的person不存在");
            return "查找的id为:"+id+" 的person不存在";
        }
    }

    @RequestMapping("/delete")
    public String delete(Integer id){
        personService.deleteById(id);

        return "success";
    }
}

 

 

*********************

使用测试

 

查询id为:2的person
Person(id=2, name=瓜田李下1, age=11)
Person(id=2, name=瓜田李下1, age=11)
查询id为:400的person
查找的id为:400 的person不存在
查找的id为:400 的person不存在

说明:后端数据库不存在id为400的person,首次查询到后端数据库查询,再次查询时由于缓存了空值,没到后端数据库查询

 

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Redis 缓存的实现需要以下步骤: 1. 安装 Redis:首先需要在你的系统上安装 Redis 服务器。 2. 连接到 Redis:使用 Redis 客户端连接到 Redis 服务器。 3. 将数据存入 Redis:使用 Redis 客户端操作将数据存入 Redis 服务器。 4. 获取数据:使用 Redis 客户端操作从 Redis 服务器获取数据。 5. 设置缓存过期时间:可以为存储在 Redis 中的数据设置过期时间,以便在数据过期后将其从 Redis 中删除。 这些步骤可以使用各种语言的 Redis 客户端库来实现,例如 Java、Python、Ruby 等。 ### 回答2: Redis(Remote Dictionary Server)是一种使用内存存储的开源缓存数据库,它支持各种数据结构,并提供了高性能的读写操作。 实现Redis缓存可以通过以下步骤: 1. 安装:首先,在服务器上安装Redis。可以下载官方的Redis安装包,然后根据官方文档进行安装和配置。 2. 连接:使用代码连接Redis服务器。可以选择不同的编程语言,如Java、Python等。通过连接操作可以实现与Redis服务器的通信。 3. 存储数据:使用SET命令将数据存储到Redis中。可以将数据作为键对存储,例如:使用一个字符串作为键,将某个对象序列化为字符串后作为存储到Redis中。 4. 获取数据:使用GET命令从Redis中获取数据。根据键名获取对应的,并对进行反序列化,以获得原始数据。 5. 过期和失效:可以为存储的键对设置过期时间,使其在一定时间后自动过期。通过设置过期时间,可以实现自动清理过期数据的功能。当数据过期后,再次获取对应的键对时会返回。 6. 缓存更新策略:在应用程序中,根据不同的业务需求,可以选择合适的缓存更新策略。例如,可以设置当某个键对更新时,自动更新Redis中对应的数据。 7. 集群和分片:当需要支持更大的数据量或更高的并发访问时,可以考虑使用Redis的集群和分片功能。通过将数据分片或分布在多个节点上,可以提高系统的性能和可靠性。 总结来说,实现Redis缓存需要安装Redis服务器,使用代码连接服务器进行数据存储和获取,设置过期时间,选择适当的缓存更新策略等。通过合理使用Redis缓存,可以提升系统性能和响应速度。 ### 回答3: Redis是一种常见的高性能缓存数据库,它具有快速读写能力和灵活的数据结构,可以有效地加速应用程序的访问速度。下面是关于如何实现Redis缓存的一些步骤和方法。 首先,需要在应用程序中引入Redis客户端库。Java语言中,可以使用Jedis或Lettuce等库来操作Redis。在项目中添加相关的依赖项,并配置连接Redis服务器的参数。 接着,需要确定要缓存的数据。通常来说,缓存的数据可以是经常读取但是不经常变化的数据,比如配置信息、用户信息、常用查询结果等。将这些数据存储到Redis中,可以避免每次请求都访问繁重的数据库。 然后,通过Redis的API来存储和访问数据。可以使用键对的方式存储数据,并设置生存时间,使得数据在一定时间后自动过期。这样,可以有效地管理内存和释放不再需要的数据。 在进行数据库读取之前,首先检查Redis缓存中是否存在所需的数据。通过检查数据的键是否存在,可以避免不必要的数据库查询。如果缓存中无数据,再从数据库中读取,并将结果存储到缓存中。 除了简单的键对存储之外,Redis还支持其他的数据结构,比如列表、哈希表、集合和有序集合等。根据不同的场景,可以选择合适的数据结构来存储数据,并利用Redis提供的操作方法,实现更复杂的缓存需求。 最后,需要在应用程序中正确处理数据更新和删除的操作。当数据库中的数据发生变化时,需要及时更新Redis缓存中相应的数据,以保证数据的一致性。可以在数据更新和删除操作后,强制删除Redis中的缓存数据,以便下一次访问时重新从数据库中获取最新的数据。 总而言之,实现Redis缓存需要引入Redis客户端库,确定要缓存的数据,使用Redis的API存储和访问数据,选择合适的数据结构,处理数据更新和删除操作。通过合理地使用Redis缓存,可以提升应用程序的性能和响应速度。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值