§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;
}
}