redis 的过期策略及linkedHashMap LRU实现

目录

一、Redis 过期策略

二、LinkedHashMap LRU 实现


一、Redis 过期策略

如果性能瓶颈出在数据库,可以引入redis,减缓数据库的压力

因为redis 是基于内存来进行高性能、高并发的读写操作的。因为是内存,就会有空间的限制。如果只有10g内存,一直往里面写数据,那肯定不行,所以需要采用一些策略来把过期的数据删除掉或淘汰掉。

过期策略主要有:定期删除、惰性删除两种。

定期删除

所谓定期删除,指的是 redis 默认是每隔 100ms 就随机抽取一些设置了过期时间的 key,检查其是否过期,如果过期就删除。
随机抽取这里需要注意,如果在随机抽取的数据中,过期率超过了1/4,就再执行一次,直到比例低于1/4。

这里为什么是随机抽取?

假如在redis 里插入10w个key,并且都设置了过期时间,如果每次都检查所有key,那cpu基本上都消耗在过期key的检查上了,redis对外的性能也会大大降低。

但是随机抽取会存在一个问题,就是会存在本已经过期的key,因为没有被扫描到,而继续留在内存中,并占用空间,等待被删除。

这时候就需要第二种过期策略了。

惰性删除

惰性删除,就是在获取某个 key 的时候,redis 会检查一下 ,如果这个 key 设置了过期时间,并且已经过期了,那么就直接删除,返回空。

嗯,那再考虑一种情况,如果大量的key没有被扫描到,且已过期,也没有被再次访问,即没有走惰性删除,这些大量过期 key 堆积在内存里,也有可能导致 redis 内存块耗尽了,这种情况下,怎么办?

redis内部提供了内存淘汰机制,有多种算法可以实现,比较广为人知的是LRU 算法

二、LinkedHashMap LRU 实现

如果从头开始写一个完整的LRU算法,那会要了命,幸好小菜鸡还记得 LinkedHashMap,可以基于 LinkedHashMap实现一个简单版本的LRU算法。

public class LRUCache extends LinkedHashMap {

    private final int CACHE_SIZE;

    public LRUCache(int cacheSize){
        super((int)Math.ceil(cacheSize / 0.75) +1 ,0.75f,true);
        CACHE_SIZE = cacheSize;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry eldest) {
        return size() > CACHE_SIZE;
    }
}

 

你可能感兴趣的:(Redis)