jetcache缓存

1 介绍

 是阿里的双极缓存,jvm-->redis-->数据库

文档:jetcache/docs/CN at master · alibaba/jetcache · GitHub

2 注意事项

  1.  使用的实体类一定实现序列化接口
  2. 定时刷新注解,慎用 它会为每一个key创建一个定时器 :场景为:key少,访问量大
  3. 注解泛型一定和方法泛型保持一致,否则报错
  4. expire:过期时间设置为-1或者不设置 过期时间68年左右。

  5. put入参key是null不会存数据,get入参为null,会报空指针。空字符串没有任务问题。使用缓存时我们要多封装一层,判断key为空时情况

  6. 版本

3 总结

 缓存类型为BOTH时:

查询流程:

单机:本地缓存默认是100条数据(初始化数据时,留后查询的数据),redis留所有数据。本地缓存查询不到时,去redis找,保存到本地缓存,同时也去除一条本地缓存数据。

集群:第一次访问服务器A时,流程同上述一样,第二次访问服务器B时,直接去redis找,保存到本地缓存。

删除api:本地和redis都会删除数据

4  实战

   4.1 pom

        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.30</version>
        </dependency>

        <dependency>
            <groupId>com.alicp.jetcache</groupId>
            <artifactId>jetcache-starter-redis</artifactId>
            <version>2.7.0</version>
        </dependency>

        <!--        jetcache2.7.x版本需要额外添加该依赖-->
        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>4.3.1</version>
        </dependency>
        <!-- json数据工具 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>

   4.2 启动类:

@EnableMethodCache(basePackages="com.example.jetcache.mapper")
//如果不用@CreateCache注解可以删除 EnableCreateCacheAnnotation
@EnableCreateCacheAnnotation

 4.3 配置文件

jetcache:
  ## 统计间隔,默认值0,0表示不统计,开启后定期在控制台输出缓存信息
  statIntervalMinutes: 15
  ## 默认值false, 是否将 areaName 作为远程缓存key前缀
  areaInCacheName: false
  ## 本地缓存配置
  local:
    default: ## default表示全部生效,也可以指定某个cacheName
      ## 本地缓存类型,其他可选:caffeine/linkedhashmap
      type: caffeine
      # 指定KEY的转换方式, 可选 fastjson2,fastjson,jackson
      keyConvertor: fastjson
  ## 远程缓存配置
  remote:
    default: ## default表示全部生效,也可以指定某个cacheName
      type: redis
      ## key转换器方式n
      keyConvertor: fastjson
      broadcastChannel: projectA
      ## redis序列化方式
      valueEncoder: java
      valueDecoder: java
      ## redis线程池
      poolConfig:
        minIdle: 5
        maxIdle: 20
        maxTotal: 50
      ## redis地址与端口
      host: 127.0.0.1
      port: 6379

4.4 基础查询/删除/更新/定时刷新(慎用)

import com.alicp.jetcache.anno.*;
import com.example.jetcache.entity.User;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Mapper
public interface UserMapper {

    List<User> queryUserAll();

    List<User> queryUser(User user);

    /**
     * BOTH类型查询
     * expire 过期时间,redis和本地缓存一致
     * 重启服务,本地jvm消失,会先查询redis,然后存入本地缓存
     * 本地缓存存在,不会查询redis
     *
     *
     * @param id
     * @return
     */
    @Cached(name="userCache:", key="#id", expire = 15 ,cacheType = CacheType.BOTH)
    /**
     * 只要是查询过的数据,就会定时刷新,从未查询过,则无定时刷新
     * refresh: 定时器执行查询间隔时间-每过36秒就会执行一次定时器
     * stopRefreshAfterLastAccess: 表示多久不使用对应的key缓存则会停止刷新。,如果不指定会一直刷新
refreshLockTimeout:类型为BOTH/REMOTE的缓存刷新时,同时只会有一台服务器在刷新,这台服务器会在远程缓存放置一个分布式锁,此配置指定该锁的超时时间
       */
    @CacheRefresh(refresh = 36, stopRefreshAfterLastAccess = 3600, timeUnit = TimeUnit.SECONDS)
    /**
     * 注解作用——当缓存访问【未命中】的情况下,对并发进行的加载行为进行保护;当前版本实现的是单JVM内的保护,即同一个JVM中同一个key只有一个线程去加载,其它线程等待结果
     */
    @CachePenetrationProtect
    List<User> queryUserById(String id);

    /**
     * 删除
     * @param id
     * @return
     */
    @CacheInvalidate(name="userCache.", key="#id")
    int delById(int id);

    @CacheUpdate(name="userCache.", key="#user.id", value="#user")
    int save(User user);

}

 4.5 CreateCache

          //无则新增,有则覆盖
         userCache.put(id,users);
         //删除
         userCache.remove(id);

       //删除所有数据暂无api

      

 方式一:废弃了

    @CreateCache(name= "userCache:", expire = 3600,cacheType = CacheType.BOTH)
    private Cache<String, List<User>> userCache;

    @PostMapping(value = "/queryUserById")
    public List<User> queryUserById(@RequestParam String id)  {
        if(CollectionUtil.isNotEmpty(userCache.get(id) )){
            return  userCache.get(id);
        }
        List<User> users = userMapper.queryUserById(id);
       //无则新增,有则覆盖
        userCache.put(id,users);
        return users;
    }

方式二:spring注入直接使用,如上图使用API

   @Autowired
    private Cache<Long, Object> userCache;

@Configuration
public class JetCacheConfig {

    @Autowired
    private CacheManager cacheManager;
    private Cache<String, List<User>> userCache;
    @Resource(name = "userMapper")
    private UserMapper userMapper;
    @PostConstruct
    public void init(){
        QuickConfig qc = QuickConfig.newBuilder("userCache:")
            .expire(Duration.ofSeconds(3600))
            .cacheType(CacheType.BOTH)
            //true 集群模式下,任何本地缓存都会强制删除缓存,fasle,则请求到哪个服务,哪个服务删除本地缓存,其他服务本地缓存保持不变
            // 本地缓存更新后,将在所有的节点中删除缓存,以保持强一致性
            // 两级缓存的情况下,缓存更新时发消息让其它JVM实例中的缓存失效,需要配置broadcastChannel才生效
            .syncLocal(true)
            // 默认100 后面数据会挤掉前面的数据  本地缓存元素个数限制,只对CacheType.LOCAL和CacheType.BOTH有效
            .localLimit(100)
           //不存在时则执行这个方法
            .loader(this::loadOrderSumFromDatabase)

            //newPolicy: 定时器执行查询间隔时间
            // stopRefreshAfterLastAccess:表示多久不使用对应的key缓存则会停止刷新。
          //  .refreshPolicy(RefreshPolicy.newPolicy(6, TimeUnit.SECONDS).stopRefreshAfterLastAccess(10, TimeUnit.SECONDS))
             //cache穿透保护注释表示缓存将在多线程环境中同步加载。
            .penetrationProtect(true)
            .build();
        userCache = cacheManager.getOrCreateCache(qc);
        //查询数据库,初始化全部数据
       // userCache.putAll();
    }

    private List<User> loadOrderSumFromDatabase(String id) {
        return userMapper.queryUserById(id);
    }

    @Bean
    public Cache<String, List<User>> getUserCache(){
        return userCache;
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值