Redis DB数据结构

image.png

配置项

volatile: 过期key allkeys: 全部key

影响的配置项

内存相关

  • maxmemory 最大内存限制
  • maxmemory-policy 达到最大内存限制的时候,如何驱逐key

    • volatile-lru
    • allkeys-lru
    • volatile-lfu
    • allkeys-lfu
    • volatile-random
    • allkeys-random
    • volatile-ttl
    • noeviction 【默认配置】

      延迟操作

      Redis存在2个基础的删除操作

      • 分别是阻塞的 DEL 命令,为了回收使用的内存,该命令会阻塞服务器,如果删除的key对象很小,执行的很快,如果删除的对象涉及到千万级别的value,服务器就会阻塞较长时间
      • 另外一个是非阻塞的DEL命令 UNLINK, O(1) 的执行时间。另外一个线程会在后台回收
        • bio.h/bio.c
  • lazyfree-lazy-eviction

  • lazyfree-lazy-expire: 同步删除/异步删除
  • lazyfree-lazy-server-del: 同步释放内存/异步释放内存
  • replica-lazy-flush

    Redis实现

  • expire.c 过期实现

  • evict.c 驱逐实现

    过期删除实现

    惰性删除
  • 惰性删除: 不主动删除,等到下次要使用到该key时进行检测是否已过期,由 db.c#expireIfNeeded 实现 ```c int expireIfNeeded(redisDb db, robj key) { if (!keyIsExpired(db,key)) return 0; propagateExpire(db,key,server.lazyfree_lazy_expire); notifyKeyspaceEvent(NOTIFY_EXPIRED,”expired”,key,db->id); return server.lazyfree_lazy_expire ? dbAsyncDelete(db,key) :dbSyncDelete(db,key); }

/ Check if the key is expired. / int keyIsExpired(redisDb db, robj key) { //获取key的过期时间 mstime_t when = getExpire(db,key); if (when < 0) return 0; / No expire for this key / mstime_t now = mstime() return now > when; } ```

定期删除
  • 定期删除: 在server.c#serverCron中定期调用,在expire.c#activeExpireCycle 中实现定期删除
    • 轮训遍历N个数据库
    • db->expires中随机挑选20个key,进行过期处理,轮训处理到20个或者是达到指定时间停止遍历

image.png

驱逐key实现

It is important to understand that the eviction process works like this:

  • A client runs a new command, resulting in more data added.
  • Redis checks the memory usage, and if it is greater than the maxmemory limit , it evicts keys according to the policy.
  • A new command is executed, and so forth.

So we continuously cross the boundaries of the memory limit, by going over it, and then by evicting keys to return back under the limits.

If a command results in a lot of memory being used (like a big set intersection stored into a new key) for some time, the memory limit can be surpassed by a noticeable amount.

主要由 evict.c#freeMemoryIfNeeded实现,比较maxMemory实际使用-AOF/slave使用判定是否需要回收内存。

参考链接

https://redis.io/docs/manual/eviction/