缓存和缓存淘汰算法

一、内存、缓存、寄存器

  1. CPU <===> 寄存器 <===> 缓存 <===> 内存
       寄存器:cpu中的一部分,cpu直接拿寄存器中的数据,包含:指令寄存器、程序计数器。寄存器从缓存或者内存中获取数据。
       缓存:直接从内存拿数据速度很慢,缓存那些经常读取且不经常修改的数据,让数据更接近使用者。缓存命中率越高越好。
                  一级缓存:内置在cpu内部,与cpu同速运行(但是在同步内存中的数据时,会对这个cache加锁,所以没寄存器快)
                  二级缓存和三级缓存:只能存储数据,不能存储原始指令。内存变大,速度变慢。

二、缓存算法:缓存放满了之后的淘汰策略

    FIFO:先进先出。移除最早放进来的。 缺:被置换的数据往往是被频繁访问的,所以不用这个。

    LFU(Least Frequently Used):最近最少使用。移除一段时间内用的最少的. 需要维护访问频率:用小根堆+哈希表可以实现

    LRU(Least Recently Used):移除最久未使用的(认为它在将来被访问的概率也很小,提高对热点数据的缓存效率)。 Redis、Memcached等分布式缓存系统有广泛使用?
        双向链表+哈希表实现:链表表示热点顺序、哈希表用来存储和查找
        继承LinkedHashMap可快速实现。 accessOrder: true基于访问顺序;false基于插入顺序(默认)

三、spring的缓存

    1. spring的cache是作用在方法上的:key是方法的入参,value是返回值。
    2. Cache接口:  ConcurrentMapCache: 使用java.util.concurrent.ConcurrentHashMap实现的Cache;
                          GuavaCache: 使用google的Guava做数据存储结构;
                          EhCacheCache:使用Ehcache实现;
    3. 用CacheManager接口管理各个缓存
    4. @Cacheable注解:给部分高频查询加了缓存(查业务线、话术配置、用uid查客服信息等),如果加在类上表示所有方法都支持缓存。    @Cacheable(cacheManager = String, value = String, key = String) 

 

四、缓存击穿、穿透、雪崩

1、穿透

        原因:恶意大量请求一定不存在的数据,导致每次都查db。
        解决:缓存一个过期时间短的空值; 布隆过滤器:把所有可能存在的数据存起来,类似一个不怎么精确的set,一定包含了所有的key。

2、击穿

        原因:单个key的高并发,在缓存失效的瞬间打爆db。(一个点被高频击破:如电商的爆款)
        解决:热点数据设置永不过期(都能缓存击穿了还不设置永久!);   使用互斥锁:setNX设置一个key当互斥锁,如果操作成功则loadDB否则休眠重试。

3、雪崩

        原因:多个key高并发且同时怼到DB上,导致数据库异常。 
        解决:1.缓存同时大面积失效导致雪崩:缓存的失效时间加随机值;高频热点数据如果可以的话不设置过期时间;
                   2.redis炸了导致雪崩:  事前:对redis做高可用:主从+哨兵、redis cluster   // todo
                                                         事中:hystrix 限流&降级,保护mysql不挂
                                                         事后:redis持久化做数据恢复
 
昵称多语言,存取redis时,因为key的原因发生了雪崩

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值