探讨本地缓存

引言


本文主要讨论关于本地缓存的一些见解,主要是基于工作过程中遇到的问题以及是如何解决的。对于缓存穿透,工作中虽然不是常见的问题,但是一旦遇到就是严重的生产事故,所以要对每一次缓存使用做好设计。

本文主要分为一下几部分:

遇到问题

问题的实质

本地缓存的应用

正文

一、背景

公司使用的是高可用的redis cluster,同时会有多个服务共用这个缓存集群,我们主要做的是运营营销的产品,很明显的会存在热key,即使使用的是分布式缓存也会导致集群中单机的性能带来很大的影响,甚至会影响其他的业务线。同时如何热key过多的话,超过了目前的缓存容量,会导致缓存分片被打垮的现象。当缓存服务崩溃之后,所有的数据请求会直接打到db,这就是缓存穿透的现象,如果请求量还是很大的话,会进一步导致雪崩现象,最终会导致服务不可用。这是所有公司不想看到的现象。

二、分析

直接对症下药,我们要解决的就是单点热key的问题。可以使用多机分流解决这个问题,本地缓存即可以满足这样的要求。本地缓存解决了热点,但同时也带来了数据一致性的问题,在短时间内同一客户端访问业务系统可能会取到不一致的缓存结果。对于一些对稳定性要求很高的系统,分布式缓存必须得到很好的保障,以免上述的服务雪崩,因此本地缓存显得十分重要。

三、本地缓存

本地缓存会有以下几种实现方式:EhCache/MapDB/Guava Cache,本文只讨论较为轻量级的guava Cache,刚好在本次优化中使用的就是guava cache.

使用本地缓存你要考虑到:是否愿意消耗一些内存空间来实现提速,你是否能够预料到热key,放进缓存的数据总量总不会超过内存总量。如果这些都在你的控制之内,那么就开始优化吧。

下面简单介绍下guava cache的基本参数配置,话不多少上代码:


private static Cache<String, String> localCache = CacheBuilder.newBuilder() .maximumSize(2000000).initialCapacity(1000000)recordStats().expireAfterWrite(5, TimeUnit.MINUTES)      .refreshAfterWrite(30, TimeUnit.MINUTES).build(new CacheLoader<String, String>() {  @Override            public String load(String key) throws Exception {                return generateValueByKey(key);            }            @Override            public ListenableFuture<String> reload(final String key,  String oldValue) {    return (ListenableFuture<String>) ThreadPools.getInstance().submitGuavaCacheTask(() -> generateValueByKey(key));            }        });

 

1)maximumSize:最大条数

2)maximumWeight:如果限制占用内存大小,可以设置

3)weigher:比如限制了内存大小,这里就返回每个key返回的字节数

4)expireAfterWrite:写数据后多久过期(更新也算写入)

5)expireAfterAccess:操作数据多久后过期(读写都算)

6)refreshAfterWrite:写数据后多久执行重载(其实不是过期后立刻重载,而是过期后再次访问时重载,一般做成异步方式)

7)recordStats:开启数据统计(命中率之类的统计)

8)还可以对被移除的key进行监听removalListener(listener)这里的listener你可以用于统计或者埋点日志等其他的业务相关的操作。

设计:

四、注意

本地缓存使用的时候一定要注意数据的不一致性,一定要评估好对业务产生的影响。

在本次优化过程中就遇到类似的问题,对实时性要求较高的数据,在更新数据的时候将分布式缓存中的数据进行清除同时也对本地缓存的数据进行清除(此时就是个坑,我们清除本地缓存的时候只对了单点进行了清除,此时就出现了数据不一致性的问题)。所以在使用的过程中一定要注意这个点,适合业务需求的方案才是最好的方案。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值