【13期】谈谈 Redis 的过期策略
阅读本文大概需要 6.5 分钟。
来自:https://www.shipengqi.top/
定期删除策略
随机抽取 20 个 key
删除这 20 个key中过期的key
如果过期的 key 比例超过 1/4,就重复步骤 1,继续删除。
从库的过期策略
懒惰删除策略
unlink
> unlink key
OK
flush
> flushall async
OK
异步队列
更多异步删除点
slave-lazy-flush 从库接受完 rdb 文件后的 flush 操作
lazyfree-lazy-eviction 内存达到 maxmemory 时进行淘汰
lazyfree-lazy-expire key 过期删除
lazyfree-lazy-server-del rename 指令删除 destKey
内存淘汰机制
配置参数 maxmemory。当内存超出 maxmemory,Redis 提供了几种内存淘汰机制让用户选择,配置 maxmemory-policy:
noeviction:当内存超出 maxmemory,写入请求会报错,但是删除和读请求可以继续。(使用这个策略,疯了吧)
allkeys-lru:当内存超出 maxmemory,在所有的 key 中,移除最少使用的key。只把 Redis 既当缓存是使用这种策略。(推荐)。
allkeys-random:当内存超出 maxmemory,在所有的 key 中,随机移除某个 key。(应该没人用吧)
volatile-lru:当内存超出 maxmemory,在设置了过期时间 key 的字典中,移除最少使用的 key。把 Redis 既当缓存,又做持久化的时候使用这种策略。
volatile-random:当内存超出 maxmemory,在设置了过期时间 key 的字典中,随机移除某个key。
volatile-ttl:当内存超出 maxmemory,在设置了过期时间 key 的字典中,优先移除 ttl 小的。
LRU 算法
from collections import OrderedDict
class LRUDict(OrderedDict):
def __init__(self, capacity):
self.capacity = capacity
self.items = OrderedDict()
def __setitem__(self, key, value):
old_value = self.items.get(key)
if old_value is not None:
self.items.pop(key)
self.items[key] = value
elif len(self.items) < self.capacity:
self.items[key] = value
else:
self.items.popitem(last=True)
self.items[key] = value
def __getitem__(self, key):
value = self.items.get(key)
if value is not None:
self.items.pop(key)
self.items[key] = value
return value
def __repr__(self):
return repr(self.items)
d = LRUDict(10)
for i in range(15):
d[i] = i
print d
近似 LRU 算法
LFU
// redis 的对象头
typedef struct redisObject {
unsigned type:4; // 对象类型如 zset/set/hash 等等
unsigned encoding:4; // 对象编码如 ziplist/intset/skiplist 等等
unsigned lru:24; // 对象的「热度」
int refcount; // 引用计数
void *ptr; // 对象的 body
} robj;
推荐阅读:
微信扫描二维码,关注我的公众号
朕已阅
评论