caffeine 一级缓存

caffeine 比较redis 优势

Redis 这种 NoSql 作为缓存组件,它能够很好的作为分布式缓存组件提供多个服务间的缓存,但是 Redis 这种还是需要网络开销,增加时耗。本地缓存是直接从本地内存中读取,没有网络开销,例如秒杀系统或者数据量小的缓存等,比远程缓存更合适.

Caffeine 是基于 JAVA 8 的高性能缓存库。并且在 spring5 (springboot 2.x) 后,spring 官方放弃了 Guava,而使用了性能更优秀的 Caffeine 作为默认缓存组件。

springboot 使用caffeine作为一级缓存,redis作为 二级缓存,流程图
示例
java 复制代码
		<!-- 一级缓存,效率:caffeine > guava > redis -->
        <dependency>
            <groupId>com.github.ben-manes.caffeine</groupId>
            <artifactId>caffeine</artifactId>
            <version>2.8.0</version>
        </dependency>
java 复制代码
配置类
import com.github.benmanes.caffeine.cache.Cache;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.TimeUnit;

@Configuration
public class Caffeine {
    @Bean
    public Cache<String, Object> caffeineCache() {
        return com.github.benmanes.caffeine.cache.Caffeine.newBuilder()
                // 设置每个key的过期时间
                .expireAfterWrite(60, TimeUnit.SECONDS)
                // 初始的缓存空间大小(键值对的数量,而不是内存大小)
                .initialCapacity(100)
                // 缓存的最大条数
                .maximumSize(1000)
                .build();
    }
}
java 复制代码
工具类
import com.github.benmanes.caffeine.cache.Cache;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

@Component
public class CaffeineUtils<T> {

    @Resource
    Cache<String, Object> caffeineCache;


    // 添加缓存
    public void put(String key, Object value){
        // 添加一级缓存
        caffeineCache.put(key,value);

    }
    // 获取数据
    public T get(String key){
        T info = (T) caffeineCache.asMap().get(key);
        return info;
    }


    // 判断缓存是否存在
    public boolean exist(String key){
        Object ifPresent = caffeineCache.getIfPresent(key);
        // 非空 true
        return !ObjectUtils.isEmpty(ifPresent);
    }

    // 移除数据
    public void remove(String key){
        caffeineCache.asMap().remove(key);
    }
}
java 复制代码
使用

import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;

@RestController
public class FirstCacheController {
    @Resource
    CaffeineUtils firstAndSecondCache;
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    // 添加缓存
    @RequestMapping("addCache")
    public void addFirstCache(String key){
        Map<String,Object> map = new HashMap<>();
        map.put("a","1");
        // 一级缓存
        firstAndSecondCache.put(key,map);
        // 二级缓存
        redisTemplate.opsForHash().putAll(key, map);
    }

    // 缓存是否存在
    @RequestMapping("existFirstCache")
    public void existFirstCache(String key){
        System.out.println(firstAndSecondCache.exist(key));
    }

    // 获取缓存数据
    @RequestMapping("getFirstCache")
    public Object getFirstCache(String key){
        Object o;
        //1. 一级缓存存在,返回数据
        if(firstAndSecondCache.exist(key)){
             o = firstAndSecondCache.get(key);
             return o;
        }
        //2. 一级缓存不存在,判断二级缓存是否存在
        if(redisTemplate.hasKey(key)){
            // 二级缓存数据存在
            o = redisTemplate.opsForHash().entries(key);
            // 将二级缓存数据同步给一级缓存
            firstAndSecondCache.put(key,o);
            return o;
        }
        //3. 一级缓存不存在,二级缓存也不存在
        //3.1 数据源 Mysql 中取数据 ,此处模拟。
        if(true){
            Map<String,Object> map = new HashMap<>();
            map.put("a",2);
            o = map;
            //3.2 将数据缓到 二级缓存 AND 一级缓存
            redisTemplate.opsForHash().putAll(key, map);
            firstAndSecondCache.put(key,map);

        }
        return o;
    }
    
    //移除缓存
    @RequestMapping("deleteFirstCache")
    public void deleteFirstCache(String key){
        firstAndSecondCache.remove(key);
        redisTemplate.delete(key);
    }
}
相关推荐
菠萝咕噜肉i27 分钟前
超详细:Redis分布式锁
数据库·redis·分布式·缓存·分布式锁
只因在人海中多看了你一眼4 小时前
分布式缓存 + 数据存储 + 消息队列知识体系
分布式·缓存
Dlwyz5 小时前
redis-击穿、穿透、雪崩
数据库·redis·缓存
Oak Zhang10 小时前
sharding-jdbc自定义分片算法,表对应关系存储在mysql中,缓存到redis或者本地
redis·mysql·缓存
门牙咬脆骨10 小时前
【Redis】redis缓存击穿,缓存雪崩,缓存穿透
数据库·redis·缓存
门牙咬脆骨10 小时前
【Redis】GEO数据结构
数据库·redis·缓存
Dlwyz15 小时前
问题: redis-高并发场景下如何保证缓存数据与数据库的最终一致性
数据库·redis·缓存
吴半杯17 小时前
Redis-monitor安装与配置
数据库·redis·缓存
ö Constancy18 小时前
设计LRU缓存
c++·算法·缓存
小王码农记18 小时前
vue中路由缓存
前端·vue.js·缓存·typescript·anti-design-vue