关于guava cache实现本地热点缓存

我们栖息的桌子飘向麦地
我们安坐的灯火涌向星辰

某些热点数据在短时间内可能会被成千上万次访问,在使用Redis作为缓存的前面可以使用本地缓存(JAVA虚拟机JVM缓存)作为一级缓存,把数据放到本地内存,减少服务端到Redis取数据的网络开销,减少RedisServer压力,进一步提高性能。

本次场景是秒杀模块使用缓存对不可变的商品信息等进行预热。

我们可以使用google的guava cache组件实现本地缓存,之所以选择guava是因为它可以控制key和value的大小和超时时间,可以配置LRU策略且guava是线程安全的。

<dependency>
  <groupId>com.google.guava</groupId>
  <artifactId>guava</artifactId>
  <version>18.0</version>
</dependency>
public interface CacheService {
     

    //存方法
    void setCommonCache(String key,Object value);
    //取方法
    Object getFromCommonCache(String key);
    //清除指定缓存
    void removeCommonCache(String key);
    //清除所有缓存
    void removeAllCommonCache();
    //清除多个缓存
    void removeAssignCommonCache(String... keys);
}
@Service
public class CacheServerImpl implements CacheService {
     

    private Cache<String, Object> commonCache = null;

    //@PostConstruct---Spring会在bean加载的时候执行这个方法
    @PostConstruct
    public void init() {
     
        commonCache = CacheBuilder.newBuilder()
                //设置缓存容量的初始容量为10
                .initialCapacity(10)
                //设置缓存中最大可以存储100个key,超过100个之后会按照LRU的策略移除缓存项
                .maximumSize(100)
                //设置写缓存后多少秒过期
                .expireAfterWrite(60, TimeUnit.SECONDS).build();
    }

    @Override
    public void setCommonCache(String key, Object value) {
     
        commonCache.put(key, value);
    }

    @Override
    public Object getFromCommonCache(String key) {
     
        //存在返回,不存在返回null
        return commonCache.getIfPresent(key);
    }

    @Override
    public void removeCommonCache(String key) {
     
        //清除指定缓存
        commonCache.invalidate(key);
    }

    @Override
    public void removeAllCommonCache() {
     
        //清除所有缓存
        commonCache.invalidateAll();
    }

    @Override
    public void removeAssignCommonCache(String... keys) {
     
        //清除多个key缓存
        commonCache.invalidateAll(Collections.singleton(keys));
    }
}

其中需要注意的是删除缓存的问题
如果是在分布式环境下,nginx负载均衡访问到每个项目对应的虚拟机,这样每个虚拟机都会进行本地热点缓存,而如果单纯的调用其中一个remove cache方法,只是对应的这个虚拟机的本地缓存被清掉,其他虚拟机的缓存还是存在的,这时候当然有其他的解决办法,比如使用消息队列MQ,但无疑会有点违背提高性能,提高响应速度的需求。

因此建议使用热点缓存的数据具有不可变性,持久性,也可以把热点缓存的失效时间设置短点,避免出现数据不一致性,安全问题。

文章持续更新,可以微信搜索「 绅堂Style 」第一时间阅读,回复【资料】有我准备的面试题笔记。
GitHub https://github.com/dtt11111/Nodes 有总结面试完整考点、资料以及我的系列文章。欢迎Star。
在这里插入图片描述

你可能感兴趣的:(JAVA,插件,Redis,java,缓存,本地缓存,guava,spring)