缓存一致性、SpringCache-回顾

1、缓存的读模式:
先读取缓存中的数据,如果有返回结果,如果没有查询数据库,放入缓存中,返回结果

2、缓存的写模式:

双写模式

改了数据库的数据的时候,同时改了redis缓存中的数据
问题:A改了数据库数据,因为网络问题导致了没能及时写入缓存,而此时B改了数据库数据,立马把缓存中的数据改了,这时候A的修改的缓存数据为B的写入缓存数据之上
解决:为缓存数据设置过期时间,但会出现暂时性的脏数据问题,实现最终一致性

失效模式

改了数据库的数据的时候,把redis缓存中的数据删了,等待下次主动查询进行更新
问题:A改了数据库,执行完了,删除缓存,B也改数据库,花的时间比较长,此时C网络快,查缓存发现没数据,读取了A修改的数据库老数据,然后C要更新缓存,此时因为网络问题更新慢,此时B写完了数据库立马把缓存删了,C此时把读取A的老数据写到了缓存中,最新的数据B没能放入缓存中
解决:加锁解决(笨重)

解决方案:
无论双写还是失效都会导致缓存不一致问题
1、如果是用户纬度数据(订单数据、用户数据),这种并发几率非常小,不用考虑这个问题,缓存数据加 上过期时间,每隔一段时间触发读的主动更新即可
2、如果是菜单,商品介绍等基础数据,也可以去使用canal订阅binlog的方式。
3、缓存数据+过期时间也足够解决大部分业务对于缓存的要求。
4、通过加锁保证并发读写,写写的时候按顺序排好队。读读无所谓。所以适合使用读写锁。(业务不关心 脏数据,允许临时脏数据可忽略);

总结:

  • 我们能放入缓存的数据本就不应该是实时性、一致性要求超高的。所以缓存数据的时候加上过期时间,保 证每天拿到当前最新数据即可。
  • 遇到实时性、一致性要求高的数据,就应该查数据库,即使慢点。

SpringCache

1、整合springCache简化缓存开发
1)、引入依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

2)、写配置
(1)、自动配置了哪些
自动配好了缓存过滤器RedisCacheConfiguration
自动配好了缓存过滤器RedisCacheManager
(2)、配置redis作为缓存
(3)、测试使用缓存
1)、开启缓存功能@Enablecaching
2)、只需要使用注解就能完成缓存操作

在application.priperties配置cache

#配置缓存类型使用redis
spring.cache.type=redis
#指定缓存的名字以后缓存名字全部按配置的来,不配置的话系统中用到哪些缓存自动创建出来
spring.cache.cache-name=qq
#设置存活时间,毫秒为单位
spring.cache.redis.time-to-live=3600000
#如果指定了前缀就用我们指定的前缀,如果没有就没人使用缓存的名字作为前缀
spring.cache.redis.key-prefix=CACHE_
spring.cache.redis.use-key-prefix=false
#是否缓存空值。防止缓存穿透
spring.cache.redis.cache-null-values=true

测试使用缓存
@Cacheable:触发将数据保存到缓存的操作
@CacheEvict:触发将数据从缓存删除的操作
@CahePut:不影响方法执行更新缓存
@Caching:组合以上多个操作
@CacheConfig:在类级别共享缓存的相同配置

开启缓存
1)、开启缓存功能
开启缓存功能使用**@Enablecaching**,在启动类上加上开启
只需要使用注解就能完成缓存操作
如:
在这里插入图片描述
配置Config


import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@EnableConfigurationProperties(CacheProperties.class)
@Configuration
@EnableCaching //开启缓存
public class MyCacheConfig {


//    @Autowired
//    CacheProperties cacheProperties;

    /**
     * 配置文件中的东西没有用上:
     * 1、原来和配置文件绑定的配置类是这样子的
     *
     * 2、要让他生效
     *
     * @return
     */
    @Bean
    RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties){
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();//默认配置
//        config =config.entryTtl();
        config = config.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer()));
        config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
        CacheProperties.Redis redisProperties = cacheProperties.getRedis();
        //将配置文件中所有的配置都生效
        if (redisProperties.getTimeToLive() != null) {
            config = config.entryTtl(redisProperties.getTimeToLive());
        }
        if (redisProperties.getKeyPrefix() != null) {
            config = config.prefixKeysWith(redisProperties.getKeyPrefix());
        }
        if (!redisProperties.isCacheNullValues()) {
            config = config.disableCachingNullValues();
        }
        if (!redisProperties.isUseKeyPrefix()) {
            config = config.disableKeyPrefix();
        }

        //将配置文件中的所有配置都生效
        return config;
    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值