Redis灵魂拷问系列之过期策略与数据持久化


Redis灵魂拷问系列之过期策略与数据持久化

1.redis过期策略能说一下吗

1.1 redis为什么需要过期策略

我们平常用 redis 做缓存时,可能会有一些问题:为什么有的key塞入之后就会消失,如果真的发现这样的情况,说明可能 redis 没有用对。

图量化系统的各种延时时间图

redis 本质上属于 内存数据库,把内存当作缓存使用,可以从图中看出,内存属于 ns 级别,可见速度是很快的。但是内存也是宝贵的,可以从几千的电脑只有 那么16、32G的内存,而可以有1T的硬盘中看出。

当内存被你不断塞入的数据给塞满,那么 redis 就会在你再次塞入数据时根据一些算法(LRU、LFU等)给你淘汰一些数据,才能保证你能存入数据

1.2 定期删除、惰性删除

redis使用 定期删除 + 惰性删除 的方式淘汰过期数据

  • 定期删除:redis在定期删除(比如100ms)时,不会每次都把过期的key全部删除,而是随机抽取一些过期数据进行删除
  • 惰性删除:当过期数据被访问时,redis 会进行检查,如果过期则进行删除

但是这样还是会有一些问题,如果过期数据定期删除时一直未被删除,又一直未被查询导致不走惰性删除,那么还是会一直占据着内存空间,最终导致内存占满。redis 使用 内存淘汰机制 来处理这一问题。

1.3 内存淘汰机制

redis在内存占用过多时,会自行使用一些淘汰算法,淘汰一些数据

  • allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)
  • volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的 key(这个一般不太合适)
  • volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的 key 优先移除
  • noeviction: 当内存不足以容纳新写入数据时,新写入操作会报错(很少用)
  • allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个 key(很少用)
  • volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个 key(很少用)

1.4 可以手写一个LRU算法吗

我们可以基于Java的数据结构 LinkedHashMap 来写一个

大致思路:创建LRUCache类,继承LinkedHashMap类,定义一个存放数据数量的阈值,编写构造器方法,使用LinkedHashMap类的构造器方法,设置初始容量、负载因子以及按访问顺序排序(true),重写removeEldestEntry()方法,设置当容量超过阈值时,会把最少访问的数据删除

class LRUCache<K, V> extends LinkedHashMap<K, V> {
    private final int CACHE_SIZE;

    /**
     * 传递进来最多能缓存多少数据
     *
     * @param cacheSize 缓存大小
     */
    public LRUCache(int cacheSize) {
        // true 表示让 linkedHashMap 按照访问顺序来进行排序,最近访问的放在头部,最老访问的放在尾部。
        super((int) Math.ceil(cacheSize / 0.75) + 1, 0.75f, true);
        CACHE_SIZE = cacheSize;
    }

    @Override
    protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
        // 当 map中的数据量大于指定的缓存个数的时候,就自动删除最老的数据。
        return size() > CACHE_SIZE;
    }
}

2.redis持久化RDB和AOF

也不妨瞧瞧官方怎么说的:REDIS persistence

【参考链接】
1:Redis 核心篇:唯快不破的秘密
2:Redis 6.0 新特性-多线程连环13问!
3:redis中文官方网站
4:redis 数据持久化-官方网站


评论
  目录