中间件 | Redis - [内存 & 过期策略]
@
§1 redis 内存
查看内存使用情况
也可以通过命令配置
可以通过 info memory 的 used_memory_human 和 maxmemory_human 查看阅读友好的已用内存和总内存
设置最大可用内存
redis.conf文件中的maxmemory可以设置内存,单位是字节(也支持 100mb 形式)
默认没有配置,即不限制内存(64位)或 3G(32位)
通常设置为系统最大内存的 0.75
但结合官网,如下图,可能设置为 0.8 - 0.9 更合适

- 或通过命令设置
config set maxmemory 字节数
有没有配置 maxmemory 的区别
如下图的官网描述
- 若没有指定
maxmemory,OOM 时 redis 可能会崩溃,或被 Linux kernel OOM killer 杀死
因为此时超出的就是最大物理内存 - 若指定
maxmemory,redis 会报错、指令执行失败

§2 过期策略 和 驱逐策略
区分
- 过期策略是 key 过期后需要执行的策略
- 驱逐策略是 redis 占用内存超过
maxmemory后对新的 key 应用的策略
设置过期策略
- 定时清除
即立即清除,需要由监控器始终扫描剩余时间,产生性能消耗,对 CPU 不友好 - 惰性删除
即 key 被访问时才检测是否过期,不活跃的 key 可能会积压在内存中,造成内存泄漏,对内存不友好 - 定期删除
每隔一段时间删除一轮过期键,同时限制这一过程的时长和频率减少对 CPU 的影响
周期性随机抽查 redis 的时效性数据,控制过期数据占比的方式控制删除频率
CPU 性能侵占有上限、频率可控、内存压力不大(持续清理冷数据)
但依然可能出现一直没有被抽查,也没有被二次激活的 key 侵占内存,如果短期量大,就会占用大量内存
设置内存淘汰策略
内存淘汰策略即 redis 达到设置的 maxmemory 后,如何选择一些信息清除
默认内存策略包括如下几种
| 对过期 key | 对所有 key | |
|---|---|---|
| lru | volatile-lru | allkeys-lru(常用) |
| lfu | voliatile-lfu | allkeys-lfu |
| 随机 | volatile-random | allkeys-random |
| 过期 | volatile-ttl(删除即将过期的) | |
| 特殊的 | noeviction(默认) |
清除目标分所有 key 与设置了超时的 key 2 种
清除方式包括使用 lru、lfu、随机、即将过期 4 种
设置
redis.conf文件中的maxmemory-policy可以设置内存
maxmemory-policy allkeys-lru- 命令行可以配置
config set maxmemory-policy allkeys-lru
LRU、LFU
- LRU = Least Recently Used,近期最少使用
- LFU = Least Frequently Used,最少使用
通常使用 LRU
LinkedHashMap 实现
LinkedHashMap 自带一个方法

此方法在 afterNodeInsertion 时被调用,按上面方法的返回,决定是否从队列中删除头结点

而在 afterNodeAccess,会将最后访问的 node 放到队列的尾结点,get 和 put 都在最后调用了此方法

可以参考其实现,比如 LRUCache

class LurLinkedHashmMap extends LinkedHashMap<String,Serializable>{
private int max;
public LurLinkedHashmMap(int initialCapacity, int max) {
super(initialCapacity,0.75f,true);
this.max = max;
}
// 如果是 access order 的 map,插入节点后,根据此方法决定是否删除节点
@Override
protected boolean removeEldestEntry(Map.Entry<String, Serializable> eldest) {
return this.size() > max;
}
}

浙公网安备 33010602011771号